feat: Prepare publishing flow to PyPi, increase test coverage #441
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build | |
| on: | |
| pull_request: | |
| types: | |
| - opened | |
| - reopened | |
| - synchronize | |
| - labeled | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - "*" | |
| workflow_dispatch: | |
| inputs: | |
| publish: | |
| description: 'Publish' | |
| required: true | |
| default: 'false' | |
| permissions: | |
| contents: read | |
| packages: read | |
| actions: read | |
| jobs: | |
| tests-unix: | |
| name: Unit tests for developer setup (Unix) | |
| if: | | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.author_association == 'COLLABORATOR' || | |
| github.event.pull_request.author_association == 'MEMBER' || | |
| github.event.pull_request.user.login == 'dependabot[bot]' || | |
| contains(github.event.pull_request.labels.*.name, 'safe to test') | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ macos-latest, ubuntu-latest ] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| cache: "pip" | |
| - name: Install project dependencies | |
| run: python -m pip install -r requirements.txt | |
| - name: Install project development dependencies | |
| run: python -m pip install -r requirements-dev.txt | |
| - name: Prepare build directories | |
| run: | | |
| mkdir -p artifacts | |
| mkdir -p src/c2pa/libs | |
| rm -rf dist/* build/* | |
| - name: Download native artifacts | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: python3 scripts/download_artifacts.py c2pa-v0.55.0 | |
| - name: Install package in development mode | |
| run: | | |
| pip uninstall -y c2pa | |
| pip install -e . | |
| - name: Verify installation | |
| run: | | |
| python3 -c "from c2pa import C2paError; print('C2paError imported successfully')" | |
| - name: Run tests | |
| run: python3 ./tests/test_unit_tests.py | |
| tests-windows: | |
| name: Unit tests for developer setup (Windows) | |
| if: | | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.author_association == 'COLLABORATOR' || | |
| github.event.pull_request.author_association == 'MEMBER' || | |
| github.event.pull_request.user.login == 'dependabot[bot]' || | |
| contains(github.event.pull_request.labels.*.name, 'safe to test') | |
| runs-on: windows-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| cache: "pip" | |
| - name: Install project dependencies | |
| run: python -m pip install -r requirements.txt | |
| - name: Install project development dependencies | |
| run: python -m pip install -r requirements-dev.txt | |
| - name: Prepare build directories | |
| run: | | |
| New-Item -ItemType Directory -Force -Path artifacts | |
| New-Item -ItemType Directory -Force -Path src\c2pa\libs | |
| if (Test-Path dist) { Remove-Item -Recurse -Force dist } | |
| if (Test-Path build) { Remove-Item -Recurse -Force build } | |
| - name: Download native artifacts | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: python scripts\download_artifacts.py c2pa-v0.55.0 | |
| - name: Install package in development mode | |
| run: | | |
| pip uninstall -y c2pa | |
| pip install -e . | |
| - name: Verify installation | |
| run: | | |
| python -c "from c2pa import C2paError; print('C2paError imported successfully')" | |
| - name: Run tests | |
| run: python .\tests\test_unit_tests.py | |
| build-linux-wheel: | |
| name: Build Linux wheel | |
| uses: ./.github/workflows/build-wheel.yml | |
| needs: tests-unix | |
| with: | |
| python-version: "3.10" | |
| artifact-name: wheels-linux-${{ matrix.target }} | |
| runs-on: ubuntu-latest | |
| secrets: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| strategy: | |
| matrix: | |
| target: [x86_64, aarch64] | |
| if: | | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.author_association == 'COLLABORATOR' || | |
| github.event.pull_request.author_association == 'MEMBER' || | |
| github.event.pull_request.user.login == 'dependabot[bot]' || | |
| contains(github.event.pull_request.labels.*.name, 'safe to test') | |
| test-built-linux-wheel: | |
| name: Test Linux built wheel | |
| needs: build-linux-wheel | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| target: [x86_64, aarch64] | |
| if: | | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.author_association == 'COLLABORATOR' || | |
| github.event.pull_request.author_association == 'MEMBER' || | |
| github.event.pull_request.user.login == 'dependabot[bot]' || | |
| contains(github.event.pull_request.labels.*.name, 'safe to test') | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| cache: "pip" | |
| - name: Download wheel artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: wheels-linux-${{ matrix.target }} | |
| path: dist | |
| - name: Create and activate virtual environment | |
| run: | | |
| python -m venv venv | |
| source venv/bin/activate | |
| - name: Install wheel for testing | |
| run: | | |
| source venv/bin/activate | |
| pip install dist/c2pa_python-*.whl | |
| - name: Run unittest tests on installed wheel | |
| run: | | |
| source venv/bin/activate | |
| python ./tests/test_unit_tests.py | |
| - name: Install pytest (in venv) | |
| run: | | |
| source venv/bin/activate | |
| pip install pytest | |
| - name: Run tests with pytest (venv) | |
| run: | | |
| source venv/bin/activate | |
| venv/bin/pytest tests/test_unit_tests.py -v | |
| build-windows-wheel: | |
| name: Build Windows wheel | |
| uses: ./.github/workflows/build-wheel.yml | |
| needs: tests-windows | |
| with: | |
| python-version: "3.10" | |
| architecture: ${{ matrix.target }} | |
| artifact-name: wheels-windows-${{ matrix.target }} | |
| runs-on: windows-latest | |
| secrets: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| strategy: | |
| matrix: | |
| target: [x64, x86] | |
| if: | | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.author_association == 'COLLABORATOR' || | |
| github.event.pull_request.author_association == 'MEMBER' || | |
| github.event.pull_request.user.login == 'dependabot[bot]' || | |
| contains(github.event.pull_request.labels.*.name, 'safe to test') | |
| test-built-windows-wheel: | |
| name: Test Windows built wheel | |
| needs: build-windows-wheel | |
| runs-on: windows-latest | |
| strategy: | |
| matrix: | |
| target: [x64, x86] | |
| if: | | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.author_association == 'COLLABORATOR' || | |
| github.event.pull_request.author_association == 'MEMBER' || | |
| github.event.pull_request.user.login == 'dependabot[bot]' || | |
| contains(github.event.pull_request.labels.*.name, 'safe to test') | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| cache: "pip" | |
| - name: Download wheel artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: wheels-windows-${{ matrix.target }} | |
| path: dist | |
| - name: Create and activate virtual environment | |
| run: | | |
| python -m venv venv | |
| .\venv\Scripts\activate | |
| - name: Install wheel for testing | |
| run: | | |
| .\venv\Scripts\activate | |
| $wheel = Get-ChildItem -Path dist -Filter "c2pa_python-*.whl" | Select-Object -First 1 | |
| if (-not $wheel) { Write-Error "No wheel file found in dist directory"; exit 1 } | |
| pip install $wheel.FullName | |
| - name: Run unittest tests on installed wheel | |
| run: | | |
| .\venv\Scripts\activate | |
| python .\tests\test_unit_tests.py | |
| - name: Install pytest (in venv) | |
| run: | | |
| .\venv\Scripts\activate | |
| pip install pytest | |
| - name: Run tests with pytest (venv) | |
| run: | | |
| .\venv\Scripts\activate | |
| .\venv\Scripts\pytest .\tests\test_unit_tests.py -v | |
| build-macos-wheel: | |
| name: Build macOS wheel | |
| uses: ./.github/workflows/build-wheel.yml | |
| needs: tests-unix | |
| with: | |
| python-version: "3.10" | |
| artifact-name: wheels-macos-${{ matrix.target }} | |
| runs-on: macos-latest | |
| secrets: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| strategy: | |
| matrix: | |
| target: [x86_64, aarch64] | |
| if: | | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.author_association == 'COLLABORATOR' || | |
| github.event.pull_request.author_association == 'MEMBER' || | |
| github.event.pull_request.user.login == 'dependabot[bot]' || | |
| contains(github.event.pull_request.labels.*.name, 'safe to test') | |
| test-built-macos-wheel: | |
| name: Test macOS built wheel | |
| needs: build-macos-wheel | |
| runs-on: macos-latest | |
| strategy: | |
| matrix: | |
| target: [x86_64, aarch64] | |
| if: | | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.author_association == 'COLLABORATOR' || | |
| github.event.pull_request.author_association == 'MEMBER' || | |
| github.event.pull_request.user.login == 'dependabot[bot]' || | |
| contains(github.event.pull_request.labels.*.name, 'safe to test') | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| cache: "pip" | |
| - name: Download wheel artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: wheels-macos-${{ matrix.target }} | |
| path: dist | |
| - name: Create and activate virtual environment | |
| run: | | |
| python -m venv venv | |
| source venv/bin/activate | |
| - name: Install wheel for testing | |
| run: | | |
| source venv/bin/activate | |
| pip install dist/c2pa_python-*.whl | |
| - name: Run unittest tests on installed wheel | |
| run: | | |
| source venv/bin/activate | |
| python ./tests/test_unit_tests.py | |
| - name: Install pytest (in venv) | |
| run: | | |
| source venv/bin/activate | |
| pip install pytest | |
| - name: Run tests with pytest (venv) | |
| run: | | |
| source venv/bin/activate | |
| venv/bin/pytest tests/test_unit_tests.py -v | |
| sdist: | |
| runs-on: ubuntu-latest | |
| needs: [tests-unix, tests-windows] | |
| if: | | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.author_association == 'COLLABORATOR' || | |
| github.event.pull_request.author_association == 'MEMBER' || | |
| github.event.pull_request.user.login == 'dependabot[bot]' || | |
| contains(github.event.pull_request.labels.*.name, 'safe to test') | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| cache: "pip" | |
| - name: Install dependencies | |
| run: pip install -r requirements.txt | |
| - name: Build sdist | |
| run: python setup.py sdist | |
| - name: Upload sdist | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: wheels-sdist | |
| path: dist | |
| release: | |
| name: Release | |
| if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true' | |
| runs-on: ubuntu-latest | |
| environment: pypipublish | |
| needs: [test-built-linux-wheel, test-built-macos-wheel, test-built-windows-wheel, sdist] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Create dist directory | |
| run: mkdir -p dist | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: wheels-linux-x86_64 | |
| path: dist-linux | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: wheels-linux-aarch64 | |
| path: dist-linux | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: wheels-macos-x86_64 | |
| path: dist-macos | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: wheels-macos-aarch64 | |
| path: dist-macos | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: wheels-windows-x64 | |
| path: dist-windows | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: wheels-windows-x86 | |
| path: dist-windows | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: wheels-sdist | |
| path: dist-sdist | |
| - name: Debug - List all artifact directories | |
| run: | | |
| echo "Contents of dist-linux:" | |
| ls -la dist-linux/ || echo "dist-linux is empty" | |
| echo "Contents of dist-macos:" | |
| ls -la dist-macos/ || echo "dist-macos is empty" | |
| echo "Contents of dist-windows:" | |
| ls -la dist-windows/ || echo "dist-windows is empty" | |
| echo "Contents of dist-sdist:" | |
| ls -la dist-sdist/ || echo "dist-sdist is empty" | |
| - name: Combine artifacts | |
| run: | | |
| echo "Copying Linux wheels..." | |
| cp -v dist-linux/* dist/ 2>/dev/null || echo "No Linux wheels to copy" | |
| echo "Copying macOS wheels..." | |
| cp -v dist-macos/* dist/ 2>/dev/null || echo "No macOS wheels to copy" | |
| echo "Copying Windows wheels..." | |
| cp -v dist-windows/* dist/ 2>/dev/null || echo "No Windows wheels to copy" | |
| echo "Copying source distribution..." | |
| cp -v dist-sdist/* dist/ 2>/dev/null || echo "No source distribution to copy" | |
| - name: Debug - List final dist directory | |
| run: | | |
| echo "Final contents of dist directory:" | |
| ls -la dist/ || echo "dist is empty" | |
| - name: Publish to TestPyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| packages-dir: dist | |
| # Uncomment to use TestPyPI | |
| repository-url: https://test.pypi.org/legacy/ | |
| verbose: true | |
| # Uncomment below for test runs, otherwise fails on existing packages being reuploaded | |
| skip-existing: true | |