diff --git a/.github/actions/code-coverage/action.yml b/.github/actions/code-coverage/action.yml new file mode 100644 index 00000000000..8bc37de57f2 --- /dev/null +++ b/.github/actions/code-coverage/action.yml @@ -0,0 +1,31 @@ +name: 'Code coverage' +description: 'Properly rename and upload coverage artifact for later process' + +inputs: + python-version: + description: 'Python version in which the tests was ran' + required: true + + test-type: + description: 'Tests suite name' + required: true + +runs: + using: "composite" + steps: + - name: Rename coverage file (Linux/MacOS) + if: runner.os != 'Windows' + shell: bash + run: mv .coverage .coverage.${{ runner.os }}-${{ inputs.python-version }}-${{ inputs.test-type }} + + - name: Rename coverage file (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: powershell Rename-Item .coverage coverage-${{ runner.os }}-${{ inputs.python-version }}-${{ inputs.test-type }}.coverage + + - name: Upload coverage artifact + 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..a531d9ee670 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 @@ -86,24 +82,23 @@ jobs: pip install -r conans/requirements_server.txt pip install meson - - name: Run tests - shell: bash + - name: Run Tests 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 + pytest test/${{ matrix.test-type }} --durations=20 -n auto --cov=conan --cov-report=term-missing:skip-covered + + - name: Code coverage + uses: ./.github/actions/code-coverage + with: + python-version: ${{ matrix.python-version }} + test-type: ${{ matrix.test-type }} 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 @@ -124,48 +119,10 @@ jobs: - name: Run tests shell: bash run: | - pytest -m docker_runner --durations=20 -rs + pytest -m docker_runner --durations=20 -rs --cov=conan --cov-report=term-missing:skip-covered - 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 + - name: Code coverage + uses: ./.github/actions/code-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: ${{ matrix.test-type }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000000..efa673a699f --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,117 @@ +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 + 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: Pytest coverage comment + id: coverageComment + uses: MishaKav/pytest-coverage-comment@main + with: + pytest-xml-coverage-path: ./coverage.xml + xml-skip-covered: true # Only display non fully covered files + hide-report: true # Avoids GitHub message length limit issue + + - name: Update coverage badge + uses: schneegans/dynamic-badges-action@v1.7.0 + with: + auth: ${{ secrets.PYTEST_COVERAGE_COMMENT }} + gistID: f305b2c105b15ff2b620a7a728b14934 + filename: conan-coverage.json + label: Coverage Report + message: ${{ steps.coverageComment.outputs.coverage }} + color: ${{ steps.coverageComment.outputs.color }} + namedLogo: python + + - uses: geekyeggo/delete-artifact@v5 + with: + name: | + .coverage.* + + deploy_to_pypi_test: + needs: [linux_suite] + 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 + 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..673b1147908 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 @@ -175,4 +168,10 @@ jobs: cmake --version bazel --version - python -m pytest test/${{ matrix.test-type }} --durations=20 -n auto + pytest test/${{ matrix.test-type }} --durations=20 -n auto --cov=conan --cov-report=term-missing:skip-covered + + - name: Code coverage + uses: ./.github/actions/code-coverage + with: + python-version: ${{ matrix.python-version }} + test-type: ${{ matrix.test-type }} diff --git a/.github/workflows/win-tests.yml b/.github/workflows/win-tests.yml index 2b0df32c804..4cc90d64df6 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 @@ -65,13 +52,19 @@ jobs: shell: pwsh run: | git config --global core.autocrlf false - pytest test/unittests test/integration --durations=100 -n=auto + pytest test/unittests test/integration --durations=100 -n=auto --cov=conan --cov-report=term-missing:skip-covered + + - name: Code coverage + uses: ./.github/actions/code-coverage + with: + python-version: ${{ matrix.python-version }} + test-type: unit-integration 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 +253,10 @@ 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 + pytest test/functional -n=auto --durations=100 --cov=conan --cov-report=term-missing:skip-covered + + - name: Code coverage + uses: ./.github/actions/code-coverage + with: + python-version: ${{ matrix.python-version }} + test-type: functional 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/README.md b/README.md index 7c298f615c7..a490165af19 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,10 @@ # Conan +[![license](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE.md) +[![CI](https://github.com/conan-io/conan/actions/workflows/main.yml/badge.svg)](https://github.com/conan-io/conan/actions/workflows/main.yml) +![badge](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/perseoGI/f305b2c105b15ff2b620a7a728b14934/raw/conan-coverage.json) + Decentralized, open-source (MIT), C/C++ package manager. - Homepage: https://conan.io/ diff --git a/conans/requirements_dev.txt b/conans/requirements_dev.txt index 4e26ce16c55..5106a964130 100644 --- a/conans/requirements_dev.txt +++ b/conans/requirements_dev.txt @@ -7,4 +7,5 @@ bottle PyJWT pluginbase docker -setuptools \ No newline at end of file +setuptools +pytest-cov diff --git a/setup.cfg b/setup.cfg index 6ba9f60b404..6a06692da32 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,3 +3,12 @@ count = False max-line-length = 100 statistics = False +; https://coverage.readthedocs.io/en/coverage-4.0.3/config.html#paths +; The first value must be an actual file path on the machine where the +; reporting will happen +[coverage:paths] +source = + conan/ + /Users/runner/**/conan + /home/runner/**/conan + /__w/**/conan