From 37dd1823bcea21679bc8a3a610911d6527cee912 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Tue, 27 Oct 2026 11:00:26 +0100 Subject: [PATCH 1/8] Add zizmor pre-commit hook --- .pre-commit-config.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5066109..f5628b6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,6 +13,12 @@ repos: - id: double-quote-string-fixer exclude: \.html$ + - repo: https://github.com/zizmorcore/zizmor-pre-commit + rev: v1.31.1 + hooks: + - id: zizmor + args: ['--offline'] + - repo: https://github.com/pre-commit/mirrors-prettier rev: 'v4.0.0-alpha.8' hooks: From 5f7979e52034c9eecc8b567e3e3d6a6c694d1d6f Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Tue, 27 Oct 2026 11:00:45 +0100 Subject: [PATCH 2/8] Add zizmor GHA security analysis workflow --- .github/workflows/zizmor.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/zizmor.yml diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 0000000..6b61bc5 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,24 @@ +name: GHA Security Analysis + +on: + push: + branches: [main] + pull_request: + +permissions: {} + +jobs: + zizmor: + name: GHA Security Analysis using Zizmor + runs-on: ubuntu-latest + permissions: + contents: read # Required to check out the repository. + security-events: write # Required for upload-sarif (used by zizmor-action) to upload SARIF files. + steps: + - name: Checkout repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Run zizmor + uses: zizmorcore/zizmor-action@53290badfa369cb0bf7ad16342cb62c2fa47ac7b # v0.8.0 From fe6e3ee296efa3db0fd947b413b7318163b96641 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Tue, 27 Oct 2026 11:00:51 +0100 Subject: [PATCH 3/8] Pin GitHub Actions to commit SHAs --- .github/workflows/deploy.yml | 10 +++++----- .github/workflows/linkcheck.yml | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 339e6ce..77d1e23 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -23,17 +23,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: lfs: true - name: Setup Node.js - uses: actions/setup-node@v7 + uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 with: node-version: '20' cache: 'npm' - name: Restore cache - uses: actions/cache@v6 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: | .next/cache @@ -49,7 +49,7 @@ jobs: run: npm run build - name: Upload artifact - uses: actions/upload-pages-artifact@v5 + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: ./out @@ -63,4 +63,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v5 + uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 diff --git a/.github/workflows/linkcheck.yml b/.github/workflows/linkcheck.yml index e70cfa4..78382ee 100644 --- a/.github/workflows/linkcheck.yml +++ b/.github/workflows/linkcheck.yml @@ -18,11 +18,11 @@ jobs: LYCHEE_REPORT_FILE: ./lychee/out.md runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Link Checker id: lychee - uses: lycheeverse/lychee-action@v2.9.0 + uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2.9.0 with: # v2 fails the job on broken links by default; keep the old behaviour # so the tracking issue below gets updated instead. @@ -57,7 +57,7 @@ jobs: -f body='No invalid links found! 🤖' - name: Upload artifact - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: lychee-report path: ${{ env.LYCHEE_REPORT_FILE }} From df6cb276aba3eda9c0c3775700e7dda6b68776b8 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Tue, 27 Oct 2026 11:00:59 +0100 Subject: [PATCH 4/8] Don't persist git credentials on checkout --- .github/workflows/deploy.yml | 1 + .github/workflows/linkcheck.yml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 77d1e23..9bc4a42 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -26,6 +26,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: lfs: true + persist-credentials: false - name: Setup Node.js uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 diff --git a/.github/workflows/linkcheck.yml b/.github/workflows/linkcheck.yml index 78382ee..5e543f2 100644 --- a/.github/workflows/linkcheck.yml +++ b/.github/workflows/linkcheck.yml @@ -19,6 +19,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Link Checker id: lychee From 8eb9a5ee62058e574a61d8e7286cd6e10abfa27c Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Tue, 27 Oct 2026 11:01:07 +0100 Subject: [PATCH 5/8] Use least-privilege job-level permissions in workflows --- .github/workflows/deploy.yml | 11 ++++++----- .github/workflows/linkcheck.yml | 6 ++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9bc4a42..b757183 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -7,11 +7,7 @@ on: branches: [main] workflow_dispatch: -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write +permissions: {} # Allow only one concurrent deployment concurrency: @@ -21,6 +17,8 @@ concurrency: jobs: build: runs-on: ubuntu-latest + permissions: + contents: read # Required to check out the repository. steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -60,6 +58,9 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest needs: build + permissions: + pages: write # Required by actions/deploy-pages to deploy to GitHub Pages. + id-token: write # Required by actions/deploy-pages to verify the deployment originates from an appropriate source (OIDC). if: github.ref == 'refs/heads/main' steps: - name: Deploy to GitHub Pages diff --git a/.github/workflows/linkcheck.yml b/.github/workflows/linkcheck.yml index 5e543f2..11a2dcf 100644 --- a/.github/workflows/linkcheck.yml +++ b/.github/workflows/linkcheck.yml @@ -8,8 +8,7 @@ on: env: LINK_TRACKING_ISSUE_NUMBER: 85 -permissions: - issues: write +permissions: {} jobs: check-urls: @@ -17,6 +16,9 @@ jobs: env: LYCHEE_REPORT_FILE: ./lychee/out.md runs-on: ubuntu-latest + permissions: + contents: read # Required to check out the repository. + issues: write # Required to update the link tracking issue. steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: From d2c0811e430ed590a7a33bbf0e5cd99e4bc2b678 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Tue, 27 Oct 2026 11:01:15 +0100 Subject: [PATCH 6/8] Avoid template injection in linkcheck workflow by using env vars --- .github/workflows/linkcheck.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/linkcheck.yml b/.github/workflows/linkcheck.yml index 11a2dcf..562e092 100644 --- a/.github/workflows/linkcheck.yml +++ b/.github/workflows/linkcheck.yml @@ -37,17 +37,19 @@ jobs: id: readReport run: | EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) - echo "FILE_CONTENT<<$EOF" >> $GITHUB_OUTPUT - echo "$(cat ${{ env.LYCHEE_REPORT_FILE }})" >> $GITHUB_OUTPUT - echo "$EOF" >> $GITHUB_OUTPUT - - run: echo "${{ steps.readReport.outputs.FILE_CONTENT }}" + echo "FILE_CONTENT<<$EOF" >> "$GITHUB_OUTPUT" + echo "$(cat "${LYCHEE_REPORT_FILE}")" >> "$GITHUB_OUTPUT" + echo "$EOF" >> "$GITHUB_OUTPUT" + - env: + FILE_CONTENT: ${{ steps.readReport.outputs.FILE_CONTENT }} + run: echo "${FILE_CONTENT}" - name: Update link tracking issue (update invalid links) if: steps.lychee.outputs.exit_code != 0 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} ISSUE_BODY: ${{ steps.readReport.outputs.FILE_CONTENT }} run: | - gh api --method PATCH "repos/${{ github.repository }}/issues/${LINK_TRACKING_ISSUE_NUMBER}" \ + gh api --method PATCH "repos/${GITHUB_REPOSITORY}/issues/${LINK_TRACKING_ISSUE_NUMBER}" \ -f state=open \ -f body="${ISSUE_BODY}" @@ -56,7 +58,7 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - gh api --method PATCH "repos/${{ github.repository }}/issues/${LINK_TRACKING_ISSUE_NUMBER}" \ + gh api --method PATCH "repos/${GITHUB_REPOSITORY}/issues/${LINK_TRACKING_ISSUE_NUMBER}" \ -f state=closed \ -f body='No invalid links found! 🤖' From 0559c27d98fe710c5b271c805f5db04190368e19 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Tue, 27 Oct 2026 11:01:21 +0100 Subject: [PATCH 7/8] Add a 7-day cooldown to Dependabot updates --- .github/dependabot.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index bceabfb..4add620 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -7,12 +7,16 @@ updates: directory: '/' schedule: interval: 'monthly' + cooldown: + default-days: 7 # Maintain dependencies for npm - package-ecosystem: 'npm' directory: '/' schedule: interval: 'monthly' + cooldown: + default-days: 7 groups: dependencies: From a21b8bee2d9b1539237cc5c7d52d9e9117d6c8af Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Tue, 27 Oct 2026 11:01:48 +0100 Subject: [PATCH 8/8] Switch to maintained prettier pre-commit mirror pre-commit/mirrors-prettier is archived (flagged by zizmor archived-uses). Use rbubley/mirrors-prettier as parcels does; it has no v4 tags, so pin the latest v3 release. --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f5628b6..d29b58d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,8 +19,8 @@ repos: - id: zizmor args: ['--offline'] - - repo: https://github.com/pre-commit/mirrors-prettier - rev: 'v4.0.0-alpha.8' + - repo: https://github.com/rbubley/mirrors-prettier # Update mirror as official mirror is deprecated + rev: v3.9.10 hooks: - id: prettier exclude: \.html$ @@ -35,8 +35,8 @@ repos: |vue\ |yaml|yml\ )$" - - repo: https://github.com/pre-commit/mirrors-prettier - rev: 'v4.0.0-alpha.8' + - repo: https://github.com/rbubley/mirrors-prettier # Update mirror as official mirror is deprecated + rev: v3.9.10 hooks: - id: prettier