From e05115a9984e84223171331a7c28545491d3cfe5 Mon Sep 17 00:00:00 2001 From: Pavel Zwerschke Date: Fri, 24 Jul 2026 15:51:31 +0200 Subject: [PATCH 1/4] introduce zizmor --- .../workflows/_create-meeting-notes-pr.yml | 27 ++++++---- .github/workflows/_sync-meeting-notes-pr.yml | 4 +- .github/workflows/_sync-steering-members.yml | 2 +- .github/workflows/check-teams.yml | 2 +- .github/workflows/meeting-notes.yml | 9 ++-- .pre-commit-config.yaml | 7 +++ pixi.lock | 53 +++++++++++++++++++ pixi.toml | 1 + 8 files changed, 90 insertions(+), 15 deletions(-) diff --git a/.github/workflows/_create-meeting-notes-pr.yml b/.github/workflows/_create-meeting-notes-pr.yml index ca9bb8a..dc8940e 100644 --- a/.github/workflows/_create-meeting-notes-pr.yml +++ b/.github/workflows/_create-meeting-notes-pr.yml @@ -79,13 +79,17 @@ jobs: python3 -V python3 -m pip install jinja2 requests - name: Prepare date + env: + INPUT_DATE: ${{ inputs.date || 'now' }} run: | - chosen_date="$(date -I -u --date "${{ inputs.date || 'now' }}")" + chosen_date="$(date -I -u --date "$INPUT_DATE")" echo "chosen_date=${chosen_date}" >> $GITHUB_ENV - name: Prepare branch + env: + INPUT_BRANCH_NAME: ${{ inputs.branch_name || '%Y-%m-%d-meeting-notes' }} run: | # Create new branch - branch_name=$(date --date "$chosen_date" "+${{ inputs.branch_name || '%Y-%m-%d-meeting-notes' }}") + branch_name=$(date --date "$chosen_date" "+$INPUT_BRANCH_NAME") if [[ "${{ inputs.force_push }}" == "true" ]]; then git checkout -b "${branch_name}" || git checkout "${branch_name}" else @@ -93,9 +97,12 @@ jobs: fi echo "branch_name=$branch_name" >> $GITHUB_ENV - name: Render template + env: + INPUT_OUTPUT_PATH: ${{ inputs.output_path || 'meeting-notes/%Y-%m-%d.md' }} + INPUT_TEMPLATE_PATH: ${{ inputs.template_path || 'meeting-notes/TEMPLATE.md' }} run: | # Render template - output_path=$(date --date "$chosen_date" "+${{ inputs.output_path || 'meeting-notes/%Y-%m-%d.md' }}") + output_path=$(date --date "$chosen_date" "+$INPUT_OUTPUT_PATH") export output_path mkdir -p "$(dirname "$output_path")" python3 > "$output_path" <> $GITHUB_ENV + echo "pr_title=$(date --date "$chosen_date" "+$INPUT_PR_TITLE")" >> $GITHUB_ENV # We need to escape the backticks in markdown so JS interpolation does not choke - cat <<'EOF' > "$RUNNER_TEMP/pr-body" - ${{ inputs.pr_body || 'PR BODY TEXT EXAMPLE' }} - EOF + printf '%s\n' "$INPUT_PR_BODY" > "$RUNNER_TEMP/pr-body" EOV=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) echo "pr_body<<$EOV" >> $GITHUB_ENV sed 's/`/\\`/g' "$RUNNER_TEMP/pr-body" >> $GITHUB_ENV diff --git a/.github/workflows/_sync-meeting-notes-pr.yml b/.github/workflows/_sync-meeting-notes-pr.yml index 3b164cc..3ff30ce 100644 --- a/.github/workflows/_sync-meeting-notes-pr.yml +++ b/.github/workflows/_sync-meeting-notes-pr.yml @@ -97,6 +97,8 @@ jobs: sys.exit(0) - name: Commit changes (if any) if: ${{ !inputs.dry_run }} + env: + TARGET_REF: ${{ github.head_ref || github.ref_name }} run: | set -x git config user.email "41898282+github-actions[bot]@users.noreply.github.com" @@ -106,7 +108,7 @@ jobs: if ! git diff --exit-code "$DOCPATH"; then git add "$DOCPATH" git commit -m "Update $DOCPATH" - git push origin ${{ github.head_ref || github.ref_name }} + git push origin "$TARGET_REF" else echo "No changes detected." fi diff --git a/.github/workflows/_sync-steering-members.yml b/.github/workflows/_sync-steering-members.yml index 237c901..54f639f 100644 --- a/.github/workflows/_sync-steering-members.yml +++ b/.github/workflows/_sync-steering-members.yml @@ -4,7 +4,7 @@ permissions: actions: read pull-requests: read on: - workflow_run: + workflow_run: # zizmor: ignore[dangerous-triggers] intentional: privileged sync must run after the untrusted "Steering members" workflow completes workflows: [Steering members] types: [completed] jobs: diff --git a/.github/workflows/check-teams.yml b/.github/workflows/check-teams.yml index 337f4de..a78ec30 100644 --- a/.github/workflows/check-teams.yml +++ b/.github/workflows/check-teams.yml @@ -1,7 +1,7 @@ name: Teams on: workflow_dispatch: - pull_request_target: + pull_request_target: # zizmor: ignore[dangerous-triggers] intentional: fork PRs need access to CONDA_ORG_WIDE_* secrets to validate teams paths: - teams/*.yml - teams/*.yaml diff --git a/.github/workflows/meeting-notes.yml b/.github/workflows/meeting-notes.yml index 2160e45..ce7425e 100644 --- a/.github/workflows/meeting-notes.yml +++ b/.github/workflows/meeting-notes.yml @@ -16,15 +16,15 @@ on: pull_request: types: - labeled -permissions: - contents: write - pull-requests: write # You need to enable 'Allow GitHub Actions to create and approve pull requests' # in your Actions Settings too jobs: create: if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + permissions: + contents: write + pull-requests: write uses: ./.github/workflows/_create-meeting-notes-pr.yml with: date: ${{ github.event_name == 'schedule' && 'next Wednesday' || (inputs.date || 'now') }} @@ -40,6 +40,9 @@ jobs: HACKMD_TOKEN: ${{ secrets.HACKMD_TOKEN }} sync: if: github.event.label.name == 'sync-hackmd-notes' + permissions: + contents: write + pull-requests: write uses: ./.github/workflows/_sync-meeting-notes-pr.yml with: pr_number: ${{ github.event.number }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1c246c9..9e181f1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -95,3 +95,10 @@ repos: exclude_types: [csv] types: [text] args: [--write-changes] + # zizmor + - id: zizmor + name: zizmor + entry: pixi run zizmor --min-severity high --fix . + language: system + types: [yaml] + pass_filenames: false diff --git a/pixi.lock b/pixi.lock index 6601e40..1761f8c 100644 --- a/pixi.lock +++ b/pixi.lock @@ -56,6 +56,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.1.0-py314h9891dd4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/yamlfmt-0.21.0-hfc2019e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zizmor-1.27.0-hb17b654_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda @@ -166,6 +167,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/ukkonen-1.1.0-py314h473ef84_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h4132b18_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/yamlfmt-0.21.0-hccc6df8_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zizmor-1.27.0-h19f9e61_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda @@ -234,6 +236,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.1.0-py314h6cfcd04_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yamlfmt-0.21.0-h820172f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zizmor-1.27.0-h6fdd925_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda win-64: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda @@ -305,6 +308,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36231-h1b9f54f_39.conda - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/yamlfmt-0.21.0-h11686cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zizmor-1.27.0-h18a1a76_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda packages: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda @@ -735,6 +739,19 @@ packages: run_exports: {} size: 1839020 timestamp: 1767643136135 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zizmor-1.27.0-hb17b654_0.conda + sha256: f19c1c24ba7558abe89d19d950da1c0f7053936c55601b347ba80f74a5a14983 + md5: b3ff4c7694157201ba382c8bf6e18fbe + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - __glibc >=2.17 + license: MIT + license_family: MIT + run_exports: {} + size: 7021312 + timestamp: 1784027920046 - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 @@ -1625,6 +1642,18 @@ packages: run_exports: {} size: 1857511 timestamp: 1767643180159 +- conda: https://conda.anaconda.org/conda-forge/osx-64/zizmor-1.27.0-h19f9e61_0.conda + sha256: db8764ab4e1ea7816dce5dfa8a93f1f41f691e6c470b701c1f4510e5af90f458 + md5: 5ec6d7f794397573771e3e7213566617 + depends: + - __osx >=11.0 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + run_exports: {} + size: 6919566 + timestamp: 1784027984539 - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda sha256: 47101a4055a70a4876ffc87b750ab2287b67eca793f21c8224be5e1ee6394d3f md5: 727109b184d680772e3122f40136d5ca @@ -1975,6 +2004,18 @@ packages: run_exports: {} size: 1679631 timestamp: 1767643185192 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zizmor-1.27.0-h6fdd925_0.conda + sha256: 588c87a1449c96daed94dc0cc6c747d3e371d5b07edeaa670ad96449a42989e3 + md5: 1a5b951f52d047d4ca5063da6a58e847 + depends: + - __osx >=11.0 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + run_exports: {} + size: 6430218 + timestamp: 1784027972251 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda sha256: 9485ba49e8f47d2b597dd399e88f4802e100851b27c21d7525625b0b4025a5d9 md5: ab136e4c34e97f34fb621d2592a393d8 @@ -2361,6 +2402,18 @@ packages: run_exports: {} size: 1821445 timestamp: 1767643175556 +- conda: https://conda.anaconda.org/conda-forge/win-64/zizmor-1.27.0-h18a1a76_0.conda + sha256: dbe4a5f5d1a901dc0c60d9f17d75247de4ea186b84016659fa33c1189c108f6f + md5: 33aeaa9ad47e6e7b3fe04c923465b4c0 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + run_exports: {} + size: 7217865 + timestamp: 1784027958345 - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda sha256: 368d8628424966fd8f9c8018326a9c779e06913dd39e646cf331226acc90e5b2 md5: 053b84beec00b71ea8ff7a4f84b55207 diff --git a/pixi.toml b/pixi.toml index cee4938..484e077 100644 --- a/pixi.toml +++ b/pixi.toml @@ -17,6 +17,7 @@ ruff = "*" codespell = "*" yamlfmt = "*" tombi = "*" +zizmor = "*" [tasks] lint = "pre-commit run --all-files" From 2ccb922c5951a3c262dc231a214fed46643b112e Mon Sep 17 00:00:00 2001 From: Pavel Zwerschke Date: Fri, 24 Jul 2026 15:55:30 +0200 Subject: [PATCH 2/4] remove sync-steering-members --- .github/workflows/_sync-steering-members.yml | 59 -------------------- 1 file changed, 59 deletions(-) delete mode 100644 .github/workflows/_sync-steering-members.yml diff --git a/.github/workflows/_sync-steering-members.yml b/.github/workflows/_sync-steering-members.yml deleted file mode 100644 index 54f639f..0000000 --- a/.github/workflows/_sync-steering-members.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: Sync steering members -permissions: - contents: write - actions: read - pull-requests: read -on: - workflow_run: # zizmor: ignore[dangerous-triggers] intentional: privileged sync must run after the untrusted "Steering members" workflow completes - workflows: [Steering members] - types: [completed] -jobs: - sync: - if: github.event.workflow_run.conclusion == 'failure' - runs-on: ubuntu-slim - steps: - - name: Download artifact - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: steering-checklist - path: steering-sync/ - run-id: ${{ github.event.workflow_run.id }} - github-token: ${{ github.token }} - - name: Read and validate PR number - id: pr - run: | - pr_number="$(cat steering-sync/pr_number)" - if ! echo "$pr_number" | grep -qE '^[0-9]+$'; then - echo "::error::Invalid PR number: $pr_number" - exit 1 - fi - echo "number=$pr_number" >> "$GITHUB_OUTPUT" - - name: Resolve PR branch - id: branch - env: - GH_TOKEN: ${{ github.token }} - PR_NUMBER: ${{ steps.pr.outputs.number }} - run: | - pr_json="$(gh api "repos/${{ github.repository }}/pulls/$PR_NUMBER" --jq '{ref: .head.ref, repo: .head.repo.full_name}')" - echo "ref=$(echo "$pr_json" | jq -r .ref)" >> "$GITHUB_OUTPUT" - echo "repo=$(echo "$pr_json" | jq -r .repo)" >> "$GITHUB_OUTPUT" - - name: Check out PR branch - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - ref: ${{ steps.branch.outputs.ref }} - repository: ${{ steps.branch.outputs.repo }} - - name: Apply updated files - run: | - cd steering-sync - find . -type f ! -name pr_number | while read -r f; do - cp "$f" "$GITHUB_WORKSPACE/$f" - done - - name: Commit and push - run: | - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config user.name "github-actions[bot]" - if ! git diff --quiet; then - git add -A - git commit -m "Sync steering member checklist from steering.csv" - git push - fi From 88fa5dd1577270b2a04349de8fc30020b087e8a9 Mon Sep 17 00:00:00 2001 From: Pavel Zwerschke Date: Fri, 24 Jul 2026 16:37:01 +0200 Subject: [PATCH 3/4] remove check-teams (was broken anyway) --- .github/workflows/check-teams.yml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/workflows/check-teams.yml diff --git a/.github/workflows/check-teams.yml b/.github/workflows/check-teams.yml deleted file mode 100644 index 8b2e248..0000000 --- a/.github/workflows/check-teams.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Teams -on: - workflow_dispatch: - pull_request_target: # zizmor: ignore[dangerous-triggers] intentional: fork PRs need access to CONDA_ORG_WIDE_* secrets to validate teams - paths: - - teams/*.yml - - teams/*.yaml - - teams/*.schema.json - - scripts/schemas.py -jobs: - check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - uses: prefix-dev/setup-pixi@a09b6247153796b190642a2b53fac4241043cf6f # v0.10.0 - - run: pixi run check_teams - env: - CONDA_ORG_WIDE_TOKEN: ${{ secrets.CONDA_ORG_WIDE_READ_ONLY }} - CONDA_INCUBATOR_ORG_WIDE_TOKEN: ${{ secrets.CONDA_INCUBATOR_ORG_WIDE_READ_ONLY }} From a8811e6f28328bfb22d65998f97c3e25727886c2 Mon Sep 17 00:00:00 2001 From: Pavel Zwerschke Date: Fri, 24 Jul 2026 16:44:32 +0200 Subject: [PATCH 4/4] also remove sync-steering-members --- .github/ISSUE_TEMPLATE/graduation_request.yml | 5 --- .github/workflows/check-steering-members.yml | 45 ------------------- .pre-commit-config.yaml | 8 ++++ 3 files changed, 8 insertions(+), 50 deletions(-) delete mode 100644 .github/workflows/check-steering-members.yml diff --git a/.github/ISSUE_TEMPLATE/graduation_request.yml b/.github/ISSUE_TEMPLATE/graduation_request.yml index 28bc377..5f29ca1 100644 --- a/.github/ISSUE_TEMPLATE/graduation_request.yml +++ b/.github/ISSUE_TEMPLATE/graduation_request.yml @@ -134,11 +134,6 @@ body: - [ ] no - [ ] abstain - @mbargull (Marcel Bargull) - - [ ] yes - - [ ] no - - [ ] abstain - @jakirkham (John Kirkham) - [ ] yes - [ ] no diff --git a/.github/workflows/check-steering-members.yml b/.github/workflows/check-steering-members.yml deleted file mode 100644 index 1fd855b..0000000 --- a/.github/workflows/check-steering-members.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Steering members -on: - workflow_dispatch: - pull_request: - paths: - - steering.csv -permissions: - contents: read -jobs: - check: - runs-on: ubuntu-slim - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - uses: prefix-dev/setup-pixi@a09b6247153796b190642a2b53fac4241043cf6f # v0.10.0 - - name: Check steering member checklist - id: check - run: | - if pixi run sync_steering_members -- --check; then - echo "stale=false" >> "$GITHUB_OUTPUT" - else - echo "stale=true" >> "$GITHUB_OUTPUT" - pixi run sync_steering_members - fi - - name: Prepare artifact - if: steps.check.outputs.stale == 'true' && github.event_name == 'pull_request' - run: | - mkdir -p steering-sync/.github/ISSUE_TEMPLATE - git diff --name-only | while read -r f; do - cp "$f" "steering-sync/$f" - done - echo "$PR_NUMBER" > steering-sync/pr_number - env: - PR_NUMBER: ${{ github.event.pull_request.number }} - - name: Upload artifact - if: steps.check.outputs.stale == 'true' && github.event_name == 'pull_request' - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: steering-checklist - path: steering-sync/ - retention-days: 1 - - name: Fail if stale - if: steps.check.outputs.stale == 'true' - run: exit 1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9e181f1..f1f6ed0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -102,3 +102,11 @@ repos: language: system types: [yaml] pass_filenames: false + # custom hooks + - id: sync-steering-members + name: Sync steering members + entry: pixi run sync_steering_members + language: system + always_run: true + pass_filenames: false + require_serial: true