ci: add actionlint, zizmor, and oxfmt checks - #15
Conversation
Add a workflow-lint CI job running actionlint, zizmor, and oxfmt (YAML/Markdown/JSON format check), all managed via mise. Fix the issues zizmor found: - Disable credential persistence on all checkout steps (artipacked) - Scope contents:write to the release job only (excessive-permissions) - Disable mise-action caching in release.yml (cache-poisoning) - Ignore superfluous-actions for action-gh-release via .github/zizmor.yml Also reformat renovate.json with oxfmt.
📝 WalkthroughWalkthroughThe pull request adds workflow linting with ChangesWorkflow hardening and validation
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant CI as workflow-lint job
participant Actionlint
participant Zizmor
participant Oxfmt
CI->>Actionlint: validate workflow files
CI->>Zizmor: scan workflow files with GITHUB_TOKEN
CI->>Oxfmt: format-check workflow files
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/ci.yml:
- Line 62: Update the zizmor workflow step to enable strict collection by adding
the --strict-collection option while preserving the existing .github/workflows/
target.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: b1e26549-8af9-4f2f-9293-3077325589e6
📒 Files selected for processing (5)
.github/workflows/ci.yml.github/workflows/release.yml.github/zizmor.ymlmise.tomlrenovate.json
| - name: actionlint | ||
| run: actionlint | ||
| - name: zizmor | ||
| run: zizmor .github/workflows/ |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- workflow context ---'
sed -n '45,75p' .github/workflows/ci.yml
printf '%s\n' '--- zizmor references ---'
rg -n -i 'zizmor|strict-collection' .github README.md 2>/dev/null || true
printf '%s\n' '--- pinned documentation option ---'
curl -fsSL --max-time 20 https://raw.githubusercontent.com/zizmorcore/zizmor/v1.28.0/docs/usage.md \
| rg -n -C 4 -- '--strict-collection|strict.collection|collection'Repository: sou1118/typdiff
Length of output: 3257
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- all tracked version/config references ---'
rg -n -i 'zizmor|mise|aqua' --glob '!node_modules/**' --glob '!dist/**' --glob '!build/**' . || true
printf '%s\n' '--- v1.28.0 source tree candidates ---'
curl -fsSL --max-time 20 \
'https://api.github.com/repos/zizmorcore/zizmor/git/trees/v1.28.0?recursive=1' \
| jq -r '.tree[] | select(.path | test("src/|Cargo.toml|CHANGELOG|release"; "i")) | .path' \
| head -200
printf '%s\n' '--- tagged source references ---'
for path in \
src/cli.rs \
src/main.rs \
src/args.rs \
src/collection.rs \
src/inputs.rs
do
url="https://raw.githubusercontent.com/zizmorcore/zizmor/v1.28.0/$path"
body="$(curl -fsSL --max-time 20 "$url" 2>/dev/null || true)"
if [ -n "$body" ]; then
printf '%s\n' "--- $path ---"
printf '%s\n' "$body" | rg -n -C 5 'strict.collection|strict-collection|parse.*fail|collection' || true
fi
doneRepository: sou1118/typdiff
Length of output: 5468
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- version configuration ---'
cat -n mise.toml
for path in crates/zizmor/src/cli.rs crates/zizmor/src/main.rs crates/zizmor/src/models/inputs.rs; do
printf '%s\n' "--- $path ---"
curl -fsSL --max-time 20 \
"https://raw.githubusercontent.com/zizmorcore/zizmor/v1.28.0/$path" \
| rg -n -C 8 'strict.collection|strict-collection|collection|parse' || true
done
printf '%s\n' '--- relevant tagged source declarations ---'
for path in crates/zizmor/src/cli.rs crates/zizmor/src/main.rs; do
curl -fsSL --max-time 20 \
"https://raw.githubusercontent.com/zizmorcore/zizmor/v1.28.0/$path" \
| rg -n 'struct|enum|strict|collect|parse|exit|Error' || true
doneRepository: sou1118/typdiff
Length of output: 14596
🏁 Script executed:
#!/bin/bash
set -eu
path=crates/zizmor/src/registry/input.rs
curl -fsSL --max-time 20 \
"https://raw.githubusercontent.com/zizmorcore/zizmor/v1.28.0/$path" \
> /tmp/zizmor-input-v1.28.0.rs
printf '%s\n' '--- collector structure ---'
rg -n -C 12 'strict|parse|warn|Syntax|Schema|CollectionError|collect' /tmp/zizmor-input-v1.28.0.rs
printf '%s\n' '--- standalone semantic check ---'
python3 - <<'PY'
from pathlib import Path
s = Path('/tmp/zizmor-input-v1.28.0.rs').read_text()
needles = [
'if options.strict',
'tracing::warn!',
'CollectionError',
]
for needle in needles:
print(f'{needle}: {s.count(needle)} occurrence(s)')
assert 'if options.strict' in s
assert 'tracing::warn!' in s
print('The collector has separate strict and warning branches.')
PYRepository: sou1118/typdiff
Length of output: 23875
🏁 Script executed:
#!/bin/bash
set -eu
python3 - <<'PY'
from pathlib import Path
import re
s = Path('/tmp/zizmor-input-v1.28.0.rs').read_text()
syntax = re.search(
r'Err\(CollectionError::Syntax\(e\)\) if !strict:\s*\{(?P<body>.*?)\n\s*\}\n'
r'\s*Err\(e @ CollectionError::Schema',
s, re.S,
)
schema = re.search(
r'Err\(e @ CollectionError::Schema \{ \.\. \}\) if !strict:\s*\{(?P<body>.*?)\n\s*\}\n'
r'\s*Err\(e\) => Err\(CollectionError::Inner',
s, re.S,
)
assert syntax and 'tracing::warn!' in syntax.group('body') and 'Ok(())' in syntax.group('body')
assert schema and 'tracing::warn!' in schema.group('body') and 'Ok(())' in schema.group('body')
assert 'Err(e) => Err(CollectionError::Inner' in s
print('v1.28.0 collector behavior: non-strict syntax/schema errors warn and return Ok(()); strict errors return Err.')
main = Path('/tmp/zizmor-main-v1.28.0.rs')
if not main.exists():
import urllib.request
main.write_bytes(urllib.request.urlopen(
'https://raw.githubusercontent.com/zizmorcore/zizmor/v1.28.0/crates/zizmor/src/main.rs',
timeout=20,
).read())
m = main.read_text()
exit_block = re.search(r'Error::Collection\(err\).*?let exit = if .*?;\s*exit', m, re.S)
assert exit_block
assert 'ExitCode::FAILURE' in exit_block.group()
print('v1.28.0 CLI maps collection errors to a failing process exit.')
PYRepository: sou1118/typdiff
Length of output: 242
🏁 Script executed:
#!/bin/bash
set -eu
python3 - <<'PY'
from pathlib import Path
import re, urllib.request
src = Path('/tmp/zizmor-input-v1.28.0.rs').read_text()
for variant in ('Syntax', 'Schema'):
pattern = rf'Err\(.*CollectionError::{variant}.*\) if !strict\s*=>\s*\{{(?P<body>.*?)\n\s*\}}\n'
match = re.search(pattern, src, re.S)
assert match, variant
body = match.group('body')
assert 'tracing::warn!' in body and 'Ok(())' in body, variant
assert re.search(r'Err\(e\) => Err\(CollectionError::Inner', src)
print('v1.28.0: non-strict syntax/schema collection errors warn and return Ok(()); strict errors return Err.')
main = Path('/tmp/zizmor-main-v1.28.0.rs')
main.write_bytes(urllib.request.urlopen(
'https://raw.githubusercontent.com/zizmorcore/zizmor/v1.28.0/crates/zizmor/src/main.rs',
timeout=20,
).read())
m = main.read_text()
assert 'Error::Collection(err)' in m
assert re.search(r'let exit = if .*?ExitCode::FAILURE', m, re.S)
print('v1.28.0: collection errors map to a failing process exit.')
PYRepository: sou1118/typdiff
Length of output: 2542
🏁 Script executed:
#!/bin/bash
set -eu
curl -fsSL --max-time 20 \
https://raw.githubusercontent.com/zizmorcore/zizmor/v1.28.0/crates/zizmor/src/main.rs \
| sed -n '585,615p'Repository: sou1118/typdiff
Length of output: 866
Add --strict-collection to the zizmor step.
When a collected input has syntax or schema errors, zizmor 1.28.0 warns and skips it unless strict collection is enabled. Run zizmor --strict-collection .github/workflows/.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ci.yml at line 62, Update the zizmor workflow step to
enable strict collection by adding the --strict-collection option while
preserving the existing .github/workflows/ target.
Summary
Add a Workflow Lint job to CI that runs three checks, all version-pinned in
mise.toml:GH_TOKENfor online audits)apps_v1.77.0release tag)Security fixes (zizmor findings)
Running zizmor surfaced real issues, fixed here so the new check starts green:
actions/checkoutpersists git credentials in the workspace by default — addedpersist-credentials: falseeverywhere; nothing in these workflows pushes back.contents: writeworkflow-wide — nowreadat the top level, withwritescoped to the release job only.action-gh-releaseforgenerate_release_notes/asset handling; ignored via.github/zizmor.yml.Also reformatted
renovate.jsonper oxfmt.Notes
Summary by CodeRabbit
Chores
Documentation