feat: use uv #44
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: Python CI | |
| on: | |
| pull_request: | |
| branches: [ main, master ] | |
| push: | |
| branches: [ main, master ] | |
| release: | |
| types: [ released ] | |
| workflow_dispatch: | |
| jobs: | |
| lint: | |
| runs-on: ubuntu-latest | |
| name: Lint | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 20 | |
| - name: Install node deps | |
| working-directory: server/frontend | |
| run: npm install | |
| - name: Install pre-commit | |
| run: pipx install pre-commit | |
| - name: Run linters | |
| run: pre-commit run -a | |
| test: | |
| name: Python ${{ matrix.python-version }} (${{ matrix.platform }}) | |
| needs: lint | |
| runs-on: ${{ matrix.platform }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - python-version: "3.10" | |
| platform: ubuntu-latest | |
| toxenv: py310 | |
| - python-version: "3.11" | |
| platform: ubuntu-latest | |
| toxenv: py311 | |
| - python-version: "3.12" | |
| platform: ubuntu-latest | |
| toxenv: py312 | |
| - python-version: "3.13" | |
| platform: ubuntu-latest | |
| toxenv: py313 | |
| - python-version: "3.14" | |
| platform: ubuntu-latest | |
| toxenv: py314 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: astral-sh/setup-uv@v7 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Run tests | |
| run: uvx --from tox-uv tox -e ${{ matrix.toxenv }} | |
| - uses: codecov/codecov-action@v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| verbose: true | |
| node-build: | |
| name: Build frontend node 20 | |
| needs: lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 20 | |
| - name: Install node deps | |
| working-directory: server/frontend | |
| run: npm install | |
| - name: Run tests | |
| working-directory: server/frontend | |
| run: npm run test | |
| - name: Production build | |
| working-directory: server/frontend | |
| run: npm run production | |
| - uses: codecov/codecov-action@v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| verbose: true | |
| docker-build: | |
| name: Docker build | |
| needs: [lint, node-build] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Write SCM version | |
| id: scm_version | |
| run: | | |
| pipx install hatch | |
| echo "scm_version=$(hatch version)" >> "$GITHUB_OUTPUT" | |
| - name: Build and export | |
| uses: docker/build-push-action@v6 | |
| with: | |
| tags: mozillasecurity/fuzzmanager:latest | |
| outputs: type=docker,dest=${{ runner.temp }}/fuzzmanager.tar | |
| build-args: | | |
| SETUPTOOLS_SCM_PRETEND_VERSION_FOR_FuzzManager=${{ steps.scm_version.outputs.scm_version }} | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: docker-image | |
| path: ${{ runner.temp }}/fuzzmanager.tar | |
| docker-push: | |
| name: Docker push | |
| environment: dockerhub | |
| needs: [docker-build, test] | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main') | |
| steps: | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Download artifact | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: docker-image | |
| path: ${{ runner.temp }} | |
| - name: Load image | |
| run: | | |
| docker load --input ${{ runner.temp }}/fuzzmanager.tar | |
| docker image ls -a | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ vars.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Push image | |
| run: | | |
| docker push mozillasecurity/fuzzmanager:latest | |
| python-build: | |
| name: Python build | |
| needs: test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - uses: astral-sh/setup-uv@v7 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Build Python distributions | |
| run: uv build | |
| - name: Strip git URLs from sdist (PyPI requirement) | |
| run: | | |
| WORK="$(mktemp -d)" | |
| TAR="$(ls dist/*.tar.*)" | |
| tar -C "$WORK" -xvaf "$TAR" | |
| sed -Ei 's/^(Requires-Dist:\s*[A-Za-z0-9][A-Za-z0-9._-]*)\s*@\s*([^ ]+)(.*)$/\1\3/' "$WORK"/*/PKG-INFO | |
| FN="$(ls "$WORK")" | |
| rm "$TAR" | |
| tar -C "$WORK" -cvaf "$TAR" "$FN" | |
| rm -rf "$WORK" | |
| - name: Check Python distributions | |
| run: uvx twine check dist/* | |
| - name: Store build artifacts | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: python-package-distributions | |
| path: dist/ | |
| pypi: | |
| name: Publish Python distribution to PyPI | |
| if: github.event_name == 'release' | |
| needs: python-build | |
| runs-on: ubuntu-latest | |
| environment: pypi | |
| permissions: | |
| id-token: write | |
| steps: | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: python-package-distributions | |
| path: dist/ | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| verbose: true |