From 193eb3e6d3a877d68ab9df2dfe1d1547698a3b97 Mon Sep 17 00:00:00 2001 From: Jerome Kelleher Date: Fri, 26 Jun 2026 12:33:58 +0100 Subject: [PATCH 1/3] Add zizmor and harden GitHub Actions workflows --- .github/workflows/docs.yml | 3 +++ .github/workflows/lint.yml | 3 +++ .github/workflows/tests.yml | 7 ++++++- .github/workflows/wheels.yml | 17 +++++++++++------ .github/zizmor.yml | 9 +++++++++ prek.toml | 13 +++++++++++++ pyproject.toml | 1 + uv.lock | 22 ++++++++++++++++++++++ 8 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 .github/zizmor.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 4e39993..a87d102 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -8,6 +8,9 @@ on: - '*' merge_group: +permissions: + contents: read + jobs: Docs: uses: tskit-dev/.github/.github/workflows/docs.yml@v17 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e72945b..8925933 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -3,6 +3,9 @@ name: Lint on: pull_request: +permissions: + contents: read + jobs: Lint: uses: tskit-dev/.github/.github/workflows/lint.yml@v17 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 464c6d6..9e7b9f6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -6,6 +6,9 @@ on: branches: [main, test] merge_group: +permissions: + contents: read + jobs: packaging: name: Python packaging @@ -13,7 +16,9 @@ jobs: test: name: Python - uses: tskit-dev/.github/.github/workflows/python-tests.yml@v17 + # Trusted first-party tskit-dev reusable workflow that needs inherited + # secrets (e.g. CODECOV_TOKEN). + uses: tskit-dev/.github/.github/workflows/python-tests.yml@v17 # zizmor: ignore[secrets-inherit] with: os: ${{ matrix.os }} python-version: ${{ matrix.python }} diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 2558727..6bba338 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -6,23 +6,28 @@ on: release: types: [published] +permissions: + contents: read + jobs: build: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 + persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: version: "0.10.0" + enable-cache: false - name: Build run: uv build - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: dist path: dist/ @@ -34,18 +39,18 @@ jobs: permissions: id-token: write steps: - - uses: actions/download-artifact@v7.0.0 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: dist path: dist - name: Publish to TestPyPI if: github.event_name == 'push' && github.ref_name == 'test-publish' - uses: pypa/gh-action-pypi-publish@v1.13.0 + uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 with: repository-url: https://test.pypi.org/legacy/ verbose: true - name: Publish to PyPI if: github.event_name == 'release' - uses: pypa/gh-action-pypi-publish@v1.13.0 + uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000..cf48ef4 --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,9 @@ +# zizmor configuration for tskit-dev repos. +# Third-party actions must be hash-pinned; first-party tskit-dev reusable +# workflows are trusted and may stay pinned to a version tag (e.g. @v17). +rules: + unpinned-uses: + config: + policies: + tskit-dev/*: ref-pin + "*": hash-pin diff --git a/prek.toml b/prek.toml index d809628..593f6ae 100644 --- a/prek.toml +++ b/prek.toml @@ -38,3 +38,16 @@ hooks = [ types = ["python"], }, ] + +[[repos]] +repo = "local" +hooks = [ + { + id = "zizmor", + name = "zizmor", + language = "system", + entry = "uv run --only-group=lint zizmor", + files = "^\\.github/workflows/.*\\.ya?ml$", + pass_filenames = true, + }, +] diff --git a/pyproject.toml b/pyproject.toml index a173c75..4aeb490 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,6 +83,7 @@ docs = [ lint = [ "ruff==0.15.1", "prek==0.3.3", + "zizmor==1.26.1", ] packaging = [ diff --git a/uv.lock b/uv.lock index 1033ab7..e5e5c24 100644 --- a/uv.lock +++ b/uv.lock @@ -2973,6 +2973,7 @@ dev = [ { name = "sphinx-issues" }, { name = "twine" }, { name = "validate-pyproject", extra = ["all"] }, + { name = "zizmor" }, ] docs = [ { name = "jupyter-book" }, @@ -2985,6 +2986,7 @@ docs = [ lint = [ { name = "prek" }, { name = "ruff" }, + { name = "zizmor" }, ] packaging = [ { name = "twine" }, @@ -3035,6 +3037,7 @@ dev = [ { name = "sphinx-issues" }, { name = "twine" }, { name = "validate-pyproject", extras = ["all"] }, + { name = "zizmor", specifier = "==1.26.1" }, ] docs = [ { name = "jupyter-book", specifier = "<2" }, @@ -3047,6 +3050,7 @@ docs = [ lint = [ { name = "prek", specifier = "==0.3.3" }, { name = "ruff", specifier = "==0.15.1" }, + { name = "zizmor", specifier = "==1.26.1" }, ] packaging = [ { name = "twine" }, @@ -3176,3 +3180,21 @@ sdist = { url = "https://files.pythonhosted.org/packages/e3/02/0f2892c661036d50e wheels = [ { url = "https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e", size = 10276, upload-time = "2025-06-08T17:06:38.034Z" }, ] + +[[package]] +name = "zizmor" +version = "1.26.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/a0/a29b38e24981b4bb41db4f292b2c9fb9ddf8b05d6b724abddd7bd108b621/zizmor-1.26.1.tar.gz", hash = "sha256:0c2cc575007a4db99d89d5acc6120cfa7b61504bc2394c3b50af348c73f1916e", size = 535275, upload-time = "2026-06-21T02:47:21.265Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/a9/2f47f7db8db9491025e00a7f1a0f25d32b642c0285b2fe070ac63e679b47/zizmor-1.26.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7ea21ca959c8e888de238fee81d73a1fdf89a82067eac75b8f1acdbd23e2eeaf", size = 9086061, upload-time = "2026-06-21T02:46:57.492Z" }, + { url = "https://files.pythonhosted.org/packages/58/92/cf6801f01e1d65cbda89a2e2926ea42caf1daad9ffa3f1fc88e4c68f48a9/zizmor-1.26.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:78083b495593f8b0b9dec14036a0836a5afcddda8a40738336ff4e399476b741", size = 8626865, upload-time = "2026-06-21T02:47:00.323Z" }, + { url = "https://files.pythonhosted.org/packages/b4/b1/ff38fc2921f1fb13244bb3a3642c4b45ecf3946c279942aafcb5dbf55a57/zizmor-1.26.1-py3-none-manylinux_2_24_aarch64.whl", hash = "sha256:bb7ebbe565a3742eb49a590352127ad549bb122b9b4ff9424ebab7525fa3b6b6", size = 8843965, upload-time = "2026-06-21T02:47:03.318Z" }, + { url = "https://files.pythonhosted.org/packages/3d/06/c07fd0eeef0427d93e99d552d5386526fbcd0bf05fc95cd37bdc6229fccb/zizmor-1.26.1-py3-none-manylinux_2_28_armv7l.whl", hash = "sha256:d3049010b6bd6f849413b6d20c28e0c677b90e0a5b2bc73cbee7f7bd86dc5828", size = 8386985, upload-time = "2026-06-21T02:47:05.741Z" }, + { url = "https://files.pythonhosted.org/packages/a8/2b/61ab13d45d6ce57ef5a08bb3246981f62e30bb4938098b17bb7b88110b79/zizmor-1.26.1-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:6a958d8a0941d7e1d0de8436670b5cb7fc64c8028b4d16e3f519ccc77f953cef", size = 9257232, upload-time = "2026-06-21T02:47:07.941Z" }, + { url = "https://files.pythonhosted.org/packages/e3/ad/bd74a96cb02045414ec5b573cd97ff3b82a97fd0bd6658f93c36a011c439/zizmor-1.26.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d2744cdf944436ca7a009ae8b626a017a40381ec990216abd6cf6b8beb23323a", size = 8873798, upload-time = "2026-06-21T02:47:10.472Z" }, + { url = "https://files.pythonhosted.org/packages/b8/7e/fb3d608ee11e2f619d43ad93bab46eb7b32769fa82b1d86fd23f27c2585b/zizmor-1.26.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:44099f426af9da750ff9f548a0084e11d7d83e0158fe1a2778672398d728efdd", size = 8350857, upload-time = "2026-06-21T02:47:12.748Z" }, + { url = "https://files.pythonhosted.org/packages/27/cc/82d7a838c2d490071555c364f90eb851044b3eeefc1d68612179a2cd1ae5/zizmor-1.26.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:8313cc264dec792f00a7328eb7c8e89e7d62d54f950fc897d1e6a5a6e5762203", size = 9351148, upload-time = "2026-06-21T02:47:14.777Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ee/d2a2301f30b9e1bf0d721bfd31739acd71e048757f9ba79279583eb30ac0/zizmor-1.26.1-py3-none-win32.whl", hash = "sha256:c96d7787d69fb298eae939e00dfdf7f534d7dfbd9cc17ab442c0650a56851415", size = 7531021, upload-time = "2026-06-21T02:47:17.247Z" }, + { url = "https://files.pythonhosted.org/packages/91/58/ad561f3a5057d3c0f152002e180a3a5745e72ea9d69bf66450ef9f5d3fe5/zizmor-1.26.1-py3-none-win_amd64.whl", hash = "sha256:0a05acf6068609fb6df3b137276cf18a686226a1e0e207941cb34a85929f16cf", size = 8616584, upload-time = "2026-06-21T02:47:19.094Z" }, +] From af3a5ba640417c0e4d56ff190e30c77b86cee452 Mon Sep 17 00:00:00 2001 From: Jerome Kelleher Date: Tue, 30 Jun 2026 13:50:17 +0100 Subject: [PATCH 2/3] Pin tskit-dev shared workflows to v18 --- .github/workflows/docs.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/tests.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a87d102..5e7762b 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -13,4 +13,4 @@ permissions: jobs: Docs: - uses: tskit-dev/.github/.github/workflows/docs.yml@v17 + uses: tskit-dev/.github/.github/workflows/docs.yml@v18 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 8925933..10c0334 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,4 +8,4 @@ permissions: jobs: Lint: - uses: tskit-dev/.github/.github/workflows/lint.yml@v17 + uses: tskit-dev/.github/.github/workflows/lint.yml@v18 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9e7b9f6..2b45165 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,7 +12,7 @@ permissions: jobs: packaging: name: Python packaging - uses: tskit-dev/.github/.github/workflows/python-packaging.yml@v17 + uses: tskit-dev/.github/.github/workflows/python-packaging.yml@v18 test: name: Python From 8ae78c4d46a8c00723b30760755f2423681997f7 Mon Sep 17 00:00:00 2001 From: Jerome Kelleher Date: Tue, 30 Jun 2026 14:32:07 +0100 Subject: [PATCH 3/3] Pass CODECOV_TOKEN explicitly and pin shared workflows to v19 --- .github/workflows/docs.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/tests.yml | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 5e7762b..9cdc583 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -13,4 +13,4 @@ permissions: jobs: Docs: - uses: tskit-dev/.github/.github/workflows/docs.yml@v18 + uses: tskit-dev/.github/.github/workflows/docs.yml@v19 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 10c0334..0c20add 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,4 +8,4 @@ permissions: jobs: Lint: - uses: tskit-dev/.github/.github/workflows/lint.yml@v18 + uses: tskit-dev/.github/.github/workflows/lint.yml@v19 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2b45165..2ac3ac7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,18 +12,17 @@ permissions: jobs: packaging: name: Python packaging - uses: tskit-dev/.github/.github/workflows/python-packaging.yml@v18 + uses: tskit-dev/.github/.github/workflows/python-packaging.yml@v19 test: name: Python - # Trusted first-party tskit-dev reusable workflow that needs inherited - # secrets (e.g. CODECOV_TOKEN). - uses: tskit-dev/.github/.github/workflows/python-tests.yml@v17 # zizmor: ignore[secrets-inherit] + uses: tskit-dev/.github/.github/workflows/python-tests.yml@v19 with: os: ${{ matrix.os }} python-version: ${{ matrix.python }} coverage-directory: tstrait - secrets: inherit + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} strategy: matrix: python: ["3.11", "3.13"]