From e40bdd8b6b2f36040ff3cb0bdc692270c24aea5d Mon Sep 17 00:00:00 2001 From: Meryl Dakin Date: Wed, 11 Mar 2026 10:40:14 -0400 Subject: [PATCH] feat(ci): add release version validation to prevent mismatched releases - Add validate-release job that compares git tag to package.json version - Block publish-brew and publish-npm if versions don't match - Provide clear error message with remediation steps - Add Claude skill for guided release process --- .claude/skills/release-cli/SKILL.md | 54 ++++++++++++++++++++++++ .github/workflows/on-release-created.yml | 23 ++++++++++ 2 files changed, 77 insertions(+) create mode 100644 .claude/skills/release-cli/SKILL.md diff --git a/.claude/skills/release-cli/SKILL.md b/.claude/skills/release-cli/SKILL.md new file mode 100644 index 00000000..df9abdc9 --- /dev/null +++ b/.claude/skills/release-cli/SKILL.md @@ -0,0 +1,54 @@ +--- +name: release-cli +description: Prep a knock-cli release. Use when the user asks to prepare, create, + or cut a release, or bump the version. +argument-hint: [version] +--- + +# Knock CLI Release Prep + +Prepare a new CLI release by bumping the version, creating the tag, and opening a PR. + +## Instructions + +If no version is provided, ask the user what version to release. Check the current +version in package.json to help them decide (patch, minor, or major bump). + +Execute these steps: + +1. **Check prerequisites** + - Run `git status` to ensure working directory is clean + - Run `git checkout main && git pull` to ensure you're on latest main + - Show current version: `node -p "require('./package.json').version"` + +2. **Create release branch** + ```bash + git checkout -b release-v{version} + ``` + +3. **Build and bump version** + ```bash + yarn build && yarn version --new-version {version} + ``` + This updates package.json and creates the git tag automatically. + +4. **Push branch and tag** + ```bash + git push origin release-v{version} + git push origin v{version} + ``` + +5. **Create PR** + Create a PR with title "v{version}" targeting main. The PR body should note + this is a release version bump. + +6. **Provide next steps** + Tell the user: + - Merge the PR once approved + - Then run in Slack: `/release cut knock-cli -v {version}` + +## Important + +- The git tag MUST match the version in package.json exactly +- `yarn version` creates both the package.json change AND the git tag +- The release pipeline validates this match and will fail if they don't match diff --git a/.github/workflows/on-release-created.yml b/.github/workflows/on-release-created.yml index 8c03d365..ca03c8b9 100644 --- a/.github/workflows/on-release-created.yml +++ b/.github/workflows/on-release-created.yml @@ -3,7 +3,30 @@ on: release: types: [created] jobs: + validate-release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Validate version match + run: | + TAG_VERSION="${GITHUB_REF_NAME#v}" + PACKAGE_VERSION=$(node -p "require('./package.json').version") + + if [ "${TAG_VERSION}" != "${PACKAGE_VERSION}" ]; then + echo "::error::Version mismatch! Git tag (v${TAG_VERSION}) does not match package.json (${PACKAGE_VERSION})" + echo "" + echo "To fix:" + echo " 1. Delete this release: gh release delete ${GITHUB_REF_NAME}" + echo " 2. Delete the tag: git push --delete origin ${GITHUB_REF_NAME}" + echo " 3. Run 'yarn version' with the correct version" + echo " 4. Push the tag and re-cut the release" + exit 1 + fi + echo "Version validated: ${TAG_VERSION}" + publish-brew: + needs: [validate-release] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3