Skip to content

ci: zizmor security checks, richer job summaries#79

Merged
ndonkoHenri merged 12 commits into
mainfrom
zizmor
Jun 19, 2026
Merged

ci: zizmor security checks, richer job summaries#79
ndonkoHenri merged 12 commits into
mainfrom
zizmor

Conversation

@ndonkoHenri

@ndonkoHenri ndonkoHenri commented Jun 17, 2026

Copy link
Copy Markdown

Housekeeping pass over the build/publish CI: clearer run summaries, a security audit + hardening of the workflows. No change to what wheels we build or where they publish.

Workflow security hardening (now zizmor-clean)

Ran zizmor over the workflows and fixed every finding:

  • Pinned every action to a commit SHA (@<sha> # <tag>), so Dependabot still tracks/bumps them. dtolnay/rust-toolchain gained an explicit toolchain: stable since the SHA drops the channel.
  • Least-privilege permissions: — top-level contents: read on both workflows (deny-by-default elsewhere).
  • persist-credentials: false on all checkouts (we publish via curl, not git).
  • Template-injection fixinputs.* used in the matrix step are now passed via env: instead of interpolated straight into run:.

New: Security audit workflow

.github/workflows/zizmor.yml runs zizmor (official zizmor-action) on every push and PR, uploading findings to code scanning — so workflow-security regressions surface as a check + Security-tab alerts before they land.

Job summaries

Workflow runs now write readable Markdown to the GitHub job summary instead of burying everything in logs:

  • Built wheels — per job, a table of every *.whl produced (name + size), inspired by cibuildwheel's summary.
  • Publish status — for the publish step, a per-wheel table marking each as ✅ published / ⏭️ already exists / ❌ failed (HTTP code), with a tally. The publish step now also returns non-zero on a real upload error instead of silently swallowing it (duplicates are still fine).
  • On-device test — friendlier, platform-specific headings (🧪 Test on Android Emulator / 🧪 Test on iOS Simulator), all leveled to ### so the summary reads as build → test → publish.

🔢 Default build number → 1

read_meta.py + the meta schema now default a recipe's build.number to 1.

Phase 1 — a Summarize built wheels step lists each matrix job's produced
wheels (name + size) in the GitHub job summary (cibuildwheel-style).

Phase 2 — publish_to_pypi now captures Gemfury's per-wheel HTTP status and
writes a publish table (published / already-exists / failed), and returns
non-zero on a real upload failure (previously a failed upload was silently
swallowed). Duplicates (409 / already exists) are expected on re-publish and
do not fail the step.
…n run on workflow_dispatch

Publishing was gated to push-to-main only. Add a boolean publish input
(default false) threaded build-wheels.yml -> build-wheels-version.yml; the
publish step now runs when (push to main) OR publish=true. Lets a manual
dispatch exercise + demo the publish summary without changing default behavior.
…e test title

The mobile-test summary used a ## heading titled "recipe-tester — <platform>",
while the built-wheels (📦) and publish (⬆️) sections use ###. Level it to ###
and rename to "🧪 On-device test — <platform>" so the run summary reads as a
consistent build → test → publish progression.
The publish input was demo scaffolding so a fork dispatch could exercise the
publish-status summary. Revert it: publishing is back to push-to-main-only.
Keeps the built-wheels (📦) and publish-status (⬆️) summaries and the
on-device test heading (🧪).
Standardize on-device test section titles by dynamically including the specific platform (e.g., Android Emulator, iOS Simulator) for clarity in the job summary.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Housekeeping update to the repository’s CI and metadata defaults: hardens GitHub Actions workflows (zizmor-clean, pinned actions, least-privilege permissions), improves GitHub job summaries for builds/tests/publishing, tunes Dependabot noise/risk controls, and updates the default recipe build.number to 1 to align build tagging behavior.

Changes:

  • Add a dedicated zizmor workflow and harden existing wheel build workflows (pinned SHAs, reduced permissions, safer input handling, non-persisting checkouts).
  • Add richer job summaries (built wheel tables; clearer on-device test headings; publish outcome table and stricter failure behavior).
  • Tune Dependabot scheduling/grouping and update meta schema + CI parsing to default build.number to 1.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/forge/schema/meta-schema.yaml Changes recipe schema default build.number to 1 and expands its description.
.github/workflows/zizmor.yml Adds zizmor workflow to continuously scan Actions security and upload results to code scanning.
.github/workflows/build-wheels.yml Hardens workflow permissions/checkout and pins actions to SHAs.
.github/workflows/build-wheels-version.yml Hardens workflow permissions/checkout, pins actions to SHAs, mitigates template injection risk, adds wheel build summaries, updates action versions.
.github/dependabot.yml Adjusts cadence/grouping and adds cooldown settings for Dependabot updates.
.ci/wait_for_console.sh Improves GitHub job summary headings for on-device test output.
.ci/read_meta.py Aligns build number default parsing with the updated schema default (1).
.ci/common.sh Enhances publishing to emit a job-summary table and fail on real upload errors.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .ci/common.sh
- Stop merging curl stderr into the captured output (drop 2>&1): a
  transfer-level failure could otherwise push a non-status line onto what
  tail parses as the HTTP code. -S still surfaces errors on stderr / the log.
- Drop "denied" from the duplicate-detection pattern: it is ambiguous and
  would misclassify a real 401/403 auth failure as "already exists".
  Keep matching only "already exists|same version".
Fork PRs run with a read-only GITHUB_TOKEN (no security-events: write), so the
code-scanning SARIF upload fails and reddens the check for external
contributors. Gate advanced-security on the PR not being from a fork: forks
still get inline annotations, while pushes and same-repo PRs upload to the
Security tab.
Dependabot does not run on this fork, so the config was dead. Drop it; manage
dependency updates separately if needed.
@ndonkoHenri ndonkoHenri changed the title ci: zizmor security checks, richer job summaries and Dependabot tuning ci: zizmor security checks, richer job summaries Jun 18, 2026
@ndonkoHenri ndonkoHenri merged commit e0d494b into main Jun 19, 2026
27 of 28 checks passed
@ndonkoHenri ndonkoHenri deleted the zizmor branch June 19, 2026 12:30
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