From 0e6b7f0de50d0d802bfb50472839c83c0af7616c Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Thu, 31 Oct 2024 10:05:57 +0100 Subject: [PATCH] Thank you Doctor Zizmor! (#663) --- .github/workflows/build-docset.yml | 1 + .github/workflows/ci.yml | 78 +++++++++++++++++---------- .github/workflows/codeql-analysis.yml | 2 + .github/workflows/pypi-package.yml | 21 +++++--- .github/workflows/zizmor.yml | 37 +++++++++++++ 5 files changed, 103 insertions(+), 36 deletions(-) create mode 100644 .github/workflows/zizmor.yml diff --git a/.github/workflows/build-docset.yml b/.github/workflows/build-docset.yml index 110532fe..fe14f451 100644 --- a/.github/workflows/build-docset.yml +++ b/.github/workflows/build-docset.yml @@ -19,6 +19,7 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 # get correct version + persist-credentials: false - uses: actions/setup-python@v5 with: python-version: "3.12" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e6eee1fd..47a43a65 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,7 @@ env: permissions: {} + jobs: build-package: name: Build & verify package @@ -23,20 +24,25 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 + persist-credentials: false - uses: hynek/build-and-inspect-python-package@v2 id: baipp outputs: + # Used to define the matrix for tests below. The value is based on + # packaging metadata (trove classifiers). python-versions: ${{ steps.baipp.outputs.supported_python_classifiers_json_array }} tests: - name: Tests & API Mypy on ${{ matrix.python-version }} - needs: build-package + name: Tests & Mypy API on ${{ matrix.python-version }} runs-on: ubuntu-latest + needs: build-package + strategy: fail-fast: false matrix: + # Created by the build-and-inspect-python-package action above. python-version: ${{ fromJson(needs.build-package.outputs.python-versions) }} steps: @@ -45,18 +51,22 @@ jobs: with: name: Packages path: dist - - run: tar xf dist/*.tar.gz --strip-components=1 + - run: | + tar xf dist/*.tar.gz --strip-components=1 + rm -rf src - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} allow-prereleases: true - uses: hynek/setup-cached-uv@v2 - - run: > - uvx --with=tox-uv - tox run + - name: Run tests + env: + PYTHON: ${{ matrix.python-version }} + run: > + uvx --with tox-uv tox run --installpkg dist/*.whl - -f py$(echo ${{ matrix.python-version }} | tr -d .) + -f py${PYTHON//./}-tests - name: Upload coverage data uses: actions/upload-artifact@v4 @@ -66,23 +76,36 @@ jobs: include-hidden-files: true if-no-files-found: ignore + - name: Check public API with Mypy + env: + PYTHON: ${{ matrix.python-version }} + run: > + uvx --with tox-uv tox run + --installpkg dist/*.whl + -e py${PYTHON//./}-mypy + coverage: - name: Combine & check coverage - needs: tests + name: Ensure 100% test coverage runs-on: ubuntu-latest + needs: tests + if: always() steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - uses: actions/setup-python@v5 with: python-version-file: .python-version-default - uses: hynek/setup-cached-uv@v2 - - uses: actions/download-artifact@v4 + + - name: Download coverage data + uses: actions/download-artifact@v4 with: pattern: coverage-data-* merge-multiple: true - - name: Combine coverage & fail if it's <100%. + - name: Combine coverage and fail if it's <100%. run: | uv tool install coverage @@ -103,9 +126,9 @@ jobs: if: ${{ failure() }} mypy-pkg: - name: Type-check package - needs: build-package + name: Mypy Codebase runs-on: ubuntu-latest + needs: build-package steps: - name: Download pre-built packages @@ -117,20 +140,16 @@ jobs: - uses: actions/setup-python@v5 with: python-version-file: .python-version-default - allow-prereleases: true - uses: hynek/setup-cached-uv@v2 - run: > - uvx --with=tox-uv - tox run - --installpkg dist/*.whl - -e mypy-pkg + uvx --with tox-uv + tox run -e mypy-pkg pyright: - name: Pyright + name: Pyright Codebase runs-on: ubuntu-latest needs: build-package - steps: - name: Download pre-built packages uses: actions/download-artifact@v4 @@ -141,14 +160,12 @@ jobs: - uses: actions/setup-python@v5 with: python-version-file: .python-version-default - allow-prereleases: true - uses: hynek/setup-cached-uv@v2 - run: > - uvx --with=tox-uv - tox run - --installpkg dist/*.whl - -e pyright + uvx --with tox-uv + tox run -e pyright + docs: name: Build docs & run doctests @@ -168,9 +185,8 @@ jobs: - uses: hynek/setup-cached-uv@v2 - run: > - uvx --with=tox-uv - tox run - -e docs + uvx --with tox-uv + tox run -e docs install-dev: name: Verify dev env @@ -181,6 +197,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - uses: actions/setup-python@v5 with: python-version-file: .python-version-default @@ -200,10 +218,10 @@ jobs: needs: - coverage - - docs - install-dev - mypy-pkg - pyright + - docs runs-on: ubuntu-latest @@ -220,6 +238,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - uses: actions/setup-python@v5 with: python-version-file: .python-version-default diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 68f325e6..7907ccb0 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -25,6 +25,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + persist-credentials: false - name: Initialize CodeQL uses: github/codeql-action/init@v3 diff --git a/.github/workflows/pypi-package.yml b/.github/workflows/pypi-package.yml index 43093ce5..9417b97d 100644 --- a/.github/workflows/pypi-package.yml +++ b/.github/workflows/pypi-package.yml @@ -1,5 +1,5 @@ --- -name: Build & maybe upload PyPI package +name: Build & upload PyPI package on: push: @@ -10,20 +10,21 @@ on: - published workflow_dispatch: -permissions: - attestations: write - contents: read - id-token: write jobs: + # Always build & lint package. build-package: name: Build & verify package runs-on: ubuntu-latest + permissions: + attestations: write + id-token: write steps: - uses: actions/checkout@v4 with: fetch-depth: 0 + persist-credentials: false - uses: hynek/build-and-inspect-python-package@v2 with: @@ -33,10 +34,13 @@ jobs: release-test-pypi: name: Publish in-dev package to test.pypi.org environment: release-test-pypi - if: github.event_name == 'push' && github.ref == 'refs/heads/main' + if: github.repository_owner == 'hynek' && github.event_name == 'push' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest needs: build-package + permissions: + id-token: write + steps: - name: Download packages built by build-and-inspect-python-package uses: actions/download-artifact@v4 @@ -53,10 +57,13 @@ jobs: release-pypi: name: Publish released package to pypi.org environment: release-pypi - if: github.event.action == 'published' + if: github.repository_owner == 'hynek' && github.event.action == 'published' runs-on: ubuntu-latest needs: build-package + permissions: + id-token: write + steps: - name: Download packages built by build-and-inspect-python-package uses: actions/download-artifact@v4 diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 00000000..08294a4a --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,37 @@ +# https://github.com/woodruffw/zizmor +name: GitHub Actions Security Analysis with Zizmor + +on: + push: + branches: ["main"] + pull_request: + branches: ["*"] + +permissions: + contents: read + +jobs: + zizmor: + name: Zizmor latest via Cargo + runs-on: ubuntu-latest + permissions: + security-events: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + persist-credentials: false + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + - name: Get zizmor + run: cargo install zizmor + - name: Run zizmor + run: zizmor --format sarif . > results.sarif + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v3 + with: + # Path to SARIF file relative to the root of the repository + sarif_file: results.sarif + # Optional category for the results + # Used to differentiate multiple results for one commit + category: zizmor