Skip to content

Release tooling: CI tagging, single-source VERSION, CI tests, latest selector - #21

Merged
hubertp merged 5 commits into
mainfrom
hubert/selector-latest
Oct 6, 2026
Merged

hubertp merged 5 commits into
mainfrom
hubert/selector-latest

Conversation

@hubertp

@hubertp hubertp commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

release=latest in the installer selector

  • The shared assets' playoffs/install.sh (in modiqo/rote-releases) may hold release=latest or a pinned tag/SHA. Every deploy replaces it with the deployed tag (production) or SHA (staging); the deployed selector must show a concrete reference.

Release scripts moved to .github/release/

  • publish-play, publish_play.py, tag_play.py move out of scripts/release/ and out of the plugin payload; workflow, justfile, and docs point at the new path.

CI tags releases (.github/workflows/tag-release.yml)

  • Runs on every push to main and tags the pushed commit when its VERSION has no tag yet. A merge that keeps VERSION reports version_unchanged; a tag on an unrelated commit fails and is never moved.
  • Removes the release-check, release-tag, and release-tag-check just recipes.

VERSION is the only file to bump

  • just package writes VERSION into the four plugin manifests, plugins/play/package.json, pyproject.toml, and uv.lock; just package-check (so just check) fails while any disagree.
  • The search User-Agent reads VERSION at runtime; tests read VERSION instead of hardcoding it; the README pin example uses vX.Y.Z.

CI runs just test on PRs and pushes to main (.github/workflows/ci.yml)

  • just test runs just check first. Five tests that relied on the developer machine (Codex on PATH, a display, a rote skill in ~/.claude) now set that up themselves.

Notes

  • The tag job needs contents: write; a future admin-only v* tag ruleset must allow GitHub Actions.
  • To make CI block merges, add the test check to the main ruleset.
  • Switching rote-releases to release=latest should follow this merge.

Test plan

  • Selector: latest and pinned inputs become the given tag/SHA; strict rejections hold
  • Tagging in a scratch repo with a bare remote: tagged, already_tagged, version_unchanged, refusal on an unrelated tag
  • Simulated bump to 0.4.106: package-check lists all 7 stale copies; just package fixes them; uv lock --check passes
  • just test passes locally and in a clean ubuntu:24.04 container
  • CI test job passes on this PR
  • After merge: tag job reports version_unchanged; staging deploy succeeds

What changed

- Accept `release=latest` in the shared assets' playoffs/install.sh,
  alongside a pinned tag or commit.

- Keep the deployed selector strict: each deploy writes the tag or
  commit SHA, and verification rejects a public selector still at latest.

Why

The shared assets no longer need a commit for every Play release just to
keep a parseable pinned value; each deploy supplies the real reference.

How to verify

1. Run pyright on scripts/release and `just package-check`.

2. Feed replace_selector a selector with `release=latest`; expect only
   that line to become the given tag or SHA.
What changed

- Move publish-play, publish_play.py, and tag_play.py from
  scripts/release to .github/release.

- Point the deploy workflow, justfile recipes, and docs at the new path.

- Stop shipping the release scripts in the plugin payload.

Why

The scripts only serve CI deployment and maintainer tagging, so they
belong with the workflow rather than in the installed skill.

How to verify

1. Run `just package-check` and `just release-tag-check`.

2. Run `just release-check` from a clean checkout of main.
What changed

- Add a Tag Play release workflow that runs on every push to main and
  tags the pushed commit when its VERSION has no tag yet.

- Report `version_unchanged` when the version's tag already sits on an
  earlier main commit, so merges without a bump succeed without tagging.

- Remove the release-check, release-tag, and release-tag-check recipes.

- Document the CI tagging outcomes and the direct publish-play check.

Why

Merging a version bump should produce its tag without a maintainer
remembering to run a local command.

How to verify

1. Merge a PR that keeps VERSION; expect `version_unchanged`.

2. Merge a version bump; expect `tagged` and a pushed vX.Y.Z tag.
What changed

- Have `just package` write VERSION into the plugin manifests,
  plugins/play/package.json, pyproject.toml, and uv.lock.

- Fail `just package-check` (and so `just check`) when any of them
  disagrees with VERSION.

- Build the search User-Agent from VERSION at runtime.

- Read VERSION in the bootstrap and install tests instead of
  hardcoding the release.

- Show a vX.Y.Z placeholder in the README's pinned-install example.

Why

A release bump touched 16 files by hand, and a missed manifest or test
string went unnoticed. Now a bump edits VERSION and runs `just package`.

How to verify

1. Set VERSION to a new x.y.z and run `just package-check`; expect each
   stale copy listed.

2. Run `just package`, then `just test`; expect a clean check and pass.
What changed

- Add a CI workflow that installs Node, uv, just, and typos, then runs
  `just test`, which runs `just check` first.

- Make Codex detectable in the bootstrap apply tests with a fake
  executable on PATH instead of the machine's installed Codex.

- Set DISPLAY in the guided-install tests that expect headed sign-in.

- Give the preflight readiness test a temporary home with a rote skill.

Why

Nothing checked PRs before merge. On a clean runner, five tests failed
because they read the developer's installed harnesses, display, and
skills rather than setting them up.

How to verify

1. Run `just test` locally; expect a pass.

2. Run the suite with an empty HOME, no DISPLAY, and a minimal PATH;
   expect the same pass.
@hubertp hubertp changed the title feat(deploy): accept release=latest in the installer selector; move release scripts to .github Release tooling: CI tagging, single-source VERSION, CI tests, latest selector Oct 2, 2026
@hubertp
hubertp merged commit 22f31a1 into main Oct 6, 2026
2 checks passed
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.

2 participants