| name | github-release |
| description | Use when releasing this repository from the CLI by promoting develop to main with a fast-forward push, grading the release as patch/minor/major by what installed projects actually pay, computing the next version from the latest tag, and publishing a GitHub release with agent-written notes. No release PR, no release-drafter. |
GitHub Release
Use this repository skill for release execution.
Release Model
- A release promotes the current
origin/develop to main with a fast-forward push: git push origin develop:main. There is no release PR and no release/* branch.
develop must already contain every intended release change, squash-merged through develop-task-flow.
- The bump is graded against this project's version rubric, not against a rule inside this skill. See Version Rubric.
- The next version is computed from the latest
vX.Y.Z tag using the graded bump type. See Version Format.
- The release tag and GitHub release are created from the CLI with
git tag and gh release create.
- Release notes are written by the agent from the commits in
<previous tag>..<new tag>, categorized by conventional commit prefix.
GitHub Profile
Before any gh command, resolve the host from JIG_GITHUB_HOST, local jig.githubHost, then github.com, and resolve the profile from JIG_GITHUB_PROFILE, then local jig.githubProfile. If a profile is configured, read its credential with gh auth token --hostname <host> --user <profile> without printing it and run every gh command with that credential through GH_TOKEN (github.com or *.ghe.com) or GH_ENTERPRISE_TOKEN (other hosts). Verify gh api user --jq .login matches the profile. Do not use gh auth switch; fall back to the globally active account only when neither the environment nor local config selects a profile.
Version Rubric
The grading rubric is not in this skill. It is a project-owned file, so every project grades by its own axis. The version-rubric skill owns that file.
Resolve the rubric path in this order:
JIG_VERSION_RUBRIC environment variable (session-only override).
git config --local --get jig.versionRubric (repository override).
.jig/versioning.md (the convention).
Apply it like this:
- Grade with the rubric's
## Decision Order: ask its questions in order and stop at the first match. That ordering is fixed; a rubric cannot change it.
- Check the graded bump against the rubric's
## Grade Definitions before computing the version, and quote the deciding question in the report.
- Apply
## Hard Rules after the ordered questions. A rubric without that section has no escalation rule.
- A missing optional section (
## Hard Rules, ## Interface Paths, ## Release Notes, ## Version Format, ## Pre-Release Checks) means that rule does not apply.
- Rubrics written before the contract switched to English carry Korean titles, and they stay valid. Accept either spelling for every section:
## 판정 순서, ## 등급 정의, ## 강경 규칙, ## 인터페이스 경로, ## 릴리즈 노트, ## 버전 형식, ## 릴리즈 전 검증, and > 기준: for > Basis:. Read the file as it is; never retitle it during a release.
- Read sections beyond the contract as grading context; a project may list what counts as its public interface there.
- Report the rubric path, its source, and whether it records the adopted default or a project-specific rubric.
- Never edit the rubric file from this skill.
Recorded Task Grades
develop-task-flow grades each task as it is squash-merged and records the verdict as a Release-Grade trailer. Read those first: they were decided with the diff in hand, which this step no longer has.
git log <previous>..HEAD --no-merges --format='%h %(trailers:key=Release-Grade,valueonly)'
- The release floor is the highest grade recorded in the range, ordered
patch < minor < major. Name the commit that set it in the report.
- Grade any commit with no trailer from its subject and body, then fold that verdict into the floor. A range with no trailers at all grades exactly as it did before.
- The floor is a starting point, not the verdict. Apply the rubric once more to the range as a whole: a combination of tasks can cost more than any one of them did alone, and
## Hard Rules still runs against the composed notes in step 6.
- Never settle the release below the floor. Raising it is a normal outcome; lowering it discards evidence that is no longer available.
Interface Path Floor
When the rubric has an ## Interface Paths table, compute a second floor from the changed paths:
git diff --name-only <previous>..HEAD
- Each changed path takes the floor of the first row it matches; rows are read top to bottom. The path floor is the highest floor any changed path took. A path matching no row contributes nothing.
- Report the floor and the path that set it, so the reader can see which interface the range touched.
- This floor is advisory, unlike a recorded task grade. Paths say what changed, never how. Releasing below it is allowed and must state the reason in the report — for example, that the only change under a public path was a comment. Releasing above it needs no justification.
- A rubric with no such table skips this step entirely; do not invent globs for a project that did not write any.
When the rubric is missing or unusable:
- Missing file: run the
version-rubric skill to settle it, then continue the release. Do not stop the release for this.
version-rubric not installed: grade with the fallback below, say so in the report, and continue.
- Contract broken (neither spelling of the decision-order or grade-definition section is present, or fewer than three ordered questions): stop and point at
version-rubric. Grading with a broken rubric silently is worse than stopping.
The fallback rubric, used only in the two cases above. It matches the default version-rubric writes, so a project grades the same whether or not that skill is installed:
- Is this a fix inside what the project already does? →
patch
- Can people do something new, or did a generation turn over, while everything they already do keeps working? →
minor
- Did the value on offer widen, shrink, or change, or must a human step in to keep using it? →
major
With these escalation rules, applied after the ordered questions:
A change that raises no error but behaves differently is major. Its size does not matter.
A skill or prompt instruction that changes when the agent speaks is at least minor.
Version Format
Defaults, each overridable by the rubric's ## Version Format section:
- The version must match
^v[0-9]+\.[0-9]+\.[0-9]+$.
patch: vX.Y.Z → vX.Y.(Z+1); minor: → vX.(Y+1).0; major: → v(X+1).0.0.
- While the major version is
0, a major grade raises the minor position instead: v0.Y.Z → v0.(Y+1).0. Grade exactly as after 1.0 and state the verdict in the report, so the rule is exercised before it becomes binding.
- An explicit
vX.Y.Z from the user overrides the computed version.
Release Notes
## Changes, then one section per commit type present in the range, each only when it has items, separated by horizontal rules.
- Section titles derive from the commit prefix:
feat → ### 🚀 Enhancements, fix → ### 🐛 Fixes, chore → ### 🧰 Chores. Any other prefix becomes its own section named after it (docs: → ### 📚 Documentation). Never fold an unlisted prefix into chores.
- The rubric's
## Release Notes section overrides section order and titles.
- One
- <commit subject without type prefix> line per commit.
### Summary: user-perspective bullet items written from the commit subjects and bodies, release-note ready, with technical terms in backticks. Write them in the language the repository already uses for its release notes and commit bodies, defaulting to English.
- The
Release-Grade trailer is grading input, not prose. Keep it out of every note section.
### Migration: only when downstream projects must take action that re-running an update does not cover.
Migration Blocks
The ### Migration section is not prose. It is the input an updating agent executes, so it is written as marker-delimited blocks:
### Migration
<!-- jig:start migration-auto -->
- `rm -f .github/workflows/drafter.yaml`
- Move `.agents/skills/github-sync/` to `.agents/skills/jig-github-sync/` when it exists
<!-- jig:end migration-auto -->
<!-- jig:start migration-manual -->
- Decide whether `develop` keeps its required status checks; jig no longer sets them.
<!-- jig:end migration-manual -->
migration-auto: mechanical steps an agent finishes unattended. Every item must be idempotent and be either a single command or an unambiguous file operation. A target that is already absent counts as done.
migration-manual: steps needing a human judgement, a choice, or an irreversible action. jig-update presents these and does not run them without approval.
- When in doubt, an item is
manual. Either block may be omitted; omit the whole section when neither applies.
- A marker counts only when it is the entire line, matching
^<!-- jig:(start|end) migration-(auto|manual) -->$. Release notes routinely name these markers in prose, so a mention inside backticks or mid-sentence is text, not a marker. Keep marker lines flush left with nothing else on them, and always close a block with its matching end marker.
- A rubric may key an escalation rule off these blocks; jig's own rubric grades any
migration-manual block as major. When applying such a rule, count line-anchored markers only.
Safety Rules
- Do not force push.
- Do not bypass git hooks: never pass
--no-verify to git push.
- If
git push origin develop:main would not fast-forward, stop and report that main has commits develop lacks; never resolve this by force-pushing.
- Do not release while the worktree has uncommitted changes to tracked files.
- Do not create a tag that already exists locally or on
origin.
- Do not release while local
develop differs from origin/develop.
- Do not delete branches.
- The release must only promote already-merged
develop state; complete pending work through develop-task-flow first.
- Show the release note draft to the user before publishing, unless the user already asked for the release to be executed end to end.
- Preserve unrelated user changes.
Develop-First Gate
- If the release request includes unfinished implementation, config, docs, generated
dist, or workflow changes, stop release execution.
- Complete those changes first with
develop-task-flow: create a feature/*, fix/*, or chore/* branch from origin/develop, squash-merge it into develop, and push develop.
- Resume release only after
origin/develop contains every intended change.
- If the user has not explicitly asked to release, stop after
develop is pushed.
Release Procedure
- Inspect state:
git status --short --branch
git fetch origin --prune
- verify local
develop matches origin/develop
- Determine the previous version: latest
vX.Y.Z tag reachable from origin/main (git describe --tags --abbrev=0 origin/main).
- Resolve and read the version rubric, then grade the release against it before computing anything. Start from the grades recorded by
develop-task-flow per Recorded Task Grades, read the subjects and bodies of any commit that carries none, compute the path floor per Interface Path Floor when the rubric has that table, and review both floors against the rubric for the range as a whole. Handle a missing, uninstalled, or broken rubric per Version Rubric.
- If the graded bump is higher than the one the user requested, say so with the specific reason and ask before continuing. The user's choice wins if they repeat it; record the graded verdict in the report either way.
- If the graded bump is lower, use the requested one; a user may always release higher than required.
- Verify
origin/develop already contains every intended release change. If not, stop and run the Develop-First Gate.
- Compose the release notes from
git log <previous>..HEAD --no-merges per Release Notes. Do this before promoting or tagging, because the notes can still change the version.
- Re-check the bump against the composed notes when the rubric has a
## Hard Rules section that keys off them, counting line-anchored markers only (grep -cE '^<!-- jig:start migration-manual -->$'; a bare substring search also matches prose that names the marker):
- an opened block with no matching end marker is a defect; fix the notes before publishing
- if the rule raises the grade from step 3, go back to step 3 and resolve it with the user. Never weaken the notes to fit a version.
- Compute the new version from the settled bump type per Version Format, or validate the explicit version. It must not exist as a tag or release.
- Run the repository's pre-release validation: the commands in the rubric's
## Pre-Release Checks section when present, otherwise the validation or test command the repository already uses. Skip and report when there is none.
- Promote:
git push origin develop:main. This must fast-forward; if rejected, stop and report.
- Tag the released commit: then .
Final Report
Keep reports short and include:
- Current repo and branch
- Previous and new version
- Rubric path, source, and kind (adopted default or project-specific)
- Recorded task-grade floor and the commit that set it, or that the range carried no trailers
- Interface path floor and the path that set it, or that the rubric has no
## Interface Paths table; when the release lands below it, the reason
- Graded bump versus the requested bump, with the rubric question that decided it
develop to main promotion result
- Tag and release status
- Release note summary
- Commands that could not run and why
- User next actions, if any