Skip to content

feat(release): sync plugin version via VERSION + auto tag & GitHub Release on merge#16

Closed
mattmaynes wants to merge 2 commits into
mainfrom
versioning
Closed

feat(release): sync plugin version via VERSION + auto tag & GitHub Release on merge#16
mattmaynes wants to merge 2 commits into
mainfrom
versioning

Conversation

@mattmaynes

Copy link
Copy Markdown
Collaborator

Implements spec/plan 0007 — Plugin versioning & releases.

What & why

The plugin version was hardcoded 0.1.0 in seven manifests with no tag, no release, and no sync. Because each agent gates update detection on the manifest version string, installed users are frozen until that string moves. This stands up one enforced version + an automated, tag-marked release.

Changes

  • VERSION (root) — single source of truth (0.1.0).
  • scripts/bump-version.shX.Y.Z propagates to all 7 manifests (semver, no v); --check enforces agreement; SPECTRA_ROOT override for sandboxed tests. Format-preserving surgical substitution (one version token per file), no JSON reflow.
  • .github/workflows/ci.yml — new release job: push: main only, needs: [test, readme-drift], job-scoped contents: write (workflow stays contents: read). Idempotent gh release view guard → gh release create "$VERSION" --target "$GITHUB_SHA" --generate-notes (mints the bare-semver tag + Release + notes in one call).
  • test.sh — step 10: --check invariant, semver reject cases, and a SPECTRA_ROOT sandbox write.
  • Identity — marketplace owner + plugin authorrogueoak (post-transfer; personal name/email dropped).
  • DocsAGENTS.md "Releasing" (outside the spectra block) + docs/overview/ (features, architecture).

Decisions

  • Inaugural release is 0.1.0 (tag what's effectively shipping; bump on next change).
  • The tag is a bare semver (no v prefix); the changelog is the auto-generated Release notes from Conventional Commit titles — no CHANGELOG.md.
  • The manifest version is the real update signal; the tag is the durable marker — both wired to the same x.y.z.

Verification

  • ./test.shPASS (incl. new step 10).
  • scripts/token-report.sh --check, scripts/bump-version.sh --check → exit 0.
  • All 7 manifests parse; ci.yml validated as YAML.
  • Nothing under spectra/ changed except the author field; README token figures unaffected.

🤖 Generated with Claude Code

…lease on merge

Stand up plugin versioning and an automated release path (spec/plan 0007).

- VERSION (root) is the single source of truth; scripts/bump-version.sh
  propagates it to all seven manifests (semver, no 'v'), and --check enforces
  they agree (wired into test.sh step 10 and CI).
- CI gains a job-scoped contents:write 'release' job: on push to main, after
  the gates pass, it tags the bare-semver x.y.z and publishes a GitHub Release
  with notes generated from the Conventional Commit titles since the last tag.
  Idempotent via 'gh release view' — a no-bump push releases nothing.
- Post-transfer identity: marketplace owner and plugin author are now rogueoak.
- Reflected in AGENTS.md (Releasing) and docs/overview (features, architecture).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread test.sh
Comment thread test.sh
Comment thread .github/workflows/ci.yml Outdated
Comment thread scripts/bump-version.sh
Comment thread .github/workflows/ci.yml
Comment thread scripts/bump-version.sh Outdated
Comment thread scripts/bump-version.sh Outdated
Comment thread .github/workflows/ci.yml Outdated
Address the engineer/tester/architect/security findings on PR #16:

- bump-version.sh write() is now atomic: all 7 manifest substitutions are
  computed + validated in memory and applied only if all pass, with VERSION
  written last — a guard failure leaves nothing changed on disk (engineer major).
- --check case uses explicit if/else, not `check; exit $?` dead code (engineer).
- release job: validate VERSION is semver before handing it to gh (argument-
  injection defense, security), distinguish a real 404 from a transient/auth
  failure before publishing (engineer), and run under a non-cancelable
  job-scoped concurrency group so a release can't be aborted mid-flight (architect).
- test.sh step 10: add the negative drift case (--check must fail on drift),
  a format-preservation assertion (bump changes only the version line, no
  reflow), and no-arg/--help coverage (tester).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mattmaynes

Copy link
Copy Markdown
Collaborator Author

Closing as superseded. This branch is stale (CONFLICTING, predates the 1.0.0/1.0.1/1.0.2 releases and the whats-new.yml workflow, and still proposes 0.1.0 as the inaugural tag), so rather than rebasing we'll re-implement plan 0007 fresh on current main and reconcile the release job with whats-new.yml.

The intent is still valid and overdue: main has none of this branch's deliverables (VERSION source of truth, bump-version.sh + --check, auto-release on merge, identity -> rogueoak). The absence just caused real drift - two marketplace manifests were stranded at 0.1.1 across three releases - fixed immediately in #27. The durable --check guard from plan 0007 is what prevents a recurrence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant