release-publish-trigger
Skill0 starsChanged 3 months agoMITView on GitHub
Validates every release-automation pre-publish gate locally, then dispatches release-publish.yml via `gh workflow run` for the open release-drafter draft on develop, per the canonical-language file under spec/project/release-skill-layer/ §\"Skill B — Release publish trigger\". Verifies that exactly one open draft exists, the draft tag is reachable from the develop tip, version-bearing files align under their declared transform, every required status check reports SUCCESS on the pull-request head the develop tip merges, and `.github/workflows/release-publish.yml` exists. Refuses to dispatch on any failed gate; routes red checks to workflow-health triage. Never calls `gh release edit --draft=false` directly. Invoke when the user asks to \"publish the release\", \"trigger release publish\", \"ship the release\", or equivalent German-language requests. Typically called by sprint-review's opt-in chain, not directly after sprint closure.
- Reads credentials
In this repository36 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- audience-identifySkill
- backlog-delivery-orchestrateSkill
- backstage-catalog-generateSkill
- blog-authorSkill
- blog-author-triggerSkill
- cicd-pipeline-designSkill
- continuous-improvement-triageSkill
- cookiecutter-template-manageSkill
- docs-audience-tracks-applySkill
- docs-dry-refactorSkill
- github-issue-templates-applySkill
- issue-backlog-partitionSkill
- issue-batch-orchestrateSkill
- issue-orchestrateSkill
- lektorat-applySkill
- lektorat-auto-reviseSkill
- mermaid-diagrams-applySkill
- mkdocs-structure-applySkill
- permission-allowlist-maintainSkill
- portfolio-auditSkill
- portfolio-inflight-triageSkill
- project-structure-applySkill
- pull-request-createSkill
- pull-request-mergeSkill
- pull-request-runner-sweepSkill
- readme-structure-applySkill
- release-notes-curateSkill
- requirements-elicitSkill
- spec-drift-auditSkill
- specSkill
- tech-stack-captureSkill
- vocab-drift-auditSkill
- workflow-health-triageSkill
- working-copy-startSkill
- yaml-json-schemaSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
23 rules. About 0 are common, 4 are distinctive, and 19 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
19
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 62
Refuse and report: when zero drafts match (operator should run release-drafter.yml first) or when more than one matches without an explicit …
- Very specific: line 77
When .github/release-skill-layer.yml declares an explicit project_type: value, use it instead of the autodetection (override path) — the …
- Distinctive: line 79
When no signal matches, stop and ask the operator to declare the project type manually.
- Very specific: line 96
Read the version-bearing file list per release-automation §Version-bearing files: select the default-table rows for the project type …
- Very specific: line 103
Verify the subject prefix starts with chore(release): <tag> (the prefix-match accepts the (#N) suffix GitHub appends on squash-merge, per …
- Very specific: line 110
Read the required check list from .github/settings.yml (branches[name=develop].protection.required_status_checks.contexts).
- Distinctive: line 133
Before dispatch, surface to the operator as a single block:
- Very specific: line 147
Run gh workflow run release-publish.yml --ref develop -f tag=<tag>.
- Very specific: line 148
When the operator opts in to --dry-run, dispatch with -f dry_run=true so the workflow validates without flipping draft: false.
- Very specific: line 149
Never: call gh release edit --draft=false, gh api -X PATCH /repos/.../releases/<id> with draft=false, or any other body that flips the …
- Very specific: line 197
Read examples/01-clean-dispatch-all-gates-pass.md when all pre-publish gates pass and the skill dispatches the release workflow cleanly.
- Very specific: line 198
Read examples/02-version-bearing-files-misaligned.md when version-bearing files are out of sync and the gate blocks dispatch.
- Very specific: line 199
Read examples/03-required-checks-red-route-to-workflow-health.md when a required check on develop's tip is red and triage routes to …
- Very specific: line 200
Read examples/04-dispatch-superseded-in-queue.md when a dispatched run is cancelled in the queue without publishing, or is still queued …
- Very specific: line 204
Never dispatch when any pre-publish gate fails.
- Very specific: line 205
Never call gh release edit --draft=false, gh api -X PATCH .../releases/<id> with draft=false, or any other body that flips the draft state.
- Very specific: line 206
Never use a --ref other than the default branch (typically develop).
- Distinctive: line 207
Never poll to completion outside an explicit operator opt-in to wait mode.
- Very specific: line 208
Never report a landed dispatch, or a run still queued, as a publish that happened.
- Very specific: line 209
Never route a cancelled run to workflow-health.
- Very specific: line 210
Never retry a failed release-publish.yml run blindly.
- Distinctive: line 211
Never proceed without explicit operator confirmation of the disclosed validation state.
- Very specific: line 212
When spec/project/release-skill-layer/ or spec/project/release-automation/ disagrees with this skill's instructions, the spec wins.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Release Publish Trigger
Operationalises spec/project/release-skill-layer/<canonical_language>.md §"Skill B — Release publish trigger": validates every release-automation §Pre-publish verification gate locally, then dispatches release-publish.yml via gh workflow run. The workflow remains the audit-trail point for the Draft → Published transition; this skill is the local pre-flight plus dispatch.
Why this is a skill, not an agent
- Externally-visible mutation gates on user confirmation —
gh workflow run release-publish.ymltriggers an external publish chain (release published →release-cd-refresh-master.yml→mainfast-forward → packaging workflows); mid-flow operator gating is core to the contract and would be lost in an agent's fire-and-forget shape. - Output flows back into the main conversation — the gate-by-gate validation report, the dispatch URL, and the post-dispatch status all surface in the conversation so the operator can decide.
- Orchestrator that routes to other skills on failure — red required checks route to
workflow-healthtriage; the skill-orchestrates pattern (perskill-vs-agent) defaults the orchestrator to skill form. - Counter-dimension considered: a tool-restricted agent (read + a single
ghBash) could perform the verification half cleanly, but the dispatch decision needs the operator in the loop and the skill stays in the conversation to surface the run URL and follow-up status — keeping the whole flow in one skill is simpler than a forced split.
User-language policy
Detect the operator's language and respond in it. All git, gh api, and gh workflow run invocations stay English so that release-publish.yml's job summary, release-drafter's draft body, and downstream automation stay consistent across the portfolio.
German trigger phrases
The frontmatter description keeps the trigger lexicon English-only per spec/claude/skill-management/ §Structure (plugin-distributed skills). Treat the following German paraphrases as equivalent and discoverable through this skill:
- "veröffentliche das Release"
- "stoße den Release-Publish an"
- "ship das Release"
Preconditions
Before doing anything:
- Confirm the working directory is a git repository (
git rev-parse --is-inside-work-tree) and the remote resolves to a GitHub repository. - Confirm
ghis authenticated (gh auth status). - Locate
spec/project/release-skill-layer/andspec/project/release-automation/— either in the target repo or via thenolte-sharedplugin install path. Stop and ask if neither is reachable. - Confirm the repo's default branch (
gh repo view --json defaultBranchRef --jq .defaultBranchRef.name) is the integration branch the spec applies to (typicallydevelop).
Operations
Operation 1 resolves the open draft and Operation 2 detects the project type (the index into release-automation §Version-bearing files, shared with Skill A per the spec's §Skill split and shared shape MUST). Operations 3 to 5 then form a Plan-validate-execute cycle: Operation 3 walks every pre-publish gate, Operation 4 surfaces the validated state for explicit operator confirmation, and Operation 5 dispatches release-publish.yml. Operation 6 follows the dispatched run until it leaves the queue and reports from there; a landed dispatch isn't the skill's terminal state, because a queued run can still be superseded without publishing.
1. Resolve the open draft
- Run
gh release list --json isDraft,tagName,targetCommitish,createdAt,name. - Filter to drafts whose
targetCommitishequals the default branch. - Refuse and report when zero drafts match (operator should run
release-drafter.ymlfirst) or when more than one matches without an explicit--tagargument from the operator (no "newest wins" heuristic, perrelease-automation§Operational contract).
Tooling (optional GitHub MCP) — go/no-go: GO (narrow). Prefer github:list_releases for the draft resolution here (Op 1) and github:get_release_by_tag for the post-publish verify (Op 6), falling back to the gh commands shown, per spec/claude/mcp-tool-preference/. The release-publish.yml dispatch, the required-check-runs gate, and all workflow-run status reads have no MCP tool and stay gh (OQ-D); the reachability / version-file / alignment gates stay local git. gh/git stays authoritative; output is identical.
2. Detect project type
Per spec/project/release-skill-layer/ §Skill split and shared shape (MUST), both release-layer skills follow the same six project-type detection signals used by github-issue-templates-apply and by release-notes-curate (Skill A). Walk these six signals in order and stop at the first match. Read the files via the standard read tools — never via filename heuristics alone:
- Claude Code plugin —
.claude-plugin/plugin.jsonexists; top-levelskills/and / oragents/folder present. - Python application —
pyproject.tomldeclares[project.scripts](or equivalent application entry point), no library distribution metadata. - Python library —
pyproject.tomldeclares a distributable package without an application entry point. - Node / TypeScript library or app —
package.jsonexists;main/exportsindicates library,bin/scripts.startindicates app. - CLI tool — declared CLI entry point in
pyproject.toml([project.scripts]),package.json(bin), orCargo.toml([[bin]]). - Documentation-only repo —
mkdocs.yml,docusaurus.config.*, or similar exists with no application source.
When .github/release-skill-layer.yml declares an explicit project_type: value, use it instead of the autodetection (override path) — the same override that Skill A honours.
When no signal matches, stop and ask the operator to declare the project type manually. Never proceed with a generic fallback.
The detected type is the index into release-automation §Version-bearing files: the "Version-bearing files aligned" gate uses it to select the correct default version-bearing-file rows for this repo (Claude Code plugin, Python package, Node.js package, HACS integration, etc.) before reading and comparing each file.
3. Validate every pre-publish gate
Walk these gates in order. The skill MUST NOT proceed past a failed gate; surface the gate name, the failure detail, and the remediation path.
1. Draft tag reachable from develop
git fetch origin develop.- Resolve the draft's
targetCommitishSHA. - Run
git merge-base --is-ancestor <target-sha> origin/develop. - Failure: the draft is stale relative to
develop. Remediation: re-runrelease-drafter.ymlto refresh the draft target.
2. Version-bearing files aligned
- Read the version-bearing file list per
release-automation§Version-bearing files: select the default-table rows for the project type detected in step 2, or use the override at.github/release-automation.ymlwhen the repo declares one. - For every declared file, read the value at the
target-sha(git show <target-sha>:<path>plus the spec's selector) and compare against the target tag under the file's value transform (typically "strip leadingv" if the existing convention omits it). - Failure: any file whose value does not equal the target tag under transform. Remediation: open a
chore(release): <tag>PR (fallback path) or wait for the workflow-driven primary path to land its alignment commit.
3. Alignment commit present
- Identify the most recent commit on
developthat touched any version-bearing file:git log -1 --pretty=%s --follow -- <path>. - Verify the subject prefix starts with
chore(release): <tag>(the prefix-match accepts the(#N)suffix GitHub appends on squash-merge, perrelease-automation§Pre-publish verification). - Failure: no
chore(release): <tag>commit on the path. Remediation: same as the "Version-bearing files aligned" gate.
4. Required status checks SUCCESS where they were enforced
Evaluate this gate on the pull-request head the develop tip squash-merges, not on the tip.
- Read the required check list from
.github/settings.yml(branches[name=develop].protection.required_status_checks.contexts). - Resolve the commit to judge:
gh api repos/<owner>/<repo>/commits/<tip-sha>/pulls --jq '.[0].head.sha'.- A SHA comes back → that is the commit to query, and report it to the operator alongside the tip so the substitution is visible.
- Nothing comes back (a direct push, or a merge the API does not associate) → fall back to the tip SHA and say so in the report.
- Query
gh api repos/<owner>/<repo>/commits/<sha>/check-runsfor the resolved SHA and confirm every required context appears withconclusion=success. - Failure: any required check is
failure,cancelled,timed_out, stillin_progress, or absent. Remediation:- red checks → route to
workflow-healthtriage (classify asdefect/flake/infra/stale pin/secret drift/other); never retry the dispatch blindly. - pending checks → stop and ask the operator to wait, or opt in to wait mode (see "Wait mode" below).
- absent on a resolved pull-request head → a genuine gap: branch protection should have required it there. Report it as a protection-configuration problem, not as a missing run.
- absent on a fallback tip → the repository published from a commit on which its required contexts were never enforced. Refuse, and say that plainly rather than treating absence as green.
- red checks → route to
Why not the tip. Branch protection enforces its contexts on the pull-request head, which is where the always-run constructions that guarantee a report live. The tip is a different commit, produced by squash, and only receives whatever push-triggered workflows apply to it — so a required check whose push trigger carries a paths: filter is simply absent whenever the merge touched none of those paths. That is the normal case, not an edge one. Reading absence strictly blocks most releases; reading it leniently validates a subset while appearing to validate the set. Neither is a gate.
The tip's tree is still the tree those checks ran against: pull-request-workflow §Branch freshness requires required_status_checks.strict: true, so a pull request can only merge while up to date with develop. If a repository has turned strict off, say so in the report — the substitution's justification does not hold there.
5. Workflow file present
- Confirm
.github/workflows/release-publish.ymlexists in the repo. - Failure: the operator should adopt
release-automationfirst; this skill stops and reports.
4. Disclose the validated state and confirm
Before dispatch, surface to the operator as a single block:
- target tag and
target_commitishSHA; - result of each gate (PASS / FAIL with detail);
- version-bearing-file diff summary (file, current value, target value);
- audience-coverage summary when the draft body carries the
release-skill-layer:project-context-startmarker (Skill A has run); a non-blocking note offering to dispatchrelease-notes-curatefirst when the marker is absent; - the exact
gh workflow runinvocation that will be issued.
Block the dispatch until the operator confirms.
5. Dispatch
On confirmation:
- Run
gh workflow run release-publish.yml --ref develop -f tag=<tag>. Thetaginput is mandatory regardless of how many drafts are open (perrelease-automation§Operational contract — no "newest wins" heuristic in the workflow either). - When the operator opts in to
--dry-run, dispatch with-f dry_run=trueso the workflow validates without flippingdraft: false. - Never call
gh release edit --draft=false,gh api -X PATCH /repos/.../releases/<id>withdraft=false, or any other body that flips the draft state from this skill. The workflow is the only path.
6. Follow the run out of the queue
Immediately after gh workflow run returns:
- Find the new run:
gh run list --workflow=release-publish.yml --limit 1 --json databaseId,status,conclusion,url,headSha. The match is the run whoseheadShaequals the draft's target SHA and whosestatusisqueuedorin_progress. - A landed dispatch isn't the end of the job. While the run is
queuedit can be superseded andcancelledwithout ever starting: GitHub drops a pending run as soon as a newer one queues into the same concurrency group.release-publish.ymlshares therelease-draftgroup withrelease-drafter.yml, which fires on every push todevelop, so every merge opens the window.cancel-in-progress: falsedoesn't help here: it governs only whether an already running run is cancelled. - Re-check
gh run view <id> --json status,conclusionuntil the run leaves the queue, under the same caps as wait mode (interval ≥60 s, default 90 s; wall-clock timeout ≤15 min, default 10 min; max 10 retries; a visible status line per round). Three outcomes:statusisin_progressorcompleted: the run started and can no longer be superseded. Report the run URL and the status. This is the terminal state of the single-shot default.conclusion=cancelledwithout ever starting: the dispatch was superseded. Handle it per the terminal-conclusion branch below.- still
queuedwhen the caps run out: report an unresolved dispatch. Say that the run hasn't started, that it can still be superseded, and give the URL. Never report this as a success.
- The default stays single-shot: leaving the queue is the terminal state, not completion. The operator re-invokes (or opens the URL) once the run finishes.
- Wait mode is the explicit opt-in (via
--waitargument or unambiguous prompt phrasing like "warte bis der Publish durch ist"): keep polling past the queue untilstatus=completedor the timeout, under the same caps. Bound caps mirrorpull-request-merge's wait mode, and a failure short-circuits toworkflow-healthtriage.
On a terminal conclusion (reached in wait mode, or on a later re-invocation):
- On
conclusion=success: confirm with the operator that the release is now published (gh release view <tag> --json isDraftreturns{"isDraft": false}) and thatrelease-cd-refresh-master.ymlhas started a downstream run (gh run list --workflow=release-cd-refresh-master.yml --limit 1); both checks are part ofrelease-automation's acceptance criteria. - On
conclusion=cancelled: the run was superseded, not broken. Report it as such, name the re-dispatch as the next action, and state plainly that the release was not published. Do not route toworkflow-health: there's no red check to triage and it will find nothing. This is the one failure mode where a second dispatch from this skill is allowed. Re-run operation 3 before re-dispatching, because every gate is re-derived from live state anddevelopmay have moved since the first attempt. - On
conclusion=failure: do not retry. Route toworkflow-healthtriage — classify perspec/project/workflow-health/. The most common cause is amerge_failedfrompascalgn/automerge-actionwhenrelease-publish.ymlitself usesautomerge-action; check the run logs formergeResult: 'merge_failed'perpull-request-mergestep 7b and route as a stale-pin incident if so.
Wait mode
Activated by --wait or unambiguous operator phrasing. Caps mirror pull-request-merge:
- Interval ≥ 60 s (default 90 s).
- Wall-clock timeout ≤ 15 min (default 10 min).
- Max retries ≤ 10.
- Visible status line per round.
- Failure short-circuits to
workflow-health.
The single-shot default exists because the prompt-cache TTL is 5 min; unbounded polling burns the cache. Caps balance: short waits stay cache-warm, long waits accept one cache miss but never balloon.
Single-shot by design (not resumable)
Every gate is re-derived from live GitHub state on each run, and the dispatch itself is idempotent to re-validate — a persisted checkpoint per spec/claude/resumable-work/ would only cache staleness. Re-invoking after an interruption simply re-walks the gates; this is the deliberate exception to the plugin's resumable convention, recorded here so reviewers don't flag the absent resumable flag as an omission.
Gotchas
- A queued run can vanish before it runs, and
cancel-in-progress: falsedoesn't protect it.release-publish.ymlshares therelease-draftlane withrelease-drafter.ymldeliberately, and the next merge todevelopsupersedes a still-pending publish. Readreferences/supersession.mdbefore acting on acancelledrun or proposing to split the lane. pascalgn/automerge-action(used by somerelease-publish.ymlimplementations downstream) exits 0 even onmergeResult: 'merge_failed'. A greenrelease-publish.ymlrun is not proof the publish happened. Always re-verifygh release view <tag> --json isDraftafter asuccessconclusion.- The
taginput is mandatory becauserelease-automationforbids the workflow's "newest wins" heuristic. Even when only one draft is open, this skill passes-f tag=<tag>explicitly. - A red required check on
develop's tip blocks publish but is not always recoverable by re-running. The triage path isworkflow-health, not "retry until green." release-cd-refresh-master.ymlshould fire automatically afterrelease-publish.ymlsucceeds. When it doesn't fire (the known-platform-constraint case whererelease: publishedfromGITHUB_TOKENdoesn't cascade to a fresh workflow run, perworkflow-health§Known platform constraints), surface this and route to manual fast-forward ofmainperbranching-model§Release flow.- The skill never runs
gh release edit --draft=falseeven as a fallback — that flag is reserved for incident response and remains a manual operator action documented inrelease-automation§Non-Goals.
Examples
- Read
examples/01-clean-dispatch-all-gates-pass.mdwhen all pre-publish gates pass and the skill dispatches the release workflow cleanly. - Read
examples/02-version-bearing-files-misaligned.mdwhen version-bearing files are out of sync and the gate blocks dispatch. - Read
examples/03-required-checks-red-route-to-workflow-health.mdwhen a required check ondevelop's tip is red and triage routes toworkflow-health. - Read
examples/04-dispatch-superseded-in-queue.mdwhen a dispatched run is cancelled in the queue without publishing, or is still queued when the caps run out.
Hard rules
- Never dispatch when any pre-publish gate fails. Failures route to
workflow-healthtriage. - Never call
gh release edit --draft=false,gh api -X PATCH .../releases/<id>withdraft=false, or any other body that flips the draft state. The workflow is the only publish path. - Never use a
--refother than the default branch (typicallydevelop). - Never poll to completion outside an explicit operator opt-in to wait mode; the single-shot default ends when the run leaves the queue, not when the dispatch lands.
- Never report a landed dispatch, or a run still
queued, as a publish that happened. A dispatch that GitHub accepted can still be superseded and cancelled without publishing anything. - Never route a
cancelledrun toworkflow-health. It's a superseded dispatch, not a workflow defect, and re-dispatching (after re-running the gates) is the remedy. - Never retry a failed
release-publish.ymlrun blindly. Triage classifies the failure first. - Never proceed without explicit operator confirmation of the disclosed validation state.
- When
spec/project/release-skill-layer/orspec/project/release-automation/disagrees with this skill's instructions, the spec wins. Propose updating this skill rather than silently diverging.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

