Imported from yandy-r/claude-plugins (
.opencode-plugin/skills/releaser/SKILL.md). Install upstream withnpx skills add yandy-r/claude-plugins --skill releaser. Copyright stays with the author.
Generic Release Orchestrator
This skill prepares a release for any project: detects the toolchain, drafts a
changelog from conventional commits, plans platform/architecture artifacts, and — on
request — either generates a GitHub Actions release workflow or audits an existing one
against best practices. It emits the exact git tag, git push, and gh release create commands the user runs; it never commits, pushes, or publishes without an explicit --publish and --confirm from the user.
Not for this bundle. For
yccbundle releases usebundle-release, which is scoped to this repo'splugin.json+marketplace.jsonversion-parity contract and the Cursor/Codex sync flow.
Arguments
Parse $ARGUMENTS:
- version (optional first positional) — target semver (
1.4.0,v1.4.0, or a pre-release like1.4.0-rc.1). If omitted, the skill proposes one from commit history (conventional-commit bump) and asks for confirmation before continuing. - --arch=<list> — comma-separated target architectures (e.g.
amd64,arm64). Overrides language defaults. - --os=<list> — comma-separated target operating systems (e.g.
linux,darwin,windows). Overrides language defaults. - --ci-config / --ci-config=generate — scaffold a GitHub Actions release
workflow under
.github/workflows/release.yml. Fails if one already exists unless--ci-config=auditis also requested. (Renamed from--ciso the bare--ciflag matches the auto-fix-loop family used bygit-workflow,prp-pr, andpr-autofix.) - --ci-config=audit — invoke the
releaseragent to read the existing release workflow(s) and emit an optimization report. Read-only. - --platform=<name> — explicit toolchain override (
node,python,go,rust,docker,generic). Skips auto-detection. Useful for monorepos. - --skip-notes — skip drafting
CHANGELOGupdates and release notes. - --dry-run — run detection and print the full release plan. Writes nothing, executes no state-changing commands.
- --exclude-internal — omit the Maintenance section from the drafted release notes entirely. Use only when the release truly has zero internal-only churn worth surfacing.
- --publish[=create|edit|auto] — after the user reviews the rendered notes, invoke
publish-release.shto preview or apply thegh releasecommand. Default mode isauto(creates if no release exists, otherwise proposesedit). Useeditonly to intentionally replace an existing release body — this is destructive. - --confirm — when combined with
--publish, re-runs the helper with--confirmto actually execute theghcommand. The skill NEVER passes--confirmautomatically. - --ci — after a successful
--publish --confirm, enter the bounded Release CI auto-fix loop (Phase 8.5): poll the release-event workflow run, classify failures, dispatch a fix agent on implicated files, commit + push, re-cut the release, and loop until green or a bail cap fires. No-op (with warning) if--publish --confirmdid not succeed in this run. Shares contract withci-monitor.sh/ sibling skills. - --ci-max-pushes=N — hard cap on autonomous fix-and-recut iterations per
invocation. Default
5. Forwarded torelease-ci-monitor.sh. - --ci-max-same-failure=N — bail after the same failure signature recurs N
times. Default
3. Forwarded torelease-ci-monitor.sh. - --ci-timeout-min=N — wall-clock cap in minutes from the first iteration.
Default
30. Forwarded torelease-ci-monitor.sh. - --ci-yes — skip the one-time Phase 8.5 authorization prompt. Use only for non-interactive callers; safety caps remain enforced.
- --ci-recut=destructive — opt in to the destructive re-cut fallback when the
detected release workflow has no
workflow_dispatchtrigger. Without this flag, the loop refuses to enter when the only available re-cut path isgh release delete --cleanup-tagfollowed by re-publish.
Phase 0: Preflight
Before anything else, verify:
- Working directory is a git repo:
git rev-parse --show-toplevelsucceeds. - Working tree is clean:
git status --porcelainis empty. If dirty, STOP and ask whether to stash or abort — never silently move forward with uncommitted changes. ghis installed and authenticated when--ci-configis absent but the user asked for a GitHub release. Also required when--ciis set, since the auto-fix loop callsgh run list,gh workflow run, andgh releaseunder the hood. Surface install/login hints if missing.- If
versionwas provided, it matches the regex^v?[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9.-]+)?(\+[A-Za-z0-9.-]+)?$. Reject malformed input with a clear error.
If any check fails, STOP and surface a specific remediation — do not continue past Phase 0 with known-bad preconditions.
Phase 1: Detect project
Run:
~/.config/opencode/skills/releaser/scripts/detect-project.sh
The helper emits a single JSON document to stdout describing:
language— primary language (node,python,go,rust,docker,mixed,generic).build_system—npm/pnpm/yarn/poetry/uv/hatch/setuptools/cargo/go-modules/docker/none.manifest_files— list of version-bearing files.default_osanddefault_arch— sensible defaults for that language.existing_ci— list of.github/workflows/*.ymlfiles already present.current_version— extracted from the manifest, ornullif not found.latest_tag— output ofgit describe --tags --abbrev=0 2>/dev/nullornull.
If --platform was passed, override the detected language field before continuing.
See references/project-type-matrix.md for the full language → toolchain → default
matrix.
Phase 2: Propose version and compute bump
If the user did NOT supply a version:
- Collect commits since
latest_tag(or the last 50 if no tag exists):git log <latest_tag>..HEAD --format="%s". - Classify each commit against conventional-commit types. Determine the bump:
- Any
!marker,BREAKING CHANGEfooter, ormajor:→ major. - Any
feat:→ minor. - Otherwise → patch.
- Any
- Propose the next semver and ASK for confirmation before writing anything.
If the user DID supply a version, sanity-check the bump magnitude against commit
history. Surface a concern if they are mismatched (e.g. feat: commits but a patch
bump) and require explicit confirmation before continuing.
Phase 3: Resolve release target matrix
Build the final {os × arch} matrix:
- Start with
default_os/default_archfrom Phase 1. - If
--osor--archwas passed, replace the corresponding axis entirely. - Reject combinations with no known build recipe (e.g.
windows × armfor languages where cross-compilation is unsupported) — list the invalid combos and ask whether to drop or abort.
Store the matrix for Phases 5, 6, and 7.
Phase 4: Draft changelog and release notes
Unless --skip-notes was passed:
-
Invoke the changelog helper and capture its stdout:
~/.config/opencode/skills/releaser/scripts/draft-changelog.sh [--exclude-internal] [--template <path>] <new-version> [<from-ref>]Pass
--exclude-internalif the user requested it. Pass--template <path>if the user supplied a custom template path. The helper fills the template placeholders ({{VERSION}},{{DATE}},{{HIGHLIGHTS}},{{BREAKING}},{{FEATURES}},{{FIXES}},{{INTERNAL}},{{COMMITS}},{{COMPARE_URL}},{{PREVIOUS_TAG}}) from git history and writes the complete rendered document to stdout. -
Write the captured stdout to
docs/releases/<new-version>.md(or.github/releases/<version>.mdif the repo already uses that path). This is the notes file that thegh release createcommand consumes. -
Update
CHANGELOG.mdby prepending a slim version of the same content — Summary and per-category sections only, no<details>blocks — above any## [Unreleased]marker. If noCHANGELOG.mdexists, create one using the template seeded from~/.config/opencode/skills/releaser/references/release-notes-template.md.
Ask the user to review the drafted Summary and Upgrade Notes sections before moving on.
Internal vs. user-facing commits
Commits typed docs, chore, test, build, ci, style, and refactor are
classified as Maintenance. The helper surfaces them in a collapsible <details> block
so they are visible but not dominant. Pass --exclude-internal to drop the Maintenance
section entirely — use this only when the release genuinely contains no internal-only
churn worth surfacing; otherwise keep the section so reviewers have full context.
Phase 5: Bump version in manifests
Edit only the files named in manifest_files from Phase 1. Common targets:
package.json→versionfield.pyproject.toml→[project].versionor[tool.poetry].version.Cargo.toml→[package].version.go.moddoes not carry a version; the tag IS the version. Skip the bump step.Dockerfileordocker-compose.ymllabels → update if the repo usesorg.opencontainers.image.version.
NEVER edit files outside that list. After edits, emit a diff summary and STOP for user review before continuing.
Phase 6: CI workflow file (optional)
This phase generates or audits the release.yml file itself. It is separate from the Phase 8.5 release-CI auto-fix loop (which watches a live workflow run after publish). Three modes:
--ci-config=generate
Fails if any file in existing_ci looks release-related (matches
release|publish|deploy). Otherwise, write a new .github/workflows/release.yml by
copying the matching template:
- Node →
references/ci-templates/node-release.yml - Python →
references/ci-templates/python-release.yml - Go →
references/ci-templates/go-release.yml(uses goreleaser) - Rust →
references/ci-templates/rust-release.yml(uses cargo-dist if configured, else actions-rs matrix) - Docker →
references/ci-templates/docker-release.yml - Generic →
references/ci-templates/generic-release.yml(tag-triggered, uploads artifacts viasoftprops/action-gh-release)
Substitute the Phase 3 matrix and project name into the template. Also emit a short
.github/workflows/README.md entry documenting the new workflow — required (see
references/ci-optimization-checklist.md, "Documentation" section).
--ci-config=audit
Delegate to the releaser agent. Pass it the list of existing workflow files. The
agent returns a structured report (Findings → Severity → Fix). The skill summarizes the
top items and writes the full report to docs/prps/reviews/ci-release-audit.md for
later consumption by review-fix.
No --ci-config flag
Skip Phase 6 entirely. Print a one-line reminder: "Skipped CI workflow generation.
Run with --ci-config=generate or --ci-config=audit to include it. (This is
separate from --ci, which monitors a live release workflow after publish.)"
Phase 7: Dry-run check
If --dry-run was passed:
- Print the full release plan: detected project, proposed version, target matrix, files that would change, commands that would run.
- STOP. Write nothing, execute nothing side-effecting.
- If both
--dry-runand--publishwere passed,--dry-runwins: the publish helper does NOT run.
Phase 8: Emit next-step commands
Always emit the following block. Substitute <new-version>, <changed-files>, and
<notes-path> with real values. NEVER run these commands automatically.
Release prepared. No commits or tags have been created — review the diff, then run:
git add <changed-files>
git commit -m "chore(release): v<new-version>"
git tag -a v<new-version> -m "v<new-version>"
git push origin HEAD --follow-tags
# Create the GitHub release from the drafted notes:
gh release create v<new-version> \
--notes-file <notes-path> \
--title "v<new-version>"
# If artifacts were produced locally and need uploading:
gh release upload v<new-version> <path-to-artifact> [...]
If --ci-config=generate ran, append:
# Verify the new workflow in CI by pushing the tag — the release workflow will
# build the matrix and attach artifacts to the GitHub release.
Forge provider detection: release creation is provider-aware.
publish-release.sh detects the forge provider on origin first and routes
through the matching CLI — gh release create for github, tea release create --tag <tag> [--note-file] for forgejo/gitea (per the
operation-equivalence map). The gh release create/gh release upload commands
emitted in the Phase 8 block above are the github path; on a forgejo/gitea
remote the helper drives tea release create instead. Log the resolved provider
- CLI. See
../_shared/references/forge-detection.md.
When the user passed --publish[=create|edit|auto], after they review the rendered
notes, run:
~/.config/opencode/skills/releaser/scripts/publish-release.sh v<new-version> <notes-path> --mode=<mode>
Examples:
# Preview only — prints the resolved gh command without executing it:
~/.config/opencode/skills/releaser/scripts/publish-release.sh v1.4.0 docs/releases/v1.4.0.md --mode=auto
# Apply — executes the resolved gh command:
~/.config/opencode/skills/releaser/scripts/publish-release.sh v1.4.0 docs/releases/v1.4.0.md --mode=auto --confirm
This prints the resolved gh command without executing it. Re-run with --confirm to
apply. Use --mode=edit only when intentionally replacing an existing release body —
this is destructive.
Phase 8.5: Release CI auto-fix loop (--ci)
Runs only when ALL of the following hold:
--ciwas passed.--publishwas passed.--confirmwas passed ANDpublish-release.sh --confirmexited 0 (the release exists on GitHub and the release-event workflow has been triggered).
Otherwise, print a one-line warning — --ci ignored: no successful publish in this run — and skip to Phase 9. Never enter the loop without a live release to watch.
The contract (exit codes, RESULT= signaling, JSONL audit log, failure classification,
signature dedup, default-branch refusal) mirrors ci-monitor.sh verbatim. See
_shared/references/ci-monitoring.md,
section "Release mode", for the single source of truth.
GitHub-only: the release-CI auto-fix loop is GitHub-only — it depends on
gh run list, gh workflow run, and gh release controls that have no tea
equivalent. On a non-GitHub remote release-ci-monitor.sh returns
RESULT=unsupported-provider (exit 2). Treat it like not-found: report that
the loop is GitHub-only, render an 8.5.4-style diagnosis, and exit Phase 8.5
cleanly without retrying. (Release creation in Phase 8 remains provider-aware
via tea release create; only this post-publish monitoring loop is gated.) See
../_shared/references/forge-detection.md.
8.5.0 Detect re-cut strategy
Read .github/workflows/<resolved-release-workflow>.yml and inspect the on:
triggers:
- If
workflow_dispatchis present → preferred path: re-trigger viagh workflow run <name> --ref <tag>. Non-destructive. - Else if
--ci-recut=destructivewas passed → fallback path:gh release delete <tag> --cleanup-tag --yesthen re-runpublish-release.sh ... --confirmto recreate the tag and release. - Else → REFUSE to enter the loop. Print: "Release workflow has no
workflow_dispatchtrigger; re-running it requires destroying and recreating the release. Add aworkflow_dispatch:trigger to your release workflow, or re-run this command with--ci-recut=destructiveto opt in." Exit Phase 8.5.
8.5.1 Authorization gate (skipped if --ci-yes)
Render a one-time block showing:
- Resource: tag
v<new-version>, workflow<file>, repo<owner/name>. - Resolved caps:
--ci-max-pushes(default 5),--ci-max-same-failure(default 3),--ci-timeout-min(default 30). - Re-cut strategy detected in 8.5.0:
workflow_dispatch(preferred) ordelete-release-and-retag(destructive — only if--ci-recut=destructive). - Non-toggleable safety constraints:
- Never
git push --forceto any branch. - Never
git push --no-verify. - Never edits files outside the failed workflow step's implicated paths.
- Never amends published release notes without an explicit user opt-in.
- Never
Wait for yes/no. Any other input aborts the loop and proceeds to Phase 9 with
"loop declined" status.
/goal re-confirmation (safety)
If a /goal session directive is active when Phase 8.5 is reached, this gate is the
one human approval the bounded, destructive-capable loop depends on. Therefore:
--ci-yesdoes NOT suppress this gate under an active/goal. When/goalis active, always render the 8.5.1 block and wait for an explicityes/no, even if--ci-yeswas passed.--ci-yesis honored only when no/goaldirective is active.- A
/goalevaluator is transcript-only and cannot answer this prompt, so the loop pauses here until you respond in person. That pause is intentional:/goalmay drive the Phase 8.5.2+ fix-and-recut loop to green, but it must never auto-authorize entry into that loop. Print one line making the pause legible:/goal active — Phase 8.5.1 authorization stays interactive; --ci-yes ignored. Waiting for yes/no. - This guard applies only to the post-publish CI loop. The Phase 2 version confirm
and the Phase 5 manifest diff review are likewise never auto-approved under
/goal; see## /goal pairingfor the full out-of-scope list.
8.5.2 Loop protocol
-
Initialize audit log:
mkdir -p ~/.config/opencode/session-data/release-ci-watch/ AUDIT_LOG=~/.config/opencode/session-data/release-ci-watch/<tag>-<utc-iso>.log -
Invoke the monitor:
~/.config/opencode/shared/scripts/release-ci-monitor.sh \ --tag v<new-version> \ --workflow <detected-or-passed> \ --repo <owner/name> \ --max-pushes <N> \ --max-same-failure <N> \ --timeout-min <N> \ --log-file "$AUDIT_LOG" -
Branch on the exit code (identical contract to
ci-monitor.sh):Exit RESULT=Action 0 greenSuccess. Exit Phase 8.5, continue to Phase 9. 20 handoffStep 8.5.3 (fix and re-cut), then loop to step 2. 21 rerun-pendingsleep 30, then loop to step 2 (no fix applied).10 bail-recurrenceStep 8.5.4 (diagnosis), exit Phase 8.5. 11 bail-nonfixableStep 8.5.4, exit Phase 8.5. 12 bail-pushesStep 8.5.4, exit Phase 8.5. 13 bail-timeoutStep 8.5.4, exit Phase 8.5. 2 not-foundStep 8.5.4, exit Phase 8.5. 2 unsupported-providerRemote is not GitHub; loop is GitHub-only. Step 8.5.4, exit Phase 8.5.
8.5.3 Fix and re-cut on handoff
The monitor wrote one JSONL line to the audit log with the failed run's metadata:
run_id, workflow_name, job_name, step_name, category, signature,
log_excerpt_path, implicated_files.
-
Dispatch the fix agent via the opencode
tasktool with@release-fix-applier. Pass the JSONL line verbatim. The agent edits ONLY the implicated files, returns the proposed commit message (conventional-commit prefix matching the category —fix,ci,build, etc.) and the diff summary. -
Validate the commit message:
~/.config/opencode/skills/git-workflow/scripts/validate-commit.sh "<message>" -
Pre-push branch-protection check:
gh api repos/<owner>/<name>/branches/main/protection 2>/dev/nullIf
mainhasrequired_pull_request_reviews, the loop cannot push directly. Surface: "Direct push tomainblocked by branch protection — open a PR with the fix, merge it, and re-run with--ci." Exit Phase 8.5 withloop-blockedstatus (renders an 8.5.4-style block without retrying). -
Commit and push:
git add <implicated-files> git commit -m "<validated-message>" git push origin HEADNEVER
--force. NEVER--no-verify. -
Re-trigger the release workflow per the strategy detected in 8.5.0.
-
Preferred (
workflow_dispatchavailable):gh workflow run <name> --ref v<new-version> -
Fallback (only if
--ci-recut=destructivewas set):gh release delete v<new-version> --cleanup-tag --yes ~/.config/opencode/skills/releaser/scripts/publish-release.sh \ v<new-version> <notes-path> --mode=create --confirm
-
-
push_count++. Loop back to 8.5.2 step 2.
8.5.4 Bail diagnosis block
Render to the user:
- Reason — one of
recurrence/nonfixable/pushes/timeout/not-found/loop-blocked. - Cap that fired and its resolved value.
- Last failure —
run_id,workflow_name,job_name,step_name,category,signature. - Log excerpt path (from the monitor's
--log-file). - Audit log path.
- Next steps — concrete guidance keyed off the bail reason (e.g., for
recurrence: "The same failure (<signature>) recurred. Inspect<log-excerpt-path>and apply a manual fix before retrying.").
Always print this block — even on not-found — so the user has a single
post-mortem surface.
Phase 9: Final summary
Report to the user:
- Detected language / build system / manifest files.
- Proposed vs. requested version.
- Target
{os × arch}matrix. - Files modified (changelog, notes, manifests, workflow).
- CI workflow-file outcome (generate / audit / skipped) and report path if audit ran.
- Publish mode outcome: whether the release was published (applied with
--confirm), previewed only (print-only via--publishwithout--confirm), or emit-only (no--publishflag). - Release CI loop outcome (if
--ciwas set):green(final status),bail-*(with reason and cap that fired),loop-blocked,declined, orskipped(no successful publish). Include the audit log path so the user can inspect it. - The exact command block from Phase 8.
Then, as the last lines of the summary, print the Goal Signals block verbatim:
Goal Signals (machine-readable — printed verbatim for /goal)
RELEASE_PUBLISHED: <PASS|FAIL|n/a>
GATES_INTERACTIVE: <PASS|FAIL>
CI_GREEN: <PASS|FAIL|n/a>
CI_BAIL_VISIBLE: <PASS|n/a>
AUDIT_LOG_PRINTED: <PASS|FAIL|n/a>
Print one KEY: PASS|FAIL per line. Use PASS only when the matching ## Success Criteria item holds; otherwise FAIL. See ## Success Criteria for each key's exact
condition and n/a rules.
Success Criteria
- RELEASE_PUBLISHED:
--publish --confirmran andpublish-release.sh --confirmexited 0 (the release exists on GitHub).n/awhen--publishwas not set or ran in preview-only mode. - GATES_INTERACTIVE: Every human gate that applied this run — Phase 2 version confirm, Phase 5 manifest diff review, and the Phase 8.5.1 authorization — was satisfied by explicit user input and none was auto-approved or bypassed (including under an active
/goal).FAILif any applicable gate was skipped without a humanyes. This is the safety invariant that keeps/goalfrom wrapping the whole skill. - CI_GREEN: If
--ciran, the Phase 8.5 loop reachedRESULT=greenand the Phase 9 summary shows "Release CI loop outcome:green".n/awhen--ciwas not set or the loop was skipped (no successful publish). - CI_BAIL_VISIBLE: If
--ciended without green, the summary states the terminal outcome (bail-*,loop-blocked, ordeclined) and the cap/constraint that fired.n/awhen--cireached green or was not set. - AUDIT_LOG_PRINTED: If
--ciran, the Phase 9 summary printed the audit-log path.n/awhen--ciwas not set or the loop was skipped.
These keys are emitted verbatim in the Phase 9 Goal Signals block so a /goal evaluator can observe completion from the transcript alone.
/goal pairing
Pair this skill with the /goal session directive only for the bounded Phase 8.5 release-CI auto-fix loop — never for the skill as a whole. The full releaser flow has three human approval gates that exist specifically to prevent unattended publishing and looping; /goal must never auto-satisfy them:
- Phase 2 — version confirm. The user must approve the proposed version bump.
- Phase 5 — manifest diff review. The user must approve what changed before any commit.
- Phase 8.5.1 — CI authorization gate. The user must approve before the bounded, destructive-capable loop starts.
--ci-yesdoes not bypass this gate under an active/goal(see the 8.5.1/goalre-confirmation guard).
Because the /goal evaluator is transcript-only it cannot answer these prompts, so a /goal loop will pause at each gate until you respond in person. That is the intended behavior: only after you have published (--publish --confirm) and authorized the loop does /goal add value — driving Phase 8.5.2+ through every handoff fix-and-recut and rerun-pending retry to green without returning control between iterations. The GATES_INTERACTIVE Goal Signal records that none of the three gates was auto-approved.
The Phase 8.5 loop's RESULT= markers (from release-ci-monitor.sh, sharing the ci-monitor.sh contract with pr-autofix and prp-pr) tell the evaluator when to keep looping versus when to stop:
- Keep looping —
handoff(8.5.3 fix-and-recut) andrerun-pending(8.5.2 wait-and-retry). Recoverable progress markers, not endpoints. - Done —
RESULT=green, with the Phase 9 summary showing "Release CI loop outcome:green" and the audit-log path (CI_GREEN: PASS,AUDIT_LOG_PRINTED: PASS). - Stop — any terminal
bail-*(bail-recurrence,bail-nonfixable,bail-pushes,bail-timeout,not-found) orloop-blocked.release-ci-monitor.shexhausts recoverable retries internally before emitting a bail, so a printed terminal marker means no further automatic progress is possible. The evaluator distinguishes "loop again" from "stop" bygreenvsbail-*/loop-blockedin the Phase 9 summary — never by re-classifying bail codes. See../_shared/references/ci-monitoring.md("Release mode") for the authoritative bail taxonomy.
Recommended condition template (set this after you have approved Phases 2 and 5, published with --publish --confirm, and authorized the loop at 8.5.1):
/goal Drive the releaser Phase 8.5 release-CI loop to green, continuing through every
handoff and rerun-pending iteration without returning control to me. Done when the Phase 9
summary shows "Release CI loop outcome: green", the audit-log path is printed, and the Goal
Signals print verbatim — GATES_INTERACTIVE: PASS, CI_GREEN: PASS, and AUDIT_LOG_PRINTED:
PASS. If CI_GREEN prints FAIL alongside CI_BAIL_VISIBLE: PASS (a terminal bail-*, loop-blocked,
or declined), stop and report it — do not re-run. Never auto-approve the Phase 2 version
confirm, the Phase 5 manifest review, or the Phase 8.5.1 authorization. Stop after 25 turns
if not achieved.
The transcript-output contract and shared caveats (worktree cwd, interactive failure prompts, platform availability) live in the shared reference — read it before relying on a /goal loop:
~/.config/opencode/shared/references/goal-pairing.md
Important Notes
- Never auto-commits, pushes, or publishes. The user reviews every change and runs
the emitted commands manually. This is the same discipline as
bundle-release. - Publish helper = operator workflow, not a guardrail.
publish-release.shruns in print-only mode by default: it prints the resolvedghcommand (including--verify-tagfor creates) and exits successfully. The operator reviews that line, then re-runs the same invocation with--confirmwhen they intend to publish. The script sets an internal confirm flag only when--confirmis passed; without it, no mutatingghcall runs. --dry-runbeats--publish. If both flags are present, the publish helper does not run. Dry-run always exits before any side-effecting step.- Never edits files outside the detected
manifest_fileslist. If the repo has unusual version ownership (e.g. aVERSIONfile, a_version.py, multi-package workspaces), add it to the list via--platform=genericand the user confirms before edit. - Never regenerates third-party lockfiles as a side effect. If
package.jsonbumps requirepackage-lock.json, the skill instructs the user to run the lockfile command themselves and surfaces any drift. - CI generation is opinionated, not magic. The templates are starting points; the skill calls out which inputs require human configuration (secrets, environments, signing keys, provenance) before the workflow will run green.
- For existing CI workflow files, always prefer
--ci-config=auditfirst. Do not overwrite a working workflow without the user's explicit confirmation. --ci(Phase 8.5) is opt-in and post-publish. It enters only after--publish --confirmhas actually created/edited the release on GitHub. The authorization gate (8.5.1) cannot be bypassed except with--ci-yes, and the destructive re-cut fallback cannot be reached except with--ci-recut=destructive.- The release-CI loop never edits release notes or manifest files. It only touches files implicated by the failed workflow step. Notes and manifests are considered immutable for the lifetime of the loop.
- See
references/project-type-matrix.mdfor the full language → toolchain map. - See
references/ci-optimization-checklist.mdfor the audit criteria used by the agent and the default quality gate for generated workflows. - See
references/release-notes-template.mdfor the drafted notes format. - See
../_shared/references/ci-monitoring.md("Release mode" section) for the loop contract, exit-code table, and audit-log schema.