Skip to content

ci: adopt zizmor and harden GitHub Actions workflows - #76

Merged
hasansezertasan merged 3 commits into
mainfrom
feat/immense-wedelia
Jul 26, 2026
Merged

ci: adopt zizmor and harden GitHub Actions workflows#76
hasansezertasan merged 3 commits into
mainfrom
feat/immense-wedelia

Conversation

@hasansezertasan

Copy link
Copy Markdown
Owner

Description

Adopts zizmor static analysis for the GitHub Actions workflows, applied to both the template output (generated projects) and this repo's own CI, adapted to our stack (prek + Renovate, not pre-commit + Dependabot).

Modeled on litestar-org/project-template#39, but tuned to how this template already works.

Two-layer setup

Layer How Behavior
Blocking gate zizmor prek hook (zizmorcore/zizmor-pre-commit) in prek.toml.jinja + this repo's prek.toml Hard-fails on any finding; runs in the generated project's CI hooks job and locally
Dashboard static zizmor.yml (zizmorcore/zizmor-action, SHA-pinned) Uploads SARIF to the Security tab; non-blocking, least-privilege, self-auditing

This repo's prek.toml scopes the hook to \.github/workflows/.*\.ya?ml$ so it audits the template's static .yml workflows but skips the un-parseable *.jinja templates.

Findings resolved to zero (across every scenario)

  • artipackedpersist-credentials: false on read-only checkouts; justified # zizmor: ignore[artipacked] on the two ghp-import -p push jobs (gh-pages, release-please deploy-docs) whose push needs the persisted credential.
  • excessive-permissions — top-level permissions: {} + per-job least-privilege grants in ci.yml and manual.yml.
  • template-injection (incl. 2 High) — github.ref_name/repository/workflow moved into env: in the release-please finalize-release/attach-github-release run blocks.
  • dangerous-triggers — justified # zizmor: ignore on the six intentional pull_request_target workflows (check-pr-title, check-branch-name, check-linked-issues, task-completed-check, label, issue-manager); they never check out or execute PR code and read untrusted input only via env:.

template-ci.yml

Added a step that audits each rendered matrix scenario with the generated project's own zizmor prek hook — the exact gate a generated repo runs — covering the conditional .jinja workflow branches this repo can't scan directly.

Adaptations vs. the reference

  • Kept regular persona (not strict): Renovate's helpers:pinGitHubActionDigests already SHA-pins every uses:.
  • Dropped the Dependabot-cooldown item — Renovate is our dependency manager.

Verification

  • zizmor clean across kitchen-sink, minimal, and litestar/nats renders + this repo.
  • The authoritative prek gate (prek run zizmor --all-files, the version generated projects actually run) passes inside rendered kitchen-sink (all workflows) and minimal renders, and in this repo.
  • actionlint, yamllint, yamlfmt, GitHub-Actions schema, and TOML validity all pass.
  • The new template-ci.yml step verified end-to-end against a real render.

Notes

  • The prek hook (zizmor via zizmor-pre-commit@v1.9.0) and a bare uvx zizmor (1.28.0) disagree on label.yml's trigger under regular persona; since the hook gates generated projects, label.yml got the ignore and CLAUDE.md notes to verify with the prek hook, not bare uvx zizmor.

Adopt zizmor static analysis for the GitHub Actions workflows, both in the
template output (generated projects) and this repo's own CI, adapted to our
stack (prek + Renovate, not pre-commit + Dependabot).

Two-layer setup mirroring the reference approach:
- Blocking gate: `zizmor` prek hook (zizmorcore/zizmor-pre-commit) in
  prek.toml.jinja and this repo's prek.toml (scoped to real .yml, skipping
  un-parseable *.jinja). Runs in the generated project's CI `hooks` job.
- Dashboard: static zizmor.yml (zizmorcore/zizmor-action, SHA-pinned) uploading
  SARIF to the Security tab; non-blocking, least-privilege, self-auditing.

Drive every finding to zero across all scenarios:
- artipacked: persist-credentials: false on read-only checkouts; justified
  ignores on the two ghp-import push jobs (gh-pages, release-please deploy-docs).
- excessive-permissions: top-level permissions: {} + per-job grants in ci.yml
  and manual.yml.
- template-injection: github.ref_name/repository/workflow moved into env: in
  release-please finalize/attach run blocks.
- dangerous-triggers: justified ignores on the six intentional
  pull_request_target workflows (never check out or run PR code).

template-ci.yml additionally audits each rendered matrix scenario with the
generated project's own zizmor prek hook, covering the .jinja workflow branches
this repo can't scan directly. Kept regular persona (Renovate already SHA-pins
actions). Docs updated in CLAUDE.md, README.md, and template/README.md.jinja.
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@hasansezertasan, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 10 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6a7dec23-1389-4c98-abba-2359303ba080

📥 Commits

Reviewing files that changed from the base of the PR and between c1c39b1 and 129066d.

📒 Files selected for processing (16)
  • .github/workflows/template-ci.yml
  • .github/workflows/zizmor.yml
  • CLAUDE.md
  • README.md
  • prek.toml
  • template/.github/workflows/check-branch-name.yml
  • template/.github/workflows/check-linked-issues.yml
  • template/.github/workflows/check-pr-title.yml
  • template/.github/workflows/issue-manager.yml.jinja
  • template/.github/workflows/label.yml
  • template/.github/workflows/manual.yml
  • template/.github/workflows/release-please.yml.jinja
  • template/.github/workflows/task-completed-check.yml
  • template/.github/workflows/zizmor.yml
  • template/README.md.jinja
  • template/prek.toml.jinja
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/immense-wedelia

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

# Conflicts:
#	README.md
#	template/.github/workflows/ci.yml.jinja
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

- template-ci.yml: guard the rendered-workflow zizmor audit against a silent
  no-op — prek exits 0 when a hook matches zero files, so assert at least one
  workflow was staged before running the gate.
- release-please.yml.jinja: correct the env-indirection comment — this workflow
  triggers only on push/workflow_dispatch, so github.ref_name is not
  fork-controlled here; reframe as uniform template-injection hygiene rather
  than a fork threat.
- CLAUDE.md: zizmor has no `strict` persona; the stricter tier is `pedantic`.
@hasansezertasan
hasansezertasan merged commit c4ee482 into main Jul 26, 2026
12 checks passed
@hasansezertasan
hasansezertasan deleted the feat/immense-wedelia branch July 26, 2026 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants