From d1314018ccccaad750d2f79c3d4cda385c7967c9 Mon Sep 17 00:00:00 2001 From: Daniel Hast Date: Sat, 7 Mar 2026 14:29:15 -0500 Subject: [PATCH 1/5] ci: pin third-party action dependencies to commit hashes This improves CI security by ensuring that action dependencies cannot be changed by upstream repositories without updating the use of the dependency in this repo. Official GitHub-maintained actions are excluded from this requirement and are left pinned by a tag instead of a commit hash. This action dependency pinning policy is codified in `.github/zizmor.yml` so that Zizmor (a static analysis tool for GitHub Actions) doesn't flag these as unpinned dependencies. Also add cooldown timer for Dependabot. This fixes these two Zizmor audits: * https://docs.zizmor.sh/audits/#dependabot-cooldown * https://docs.zizmor.sh/audits/#unpinned-uses --- .github/dependabot.yml | 2 ++ .github/workflows/backport.yml | 2 +- .github/workflows/test.yml | 6 +++--- .github/workflows/test_windows.yml | 2 +- .github/zizmor.yml | 6 ++++++ 5 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 .github/zizmor.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e96fd5286f..70f4a2749a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,3 +6,5 @@ updates: interval: "daily" commit-message: prefix: "ci" + cooldown: + default-days: 7 diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index f29f0bad8d..20e8c8e94f 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -21,7 +21,7 @@ jobs: - name: Create backport PR id: backport - uses: korthout/backport-action@v4 + uses: korthout/backport-action@4aaf0e03a94ff0a619c9a511b61aeb42adea5b02 # v4.2.0 with: pull_title: "${pull_title}" label_pattern: "^ci:backport ([^ ]+)$" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 68a2344bc7..68a065acbd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -236,7 +236,7 @@ jobs: OPTS: -Doptimize=ReleaseSafe steps: - uses: actions/checkout@v6 - - uses: mlugg/setup-zig@v2 + - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: version: 0.15.2 - run: sudo apt-get install -y inotify-tools @@ -256,7 +256,7 @@ jobs: name: build using zig build (macos 15) steps: - uses: actions/checkout@v6 - - uses: mlugg/setup-zig@v2 + - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: version: 0.15.2 @@ -270,7 +270,7 @@ jobs: name: build using zig build (windows) steps: - uses: actions/checkout@v6 - - uses: mlugg/setup-zig@v2 + - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: version: 0.15.2 diff --git a/.github/workflows/test_windows.yml b/.github/workflows/test_windows.yml index b23d9bed07..6f08fd1238 100644 --- a/.github/workflows/test_windows.yml +++ b/.github/workflows/test_windows.yml @@ -66,7 +66,7 @@ jobs: exit $exitCode - if: ${{ matrix.test == 'old' }} - uses: msys2/setup-msys2@v2 + uses: msys2/setup-msys2@4f806de0a5a7294ffabaff804b38a9b435a73bda # v2.30.0 with: update: true install: unzip diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000000..4241b397b0 --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,6 @@ +rules: + unpinned-uses: + config: + policies: + actions/*: ref-pin + github/*: ref-pin From 63844b7904223212f7279316cb1a9ef22ba179d8 Mon Sep 17 00:00:00 2001 From: Daniel Hast Date: Sat, 7 Mar 2026 09:44:52 -0500 Subject: [PATCH 2/5] ci: don't persist git credentials on disk Set `persist-credentials: false` for all uses of `actions/checkout`. This prevents git credentials from being stored on disk, and fixes the following Zizmor audit: https://docs.zizmor.sh/audits/#artipacked --- .github/workflows/backport.yml | 2 ++ .github/workflows/build.yml | 6 ++++++ .github/workflows/codeql.yml | 3 +++ .github/workflows/coverity.yml | 3 +++ .github/workflows/docs.yml | 2 ++ .github/workflows/labeler_pr.yml | 3 +++ .github/workflows/lintcommit.yml | 1 + .github/workflows/lintdocurls.yml | 1 + .github/workflows/news.yml | 1 + .github/workflows/release.yml | 5 +++++ .github/workflows/response.yml | 6 ++++++ .github/workflows/reviewers_add.yml | 3 +++ .github/workflows/reviewers_remove.yml | 3 +++ .github/workflows/test.yml | 21 +++++++++++++++++++++ .github/workflows/test_windows.yml | 3 +++ .github/workflows/vim_patches.yml | 2 ++ 16 files changed, 65 insertions(+) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 20e8c8e94f..c1c4c2e584 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -12,6 +12,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - uses: actions/create-github-app-token@v2 id: app-token diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 52a45f1ae7..b4ad785f43 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,6 +30,9 @@ jobs: CMAKE_VERSION: '3.16.0' steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: ./.github/actions/setup - name: Install minimum required version of cmake @@ -59,6 +62,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: ./.github/actions/setup - name: Build bundled dependencies diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index fcd8ef7736..814e5d504b 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -23,6 +23,9 @@ jobs: steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: ./.github/actions/setup - name: Initialize CodeQL diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 10a934a5d6..a0ba9091e6 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -9,6 +9,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: ./.github/actions/setup - name: Download Coverity diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 46bc0293e9..d652129f46 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -11,6 +11,8 @@ jobs: pull-requests: write steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - uses: ./.github/actions/setup - name: Generate docs diff --git a/.github/workflows/labeler_pr.yml b/.github/workflows/labeler_pr.yml index f476b2fda8..d9fd0abffe 100644 --- a/.github/workflows/labeler_pr.yml +++ b/.github/workflows/labeler_pr.yml @@ -10,6 +10,9 @@ jobs: pull-requests: write steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: actions/labeler@v6 with: configuration-path: .github/scripts/labeler_configuration.yml diff --git a/.github/workflows/lintcommit.yml b/.github/workflows/lintcommit.yml index 560c980dd6..9bf51db6cc 100644 --- a/.github/workflows/lintcommit.yml +++ b/.github/workflows/lintcommit.yml @@ -13,6 +13,7 @@ jobs: with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} + persist-credentials: false - uses: ./.github/actions/setup diff --git a/.github/workflows/lintdocurls.yml b/.github/workflows/lintdocurls.yml index 0fbe4d36f2..b63167e67a 100644 --- a/.github/workflows/lintdocurls.yml +++ b/.github/workflows/lintdocurls.yml @@ -15,6 +15,7 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: 0 + persist-credentials: false - name: Set up git config run: | diff --git a/.github/workflows/news.yml b/.github/workflows/news.yml index 84e6c36b02..dd7465a9be 100644 --- a/.github/workflows/news.yml +++ b/.github/workflows/news.yml @@ -13,6 +13,7 @@ jobs: with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} + persist-credentials: false - name: news.txt needs to be updated run: | for commit in $(git rev-list HEAD~${{ github.event.pull_request.commits }}..HEAD); do diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fca0eb87a7..9e2d88a006 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -59,6 +59,7 @@ jobs: with: # Perform a full checkout #13471 fetch-depth: 0 + persist-credentials: false - run: ./.github/scripts/install_deps.sh - run: sudo apt-get install -y libfuse2 - run: echo "CMAKE_BUILD_TYPE=${{ needs.setup.outputs.build_type }}" >> $GITHUB_ENV @@ -105,6 +106,7 @@ jobs: with: # Perform a full checkout #13471 fetch-depth: 0 + persist-credentials: false - name: Install dependencies run: ./.github/scripts/install_deps.sh @@ -147,6 +149,7 @@ jobs: with: # Perform a full checkout #13471 fetch-depth: 0 + persist-credentials: false - run: .github/scripts/env.ps1 env: BUILD_ARCH: ${{ matrix.arch }} @@ -184,6 +187,8 @@ jobs: # Must perform checkout first, since it deletes the target directory # before running, and would therefore delete the downloaded artifacts - uses: actions/checkout@v6 + with: + persist-credentials: false - uses: actions/download-artifact@v8 diff --git a/.github/workflows/response.yml b/.github/workflows/response.yml index ad17381fd6..a518249ad1 100644 --- a/.github/workflows/response.yml +++ b/.github/workflows/response.yml @@ -14,6 +14,9 @@ jobs: pull-requests: write steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: actions/github-script@v8 with: script: | @@ -28,6 +31,9 @@ jobs: pull-requests: write steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: actions/github-script@v8 with: script: | diff --git a/.github/workflows/reviewers_add.yml b/.github/workflows/reviewers_add.yml index 06292fb759..cd594ebb28 100644 --- a/.github/workflows/reviewers_add.yml +++ b/.github/workflows/reviewers_add.yml @@ -11,6 +11,9 @@ jobs: pull-requests: write steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - name: 'Request reviewers' uses: actions/github-script@v8 with: diff --git a/.github/workflows/reviewers_remove.yml b/.github/workflows/reviewers_remove.yml index b4b523bd4d..11a46ead87 100644 --- a/.github/workflows/reviewers_remove.yml +++ b/.github/workflows/reviewers_remove.yml @@ -9,6 +9,9 @@ jobs: pull-requests: write steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - name: 'Remove reviewers' uses: actions/github-script@v8 with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 68a065acbd..d69f38c9fd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,6 +34,9 @@ jobs: CC: clang steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: ./.github/actions/setup - name: Install stylua @@ -97,6 +100,9 @@ jobs: CC: clang steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: ./.github/actions/setup - name: Build third-party deps run: | @@ -142,6 +148,9 @@ jobs: NVIM_TEST_INTEG: ${{ matrix.build.flavor == 'release' && '1' || '0' }} steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: ./.github/actions/setup with: install_flags: "--test" @@ -236,6 +245,9 @@ jobs: OPTS: -Doptimize=ReleaseSafe steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: version: 0.15.2 @@ -256,6 +268,9 @@ jobs: name: build using zig build (macos 15) steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: version: 0.15.2 @@ -270,6 +285,9 @@ jobs: name: build using zig build (windows) steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: version: 0.15.2 @@ -290,6 +308,9 @@ jobs: CC: gcc steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: ./.github/actions/setup - name: Install dependencies diff --git a/.github/workflows/test_windows.yml b/.github/workflows/test_windows.yml index 6f08fd1238..9099548f1a 100644 --- a/.github/workflows/test_windows.yml +++ b/.github/workflows/test_windows.yml @@ -19,6 +19,9 @@ jobs: test: [functional, old] steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: ./.github/actions/setup - name: Build deps diff --git a/.github/workflows/vim_patches.yml b/.github/workflows/vim_patches.yml index c2e2cac188..c710cb72bd 100644 --- a/.github/workflows/vim_patches.yml +++ b/.github/workflows/vim_patches.yml @@ -18,12 +18,14 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: 0 + persist-credentials: false - uses: actions/checkout@v6 with: repository: vim/vim path: ${{ env.VIM_SOURCE_DIR }} fetch-depth: 0 + persist-credentials: false - run: sudo apt-get install libfuse2 From 755087f8ef0dd42f477757eafeefd9690edf0619 Mon Sep 17 00:00:00 2001 From: Daniel Hast Date: Sat, 7 Mar 2026 10:05:39 -0500 Subject: [PATCH 3/5] ci: set default permissions for workflows The default workflow permissions are overly broad; setting permissions explicitly at the workflow level ensures excessive permissions are not unintentionally granted to jobs. For details, see: https://docs.zizmor.sh/audits/#excessive-permissions --- .github/workflows/backport.yml | 3 +++ .github/workflows/build.yml | 3 +++ .github/workflows/build_dummy.yml | 2 ++ .github/workflows/codeql.yml | 2 ++ .github/workflows/coverity.yml | 3 +++ .github/workflows/docs.yml | 3 +++ .github/workflows/labeler_issue.yml | 3 +++ .github/workflows/labeler_pr.yml | 3 +++ .github/workflows/lintcommit.yml | 4 ++++ .github/workflows/lintcommit_dummy.yml | 3 +++ .github/workflows/lintdocurls.yml | 2 ++ .github/workflows/news.yml | 4 ++++ .github/workflows/optional.yml | 3 +++ .github/workflows/release.yml | 3 +++ .github/workflows/response.yml | 2 ++ .github/workflows/reviewers_add.yml | 3 +++ .github/workflows/reviewers_remove.yml | 3 +++ .github/workflows/test.yml | 3 +++ .github/workflows/test_windows.yml | 3 +++ .github/workflows/vim_patches.yml | 2 ++ 20 files changed, 57 insertions(+) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index c1c4c2e584..215a2e2ef9 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -2,6 +2,9 @@ name: backport on: pull_request_target: types: [closed, labeled] + +permissions: {} + jobs: backport: permissions: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b4ad785f43..978517dba0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,6 +12,9 @@ on: - '.github/**' workflow_dispatch: +permissions: + contents: read + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} diff --git a/.github/workflows/build_dummy.yml b/.github/workflows/build_dummy.yml index 141bdfaeda..c29a3a7800 100644 --- a/.github/workflows/build_dummy.yml +++ b/.github/workflows/build_dummy.yml @@ -14,6 +14,8 @@ on: - 'cmake.*/**' - '.github/**' +permissions: {} + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 814e5d504b..edd0d1ba63 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -12,6 +12,8 @@ on: branches: [ "master" ] workflow_dispatch: +permissions: {} + jobs: analyze: name: Analyze diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index a0ba9091e6..67c6dbc822 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -4,6 +4,9 @@ on: - cron: '10 0 * * *' # Run every day at 00:10 workflow_dispatch: +permissions: + contents: read + jobs: scan: runs-on: ubuntu-latest diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d652129f46..40787a1b8f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -2,6 +2,9 @@ name: docs on: pull_request: types: [opened, synchronize, reopened, ready_for_review] + +permissions: {} + jobs: docs: runs-on: ubuntu-latest diff --git a/.github/workflows/labeler_issue.yml b/.github/workflows/labeler_issue.yml index 1c4d3b9402..75c7c1f2e9 100644 --- a/.github/workflows/labeler_issue.yml +++ b/.github/workflows/labeler_issue.yml @@ -2,6 +2,9 @@ name: "labeler: issue" on: issues: types: [opened] + +permissions: {} + jobs: labeler: permissions: diff --git a/.github/workflows/labeler_pr.yml b/.github/workflows/labeler_pr.yml index d9fd0abffe..ed9321a897 100644 --- a/.github/workflows/labeler_pr.yml +++ b/.github/workflows/labeler_pr.yml @@ -2,6 +2,9 @@ name: "labeler: PR" on: pull_request_target: types: [opened] + +permissions: {} + jobs: changed-files: runs-on: ubuntu-latest diff --git a/.github/workflows/lintcommit.yml b/.github/workflows/lintcommit.yml index 9bf51db6cc..1bcb2becb9 100644 --- a/.github/workflows/lintcommit.yml +++ b/.github/workflows/lintcommit.yml @@ -4,6 +4,10 @@ on: types: [opened, synchronize, reopened, ready_for_review] branches: - 'master' + +permissions: + contents: read + jobs: lint-commits: runs-on: ubuntu-latest diff --git a/.github/workflows/lintcommit_dummy.yml b/.github/workflows/lintcommit_dummy.yml index e4a0c4af2d..fde80474b7 100644 --- a/.github/workflows/lintcommit_dummy.yml +++ b/.github/workflows/lintcommit_dummy.yml @@ -8,6 +8,9 @@ on: types: [opened, synchronize, reopened, ready_for_review] branches: - 'release-[0-9]+.[0-9]+' + +permissions: {} + jobs: lint-commits: runs-on: ubuntu-latest diff --git a/.github/workflows/lintdocurls.yml b/.github/workflows/lintdocurls.yml index b63167e67a..424429933e 100644 --- a/.github/workflows/lintdocurls.yml +++ b/.github/workflows/lintdocurls.yml @@ -4,6 +4,8 @@ on: - cron: '22 22 * * 5' workflow_dispatch: +permissions: {} + jobs: check-unreachable-urls: runs-on: ubuntu-latest diff --git a/.github/workflows/news.yml b/.github/workflows/news.yml index dd7465a9be..56be287eac 100644 --- a/.github/workflows/news.yml +++ b/.github/workflows/news.yml @@ -4,6 +4,10 @@ on: types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] branches: - 'master' + +permissions: + contents: read + jobs: check: runs-on: ubuntu-latest diff --git a/.github/workflows/optional.yml b/.github/workflows/optional.yml index 540daccc56..acaf3644c7 100644 --- a/.github/workflows/optional.yml +++ b/.github/workflows/optional.yml @@ -4,6 +4,9 @@ on: types: [labeled, opened, synchronize, reopened] workflow_dispatch: +permissions: + contents: read + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9e2d88a006..76440c1ebc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,6 +12,9 @@ on: tags: - v[0-9]+.[0-9]+.[0-9]+ +permissions: + contents: read + # Build on the oldest supported images, so we have broader compatibility jobs: setup: diff --git a/.github/workflows/response.yml b/.github/workflows/response.yml index a518249ad1..b104334bb4 100644 --- a/.github/workflows/response.yml +++ b/.github/workflows/response.yml @@ -5,6 +5,8 @@ on: workflow_dispatch: issue_comment: +permissions: {} + jobs: close: if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' diff --git a/.github/workflows/reviewers_add.yml b/.github/workflows/reviewers_add.yml index cd594ebb28..5f07f4994e 100644 --- a/.github/workflows/reviewers_add.yml +++ b/.github/workflows/reviewers_add.yml @@ -3,6 +3,9 @@ on: pull_request_target: types: [labeled, ready_for_review, reopened] workflow_call: + +permissions: {} + jobs: request-reviewer: if: github.event.pull_request.state == 'open' && github.event.pull_request.draft == false && !endsWith(github.actor, '[bot]') diff --git a/.github/workflows/reviewers_remove.yml b/.github/workflows/reviewers_remove.yml index 11a46ead87..98a207264e 100644 --- a/.github/workflows/reviewers_remove.yml +++ b/.github/workflows/reviewers_remove.yml @@ -2,6 +2,9 @@ name: "reviewers: remove" on: pull_request_target: types: [converted_to_draft, closed] + +permissions: {} + jobs: remove-reviewers: runs-on: ubuntu-latest diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d69f38c9fd..578669c338 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,6 +10,9 @@ on: - 'release-[0-9]+.[0-9]+' workflow_dispatch: +permissions: + contents: read + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} diff --git a/.github/workflows/test_windows.yml b/.github/workflows/test_windows.yml index 9099548f1a..5bc9de73b1 100644 --- a/.github/workflows/test_windows.yml +++ b/.github/workflows/test_windows.yml @@ -9,6 +9,9 @@ on: type: number workflow_dispatch: +permissions: + contents: read + jobs: windows: runs-on: windows-2025 diff --git a/.github/workflows/vim_patches.yml b/.github/workflows/vim_patches.yml index c710cb72bd..73c2c97fac 100644 --- a/.github/workflows/vim_patches.yml +++ b/.github/workflows/vim_patches.yml @@ -4,6 +4,8 @@ on: - cron: '3 3 * * *' workflow_dispatch: +permissions: {} + jobs: update-vim-patches: runs-on: ubuntu-latest From 3572bf7e16441e38d943b02764eb163db722a7a7 Mon Sep 17 00:00:00 2001 From: Daniel Hast Date: Sat, 7 Mar 2026 12:03:52 -0500 Subject: [PATCH 4/5] ci: eliminate template expansion in code contexts Replace all template expansions in code contexts with environment variable substitutions. Template expansion in code contexts can be a source of code injection vulnerabilities; for more info, see: https://docs.zizmor.sh/audits/#template-injection --- .github/actions/cache/action.yml | 12 ++++++---- .github/actions/setup/action.yml | 4 +++- .github/workflows/backport.yml | 4 +++- .github/workflows/news.yml | 6 +++-- .github/workflows/release.yml | 36 ++++++++++++++++++++++-------- .github/workflows/test.yml | 12 +++++++--- .github/workflows/test_windows.yml | 4 +++- 7 files changed, 57 insertions(+), 21 deletions(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index 8a5c53a139..591bb67e66 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -3,18 +3,22 @@ description: "This action caches neovim dependencies" runs: using: "composite" steps: - - run: echo "CACHE_KEY=${{ github.workflow }}" >> $GITHUB_ENV + - run: echo "CACHE_KEY=${GITHUB_WORKFLOW}" >> $GITHUB_ENV shell: bash - - run: echo "CACHE_KEY=${{ github.job }}" >> $GITHUB_ENV + - run: echo "CACHE_KEY=${GITHUB_JOB}" >> $GITHUB_ENV shell: bash - if: ${{ matrix }} - run: echo "CACHE_KEY=$CACHE_KEY-${{ join(matrix.*, '-') }}" >> $GITHUB_ENV + env: + MATRIX_JOIN: ${{ join(matrix.*, '-') }} + run: echo "CACHE_KEY=${CACHE_KEY}-${MATRIX_JOIN}" >> $GITHUB_ENV shell: bash - if: ${{ matrix.build }} - run: echo "CACHE_KEY=$CACHE_KEY-${{ join(matrix.build.*, '-') }}" >> $GITHUB_ENV + env: + MATRIX_JOIN: ${{ join(matrix.build.*, '-') }} + run: echo "CACHE_KEY=${CACHE_KEY}-${MATRIX_JOIN}" >> $GITHUB_ENV shell: bash - id: image diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index dfa3101abc..b3b1d15845 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -22,7 +22,9 @@ runs: shell: pwsh - name: Install dependencies - run: ./.github/scripts/install_deps.sh ${{ inputs.install_flags }} + env: + INSTALL_FLAGS: ${{ inputs.install_flags }} + run: ./.github/scripts/install_deps.sh ${INSTALL_FLAGS} shell: bash - name: Cache diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 215a2e2ef9..31708b84fe 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -48,4 +48,6 @@ jobs: if: ${{ steps.backport.outputs.was_successful == 'true' }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh pr merge --rebase --auto ${{ steps.backport.outputs.created_pull_numbers }} + CREATED_PULL_NUMBERS: ${{ steps.backport.outputs.created_pull_numbers }} + run: | + gh pr merge --rebase --auto "${CREATED_PULL_NUMBERS}" diff --git a/.github/workflows/news.yml b/.github/workflows/news.yml index 56be287eac..f14be08651 100644 --- a/.github/workflows/news.yml +++ b/.github/workflows/news.yml @@ -19,13 +19,15 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} persist-credentials: false - name: news.txt needs to be updated + env: + PULL_REQUEST_COMMITS: ${{ github.event.pull_request.commits }} run: | - for commit in $(git rev-list HEAD~${{ github.event.pull_request.commits }}..HEAD); do + for commit in $(git rev-list "HEAD~${PULL_REQUEST_COMMITS}..HEAD"); do message=$(git log -n1 --pretty=format:%s $commit) type="$(echo "$message" | sed -E 's|([[:alpha:]]+)(\(.*\))?!?:.*|\1|')" breaking="$(echo "$message" | sed -E 's|[[:alpha:]]+(\(.*\))?!:.*|breaking-change|')" if [[ "$type" == "feat" ]] || [[ "$type" == "perf" ]] || [[ "$breaking" == "breaking-change" ]]; then - ! git diff HEAD~${{ github.event.pull_request.commits }}..HEAD --quiet runtime/doc/news.txt runtime/doc/deprecated.txt || + ! git diff "HEAD~${PULL_REQUEST_COMMITS}..HEAD" --quiet runtime/doc/news.txt runtime/doc/deprecated.txt || { echo " Pull request includes a new feature, performance improvement diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 76440c1ebc..4e8af28707 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,10 +65,17 @@ jobs: persist-credentials: false - run: ./.github/scripts/install_deps.sh - run: sudo apt-get install -y libfuse2 - - run: echo "CMAKE_BUILD_TYPE=${{ needs.setup.outputs.build_type }}" >> $GITHUB_ENV + + - run: echo "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" >> $GITHUB_ENV + env: + CMAKE_BUILD_TYPE: ${{ needs.setup.outputs.build_type }} + - name: appimage + env: + APPIMAGE_TAG: ${{ needs.setup.outputs.appimage_tag }} run: | - ./scripts/genappimage.sh ${{ needs.setup.outputs.appimage_tag }} + ./scripts/genappimage.sh "${APPIMAGE_TAG}" + - name: tar.gz run: cpack --config build/CPackConfig.cmake -G TGZ - uses: actions/upload-artifact@v7 @@ -103,6 +110,7 @@ jobs: arch: arm64 runs-on: ${{ matrix.runner }} env: + CMAKE_BUILD_TYPE: ${{ needs.setup.outputs.build_type }} MACOSX_DEPLOYMENT_TARGET: 11.0 steps: - uses: actions/checkout@v6 @@ -116,13 +124,13 @@ jobs: - name: Build deps run: | cmake -S cmake.deps -B .deps -G Ninja \ - -D CMAKE_BUILD_TYPE=${{ needs.setup.outputs.build_type }} \ + -D CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" \ -D CMAKE_FIND_FRAMEWORK=NEVER cmake --build .deps - name: Build neovim run: | cmake -B build -G Ninja \ - -D CMAKE_BUILD_TYPE=${{ needs.setup.outputs.build_type }} \ + -D CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" \ -D ENABLE_LIBINTL=OFF \ -D CMAKE_FIND_FRAMEWORK=NEVER cmake --build build @@ -147,6 +155,8 @@ jobs: arch: arm64 archive_name: nvim-win-arm64 runs-on: ${{ matrix.runner }} + env: + CMAKE_BUILD_TYPE: ${{ needs.setup.outputs.build_type }} steps: - uses: actions/checkout@v6 with: @@ -162,12 +172,14 @@ jobs: Expand-Archive -Path "wix314-binaries.zip" -DestinationPath "C:/wix" echo "C:\wix" >> $env:GITHUB_PATH - name: Build deps + shell: pwsh run: | - cmake -S cmake.deps -B .deps -G Ninja -DCMAKE_BUILD_TYPE=${{ needs.setup.outputs.build_type }} + cmake -S cmake.deps -B .deps -G Ninja -DCMAKE_BUILD_TYPE="${env:CMAKE_BUILD_TYPE}" cmake --build .deps - name: Build package + shell: pwsh run: | - cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ needs.setup.outputs.build_type }} + cmake -B build -G Ninja -DCMAKE_BUILD_TYPE="${env:CMAKE_BUILD_TYPE}" cmake --build build --target package - name: Upload artifact uses: actions/upload-artifact@v7 @@ -199,25 +211,31 @@ jobs: run: sudo apt-get update && sudo apt-get install -y gettext-base - if: github.event_name == 'workflow_dispatch' - run: echo "TAG_NAME=${{ github.event.inputs.tag_name }}" >> $GITHUB_ENV + env: + TAG_NAME: ${{ github.event.inputs.tag_name }} + run: echo "TAG_NAME=${TAG_NAME}" >> $GITHUB_ENV + - if: github.event_name == 'schedule' run: echo 'TAG_NAME=nightly' >> $GITHUB_ENV + - if: github.event_name == 'push' run: | - TAG_NAME=${{ github.ref }} - echo "TAG_NAME=${TAG_NAME#refs/tags/}" >> $GITHUB_ENV + echo "TAG_NAME=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV + - if: env.TAG_NAME == 'nightly' run: | (echo 'SUBJECT=Nvim development (prerelease) build'; echo 'PRERELEASE=--prerelease') >> $GITHUB_ENV gh release delete nightly --yes || true git push origin :nightly || true + - if: env.TAG_NAME != 'nightly' run: | (echo 'SUBJECT=Nvim release build'; echo 'PRERELEASE=') >> $GITHUB_ENV gh release delete stable --yes || true git push origin :stable || true + - name: Publish release env: NVIM_VERSION: ${{ needs.linux.outputs.version }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 578669c338..9402bfa252 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -62,7 +62,9 @@ jobs: - if: "!cancelled()" name: Determine if run should be aborted id: abort_job - run: echo "status=${{ job.status }}" >> $GITHUB_OUTPUT + env: + JOB_STATUS: ${{ job.status }} + run: echo "status=${JOB_STATUS}" >> $GITHUB_OUTPUT - if: success() || failure() && steps.abort_job.outputs.status == 'success' name: stylua @@ -175,13 +177,17 @@ jobs: run: cmake -E rm -rf -- .git - name: Build third-party deps + env: + BUILD_DEPS_FLAGS: ${{ matrix.build.deps_flags }} run: | - cmake -S cmake.deps --preset ci -D CMAKE_BUILD_TYPE=Debug ${{ matrix.build.deps_flags }} + cmake -S cmake.deps --preset ci -D CMAKE_BUILD_TYPE=Debug $BUILD_DEPS_FLAGS cmake --build .deps - name: Build + env: + BUILD_FLAGS: ${{ matrix.build.flags }} run: | - cmake --preset ci -D CMAKE_BUILD_TYPE=Debug -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX ${{ matrix.build.flags }} + cmake --preset ci -D CMAKE_BUILD_TYPE=Debug -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX $BUILD_FLAGS cmake --build build - if: ${{ matrix.test == 'unittest' }} diff --git a/.github/workflows/test_windows.yml b/.github/workflows/test_windows.yml index 5bc9de73b1..aac8480e78 100644 --- a/.github/workflows/test_windows.yml +++ b/.github/workflows/test_windows.yml @@ -33,8 +33,10 @@ jobs: cmake --build .deps - name: Build + env: + BUILD_FLAGS: ${{ inputs.build_flags }} run: | - cmake --preset ci -D CMAKE_BUILD_TYPE='RelWithDebInfo' ${{ inputs.build_flags }} + cmake --preset ci -D CMAKE_BUILD_TYPE='RelWithDebInfo' $env:BUILD_FLAGS cmake --build build - name: Install test deps From ed767a6a69c7cf218b6473f4acbc31c569f3fed2 Mon Sep 17 00:00:00 2001 From: Daniel Hast Date: Sat, 7 Mar 2026 16:06:54 -0500 Subject: [PATCH 5/5] ci: ignore known Zizmor findings This avoids false positives from existing uses of `GITHUB_ENV` and `pull_request_target` that are safe, as well as from cache usage in a workflow that doesn't produce release artifacts. --- .github/actions/cache/action.yml | 8 ++++---- .github/actions/setup/action.yml | 2 +- .github/zizmor.yml | 9 +++++++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index 591bb67e66..f48269e0d9 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -3,22 +3,22 @@ description: "This action caches neovim dependencies" runs: using: "composite" steps: - - run: echo "CACHE_KEY=${GITHUB_WORKFLOW}" >> $GITHUB_ENV + - run: echo "CACHE_KEY=${GITHUB_WORKFLOW}" >> $GITHUB_ENV # zizmor: ignore[github-env] shell: bash - - run: echo "CACHE_KEY=${GITHUB_JOB}" >> $GITHUB_ENV + - run: echo "CACHE_KEY=${GITHUB_JOB}" >> $GITHUB_ENV # zizmor: ignore[github-env] shell: bash - if: ${{ matrix }} env: MATRIX_JOIN: ${{ join(matrix.*, '-') }} - run: echo "CACHE_KEY=${CACHE_KEY}-${MATRIX_JOIN}" >> $GITHUB_ENV + run: echo "CACHE_KEY=${CACHE_KEY}-${MATRIX_JOIN}" >> $GITHUB_ENV # zizmor: ignore[github-env] shell: bash - if: ${{ matrix.build }} env: MATRIX_JOIN: ${{ join(matrix.build.*, '-') }} - run: echo "CACHE_KEY=${CACHE_KEY}-${MATRIX_JOIN}" >> $GITHUB_ENV + run: echo "CACHE_KEY=${CACHE_KEY}-${MATRIX_JOIN}" >> $GITHUB_ENV # zizmor: ignore[github-env] shell: bash - id: image diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index b3b1d15845..a3ad2e98c5 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -10,7 +10,7 @@ runs: steps: - name: Set $BIN_DIR shell: bash - run: echo "$BIN_DIR" >> $GITHUB_PATH + run: echo "$BIN_DIR" >> $GITHUB_PATH # zizmor: ignore[github-env] - if: ${{ runner.os != 'Windows' }} name: Set ulimit diff --git a/.github/zizmor.yml b/.github/zizmor.yml index 4241b397b0..2976bbe3fa 100644 --- a/.github/zizmor.yml +++ b/.github/zizmor.yml @@ -1,4 +1,13 @@ rules: + cache-poisoning: + ignore: + - test.yml + dangerous-triggers: + ignore: + - backport.yml + - labeler_pr.yml + - reviewers_add.yml + - reviewers_remove.yml unpinned-uses: config: policies: