diff --git a/.github/actions/test-coverage/action.yml b/.github/actions/test-coverage/action.yml new file mode 100644 index 00000000000..2b05757578f --- /dev/null +++ b/.github/actions/test-coverage/action.yml @@ -0,0 +1,46 @@ + +description: 'Run tests enabling coverage in certain conditions and upload coverage artifacts for later process' + +inputs: + python-version: + description: 'Python version in which the tests was ran' + required: true + + test-type: + description: 'Test suite name' + required: true + + duration: + description: 'Tests maximum duration' + required: true + default: '20' + + tests: + description: 'Tests folder and options to run' + required: false + + workers: + description: 'Number of workers to run tests' + default: auto + +runs: + using: 'composite' + steps: + - name: Run tests with coverage + if: ${{ inputs.tests }} + shell: ${{ runner.os == 'Windows' && 'pwsh' || 'bash' }} + run: | + pytest ${{ inputs.tests }} --durations=${{ inputs.duration }} -n ${{ inputs.workers }} ${{ github.ref == 'refs/heads/develop2' && '--cov=conan --cov=conans --cov=test --cov-report=term-missing:skip-covered' || '' }} + + - name: Rename coverage file + if: github.ref == 'refs/heads/develop2' + shell: bash + run: mv .coverage .coverage.${{ runner.os }}-${{ inputs.python-version }}-${{ inputs.test-type }} + + - name: Upload coverage artifact + if: github.ref == 'refs/heads/develop2' + uses: actions/upload-artifact@v4 + with: + name: .coverage.${{ runner.os }}-${{ inputs.python-version }}-${{ inputs.test-type }} + path: .coverage.${{ runner.os }}-${{ inputs.python-version }}-${{ inputs.test-type }} + include-hidden-files: true diff --git a/.github/workflows/linux-tests.yml b/.github/workflows/linux-tests.yml index 558039da0f3..1df2d43d13d 100644 --- a/.github/workflows/linux-tests.yml +++ b/.github/workflows/linux-tests.yml @@ -1,23 +1,12 @@ name: Linux tests on: - push: - branches: - - develop2 - - release/* - pull_request: - branches: - - '*' - - 'release/*' - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true + workflow_call: jobs: build_container: runs-on: ubuntu-latest + name: Build Linux container outputs: image_tag: ${{ steps.dockerfile_hash.outputs.tag }} steps: @@ -52,7 +41,7 @@ jobs: docker build -t ghcr.io/${{ github.repository_owner }}/conan-tests:${{ steps.dockerfile_hash.outputs.tag }} -f ./.ci/docker/conan-tests . docker push ghcr.io/${{ github.repository_owner }}/conan-tests:${{ steps.dockerfile_hash.outputs.tag }} - linux_test_suite: + linux_tests: needs: build_container runs-on: ubuntu-latest container: @@ -60,9 +49,16 @@ jobs: options: --user conan strategy: matrix: - python-version: ['3.12.3', '3.9.2', '3.8.6', '3.6.15'] - test-type: ['unittests', 'integration', 'functional'] - name: Conan ${{ matrix.test-type }} (${{ matrix.python-version }}) + python-version: [3.12.3, 3.9.2, 3.8.6, 3.6.15] + test-type: [unittests, integration, functional] + include: + - test-type: unittests + test-name: Unit + - test-type: integration + test-name: Integration + - test-type: functional + test-name: Functional + name: ${{ matrix.test-name }} Tests (${{ matrix.python-version }}) steps: - name: Checkout code uses: actions/checkout@v4 @@ -87,23 +83,20 @@ jobs: pip install meson - name: Run tests - shell: bash - run: | - if [ "${{ matrix.test-type }}" == "unittests" ]; then - pytest test/unittests --durations=20 -n 4 - elif [ "${{ matrix.test-type }}" == "integration" ]; then - pytest test/integration --durations=20 -n 4 - elif [ "${{ matrix.test-type }}" == "functional" ]; then - pytest test/functional --durations=20 -n 4 - fi + uses: ./.github/actions/test-coverage + with: + python-version: ${{ matrix.python-version }} + test-type: ${{ matrix.test-type }} + tests: test/${{ matrix.test-type }} + duration: 20 linux_docker_tests: needs: build_container runs-on: ubuntu-latest - name: Docker Runner Tests strategy: matrix: python-version: [3.12, 3.9] + name: Docker Runner Tests (${{ matrix.python-version }}) steps: - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 @@ -122,50 +115,10 @@ jobs: pip install -r conans/requirements_runner.txt - name: Run tests - shell: bash - run: | - pytest -m docker_runner --durations=20 -rs - - deploy_to_pypi_test: - needs: [build_container, linux_test_suite, linux_docker_tests] - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/develop2' - name: Deploy to TestPyPI - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 + uses: ./.github/actions/test-coverage with: - python-version: '3.9' - - - name: Install dependencies - run: | - pip install --upgrade pip - pip install twine - - - name: Bump Dev Version - run: | - python .ci/bump_dev_version.py - - - name: Build Package - run: | - python setup.py sdist - - - name: Upload to TestPyPI - env: - TWINE_USERNAME: ${{ secrets.TEST_PYPI_USERNAME }} - TWINE_PASSWORD: ${{ secrets.TEST_PYPI_PASSWORD }} - run: | - python -m twine upload --verbose --repository-url https://test.pypi.org/legacy/ dist/* - - - name: Deploy conan-server to TestPyPI - env: - TWINE_USERNAME: ${{ secrets.TEST_PYPI_SERVER_USERNAME }} - TWINE_PASSWORD: ${{ secrets.TEST_PYPI_SERVER_PASSWORD }} - run: | - rm -rf dist/ - mv setup_server.py setup.py - python setup.py sdist - python -m twine upload --verbose --repository-url https://test.pypi.org/legacy/ dist/* + python-version: ${{ matrix.python-version }} + test-type: docker + tests: '-m docker_runner -rs' + duration: 20 + workers: 1 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000000..02a8ad19907 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,103 @@ +name: Main Workflow +on: + push: + branches: + - develop2 + - release/* + - '*' + pull_request: + branches: + - '*' + - 'release/*' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + linux_suite: + uses: ./.github/workflows/linux-tests.yml + name: Linux test suite + + osx_suite: + uses: ./.github/workflows/osx-tests.yml + name: OSX test suite + + windows_suite: + uses: ./.github/workflows/win-tests.yml + name: Windows test suite + + code_coverage: + runs-on: ubuntu-latest + name: Code coverage + if: github.ref == 'refs/heads/develop2' # Only measure code coverage on main branch + needs: [linux_suite, osx_suite, windows_suite] + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download coverage artifacts + uses: actions/download-artifact@v4 + with: + merge-multiple: true + + - name: Merge coverage reports + run: | + pip install coverage + coverage combine + coverage report + coverage xml + + - name: Code coverage + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + + - uses: geekyeggo/delete-artifact@v5 + with: + name: | + .coverage.* + + deploy_to_pypi_test: + runs-on: ubuntu-latest + name: Deploy to TestPyPI + if: github.ref == 'refs/heads/develop2' + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.9 + + - name: Install dependencies + run: | + pip install --upgrade pip + pip install twine + + - name: Bump Dev Version + run: | + python .ci/bump_dev_version.py + + - name: Build Package + run: | + python setup.py sdist + + - name: Upload to TestPyPI + env: + TWINE_USERNAME: ${{ secrets.TEST_PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.TEST_PYPI_PASSWORD }} + run: | + python -m twine upload --verbose --repository-url https://test.pypi.org/legacy/ dist/* + + - name: Deploy conan-server to TestPyPI + env: + TWINE_USERNAME: ${{ secrets.TEST_PYPI_SERVER_USERNAME }} + TWINE_PASSWORD: ${{ secrets.TEST_PYPI_SERVER_PASSWORD }} + run: | + rm -rf dist/ + mv setup_server.py setup.py + python setup.py sdist + python -m twine upload --verbose --repository-url https://test.pypi.org/legacy/ dist/* diff --git a/.github/workflows/osx-tests.yml b/.github/workflows/osx-tests.yml index 671f8d6bf0c..065afbc33c4 100644 --- a/.github/workflows/osx-tests.yml +++ b/.github/workflows/osx-tests.yml @@ -1,21 +1,10 @@ name: OSX Tests on: - push: - branches: - - develop2 - - release/* - pull_request: - branches: - - '*' - - 'release/*' - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true + workflow_call: jobs: - setup-caches: + osx_setup: runs-on: macos-14 name: Setup and Cache Dependencies steps: @@ -118,18 +107,22 @@ jobs: chmod +x ${HOME}/Applications/bazel/${version}/bazel done - testing: - needs: setup-caches + osx_tests: + needs: osx_setup + runs-on: macos-14 strategy: fail-fast: true matrix: - python-version: ['3.8', '3.12', '3.13'] + python-version: [3.8, 3.12, 3.13] test-type: [unittests, integration, functional] - - runs-on: macos-14 - - name: Conan (${{ matrix.test-type }}) (${{ matrix.python-version }}) - + include: + - test-type: unittests + test-name: Unit + - test-type: integration + test-name: Integration + - test-type: functional + test-name: Functional + name: ${{ matrix.test-name }} Tests (${{ matrix.python-version }}) steps: - name: Checkout code uses: actions/checkout@v4 @@ -168,11 +161,14 @@ jobs: - name: Install homebrew dependencies run: | brew install xcodegen make libtool zlib autoconf automake ninja - - - name: Run Tests - run: | export PATH=${HOME}/Applications/CMake/3.15.7/bin:$PATH:/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin cmake --version bazel --version - python -m pytest test/${{ matrix.test-type }} --durations=20 -n auto + - name: Run tests + uses: ./.github/actions/test-coverage + with: + python-version: ${{ matrix.python-version }} + test-type: ${{ matrix.test-type }} + tests: test/${{ matrix.test-type }} + duration: 20 diff --git a/.github/workflows/win-tests.yml b/.github/workflows/win-tests.yml index 2b0df32c804..b9885b6bb8e 100644 --- a/.github/workflows/win-tests.yml +++ b/.github/workflows/win-tests.yml @@ -1,27 +1,14 @@ name: Windows Tests on: - push: - branches: - - develop2 - - release/* - pull_request: - branches: - - '*' - - 'release/*' - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true + workflow_call: jobs: unit_integration_tests: runs-on: windows-2022 strategy: matrix: - python-version: ['3.13', '3.8', '3.6'] - + python-version: [3.13, 3.8, 3.6] name: Unit & Integration Tests (${{ matrix.python-version }}) steps: - name: Checkout code @@ -45,7 +32,6 @@ jobs: shell: pwsh run: echo "PIP_CACHE_DIR=$(pip cache dir)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - name: Cache pip packages uses: actions/cache@v4 with: @@ -60,18 +46,21 @@ jobs: pip install -r conans/requirements.txt pip install -r conans/requirements_dev.txt pip install -r conans/requirements_server.txt + git config --global core.autocrlf false - name: Run Unit & Integration Tests - shell: pwsh - run: | - git config --global core.autocrlf false - pytest test/unittests test/integration --durations=100 -n=auto + uses: ./.github/actions/test-coverage + with: + python-version: ${{ matrix.python-version }} + test-type: unit-integration + tests: test/unittests test/integration + duration: 100 functional_tests: runs-on: windows-2022 strategy: matrix: - python-version: ['3.13', '3.8', '3.6'] + python-version: [3.13, 3.8, 3.6] name: Functional Tests (${{ matrix.python-version }}) steps: @@ -260,4 +249,12 @@ jobs: [System.Environment]::SetEnvironmentVariable('MSYS2_PATH', $msys2Path, [System.EnvironmentVariableTarget]::Process) Write-Host "Added MSYS2_PATH environment variable: $msys2Path" - pytest test/functional -n=auto --durations=100 + # Run tests in this step context to preserve fragile environment + pytest test/functional -n=auto --durations=100 ${{ github.ref == 'refs/heads/develop2' && '--cov=conan --cov=conans --cov=test --cov-report=term-missing:skip-covered' || '' }} + + - name: Code Coverage + uses: ./.github/actions/test-coverage + with: + python-version: ${{ matrix.python-version }} + test-type: functional + duration: 100 diff --git a/.gitignore b/.gitignore index 87824d1019e..593c94534ba 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ parts/ sdist/ var/ venv/ +.venv/ *.egg-info/ .installed.cfg *.egg diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 00000000000..561bf760e25 --- /dev/null +++ b/codecov.yml @@ -0,0 +1 @@ +comment: false # Disable codecov PR comments -> leave only the checks diff --git a/conans/requirements_dev.txt b/conans/requirements_dev.txt index e9e964c4569..b2876e233bb 100644 --- a/conans/requirements_dev.txt +++ b/conans/requirements_dev.txt @@ -8,3 +8,4 @@ PyJWT pluginbase docker setuptools +pytest-cov diff --git a/setup.cfg b/setup.cfg index 6ba9f60b404..ca70e3f2f14 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,3 +3,11 @@ count = False max-line-length = 100 statistics = False +; Coverage files are generated across different OS and machines, thus, coverage +; reports will contain different absolute paths to reference to the same +; project relative paths. +; This option makes coverage to use relative paths to the project root, +; removing the need for setting arbitrary runners paths described in here: +; https://coverage.readthedocs.io/en/coverage-4.0.3/config.html#paths +[coverage:run] +relative_files = True