agentsclimarketplace

Grav release

Skill getgrav/grav-skills/skills/grav-release

Use when cutting a release of a Grav plugin (Team Grav / Trilby Media, e.g. `grav-plugin-*`) or Grav core itself. Covers the two release shapes — full git-flow when the work is on `develop`, and tag-only when the work is on a dedicated release branch (like flex-objects `1.4.0` or an older Grav maintenance line like `1.7`) — plus the prerelease decision (`testing: true` in blueprints, or an `-rc.`/`-beta.` version, or Grav core's `system/defines.php`), the bare-numeric tag/title rule (never `v`-prefixed), sourcing release notes from the top CHANGELOG block, and post-release verification. Trigger when the user says "release <plugin>", "cut a release", "tag and release", "get <plugin> out", "do a prerelease", or asks to run a git-flow release / `gh release` for a Grav plugin or Grav core.From its SKILL.md

Install
npx -y skills add getgrav/grav-skills --skill grav-release

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

9.1 KB, as published. Nobody here has run it

Releasing a Grav plugin (or Grav core)

Cut a release of a Grav plugin or Grav core the way Andy does it. There are two shapes, decided by which branch the release work sits on. The version is already set in blueprints.yaml and the CHANGELOG.md before you start — your job is to verify it, tag it, and publish, not to invent a version.

Releases always happen in the source repo (~/Projects/grav/grav-plugin-<name> or the Grav core repo), never in a symlinked site copy under user/plugins/.

The one rule that bites: bare numeric, never v

Tags and release titles are bare numeric: 3.4.5, 2.0.0-rc.1, 1.4.0-rc.8. Never v-prefixed. This applies to all three of:

  1. the git tag — git tag 3.4.5
  2. the gh release create <tag> argument — gh release create 3.4.5
  3. the --title — --title "3.4.5", NOT --title "v3.4.5"

A single v-prefixed tag/release breaks git tag --sort=-v:refname and GitHub's releases/latest, so GPM and the gpm CLI stop seeing it as latest. CHANGELOG headings like # v3.4.5 are fine — that's just doc text. Only the tag, the release tag arg, and the title must be bare.

Step 0 — preflight (always)

From inside the source repo:

cd ~/Projects/grav/grav-plugin-<name>
git branch --show-current          # which branch? decides the shape (see below)
git status --short                 # MUST be clean (or only the release-prep edits)
grep -E '^version' blueprints.yaml # the version being released
head -3 CHANGELOG.md               # top heading must match that version
git tag | grep -x <version>        # MUST be absent — tag must not already exist
git rev-parse --abbrev-ref @{u} 2>/dev/null && git log --oneline @{u}..HEAD  # unpushed commits?
gh auth status                     # logged in, correct account
git remote -v                      # confirm the repo (trilbymedia/* or getgrav/*)

Checklist before proceeding:

  • Working tree clean. If the version bump / changelog aren't committed yet and it's a git-flow release, you'll commit them on the release branch (Path A). For tag-only (Path B) they should already be committed and pushed.
  • blueprints.yaml version: == top CHANGELOG.md heading. They should already agree. If they don't, stop and ask — don't guess which is right.
  • CHANGELOG date is today. The ## MM/DD/YYYY line under the top heading should be today's date, not whenever the block was first drafted. Fix it if stale.
  • Tag does not already exist.
  • Never invent a version. The version is whatever blueprints/changelog already say (typically last tag + 1). Don't bump it yourself per the changelog rules.

Decide the shape

  • On develop? → Path A: git-flow. (standard stable plugins: tntsearch, etc.)
  • On a dedicated release branch (e.g. flex-objects 1.4.0, an older Grav maintenance line like 1.7)? → Path B: tag-only. No merges. (Grav core's current 2.0.x stable is the exception — it's git-flow on master; see Grav core specifics.)

Decide prerelease vs full release

Mark the GitHub release as --prerelease if any of:

  • blueprints.yaml has testing: true
  • the version contains -rc. or -beta. (e.g. 1.4.0-rc.8, 2.0.0-beta.5)
  • Grav core: the GRAV_VERSION in system/defines.php is an rc/beta (core has no blueprints.yaml)

Otherwise it's a normal (latest) release — omit --prerelease.

Commit rules

Per Andy's global git rules: never add Co-Authored-By: or any AI-assistant coauthor trailer. Commits are solely his.


Path A — git-flow (work is on develop)

The version-prep edits (code fix, blueprints.yaml bump, CHANGELOG.md block) may be uncommitted on develop or already committed. This produces the canonical graph: a release/X.Y.Z branch merged --no-ff into master, tagged there, then the tag merged back into develop.

cd ~/Projects/grav/grav-plugin-<name>

# carries any uncommitted release-prep edits onto the release branch
git checkout -b release/<version>
git add -A
git commit -m "<short description of the release changes>"   # e.g. "PHP 8.4 deprecations"

# merge into master and tag THERE (master holds the stable line)
git checkout master
git merge --no-ff release/<version> -m "Merge branch 'release/<version>'"
git tag <version>

# back-merge the tag into develop so develop carries the release commit
git checkout develop
git merge --no-ff <version> -m "Merge tag '<version>' into develop"
git branch -d release/<version>

# push everything
git push origin master develop
git push origin <version>

Merge-commit message style matches existing history: Merge branch 'release/X.Y.Z' and Merge tag 'X.Y.Z' into develop.

Then create the GitHub release (Path A/B share this — see "Create the GitHub release").


Path B — tag-only (work is on a release branch like 1.4.0 / 1.7)

These lines (e.g. flex-objects 1.4.0, an older Grav maintenance line like 1.7) are not git-flow. The branch is the release line. The changelog + version are already committed and the branch is already pushed. You just tag the branch HEAD and publish — no master/develop merges.

cd ~/Projects/grav/grav-plugin-<name>     # or the Grav core repo
git status --short                         # clean
git log --oneline @{u}..HEAD               # should be empty — branch already pushed
git tag <version>                          # e.g. 1.4.0-rc.8
git push origin <version>

Then create the GitHub release with --target <branch> (the release branch name).


Create the GitHub release (both paths)

Release notes come from the top block of CHANGELOG.md (the block for this version). Convert its bullets into the release body, grouped by #new / #improved / #bugfix.

gh release create <version> \
  --repo <org>/grav-plugin-<name> \
  --title "<version>" \              # bare numeric — NO v
  --target <branch> \               # master for Path A (incl. Grav core 2.0.x); the release branch (1.4.0 / 1.7) for Path B
  [--prerelease] \                  # include per the prerelease decision above
  --notes "### New
- ...

### Bugfix
- ..."

--target matters: Path A targets master; Path B targets the release branch.

Verify after

gh release view <version> --repo <org>/grav-plugin-<name> \
  --json tagName,name,isPrerelease,isDraft,targetCommitish

Confirm: name is bare numeric, isDraft:false, and isPrerelease matches the decision. For git-flow, also confirm the graph: master at Merge branch 'release/X.Y.Z' (tagged), develop at Merge tag 'X.Y.Z' into develop.

Grav core specifics

  • Version lives in system/defines.php as GRAV_VERSION, not blueprints.yaml.
  • The current stable line (2.0.x) ships git-flow on master — Path A, exactly like a plugin (release branch off develop → merge --no-ff into master → tag there → back-merge the tag into develop). Confirm by checking how the previous tag was cut: git log --oneline master..develop shows the prior Merge branch 'release/X' / Merge tag 'X' into develop pair when it's git-flow.
  • 2.0 is NOT the release branch — it's the old beta/rc channel branch and now sits stale, well behind develop. Ignore it for 2.0.x stable releases; target master.
  • Older maintenance lines release Path B (tag-only) from their own line branch. "Release 1.7" means tag the HEAD of the 1.7 branch and publish with --target 1.7 — no master/develop merges. The branch name matches the line (1.7, 1.6, …).
  • Prerelease is decided by whether GRAV_VERSION is an rc/beta.
  • A plugin can depend on a specific core version (its blueprints.yaml dependencies/grav: constraint) — if a plugin RC needs an unreleased core RC, the core has to ship first or the dependency won't resolve in GPM.

Notes / gotchas

  • The plugin under user/plugins/<name> in a test site may be a symlink to the source repo (release there) or a GPM-installed copy (read-only — not releasable; find its real repo under ~/Projects/grav/).
  • A prerelease never becomes GPM/GitHub "latest" — that's the point of --prerelease for the -rc./-beta./testing:true lines, so it stays off the ?stable=1 feed.
  • If git push is blocked by the sandbox, retry the push with the sandbox disabled — pushing is an explicitly authorized step of a release.

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.