fix(cli): address PR #441 review findings from @dongmucat

- Bind release tag to origin/main: PR body, end-of-run hint, and
  cli/RELEASE.md now use `git tag $TAG origin/main` so the tag is
  always placed on the merged commit, regardless of local branch state
- Reject prerelease tags in version computation: if the latest cli-v*
  tag contains non-X.Y.Z characters (e.g., -rc.1), exit with a clear
  message instead of crashing in node parsing
- Add pr-scripts.yml workflow: runs publish-cli-test.sh on scripts/**
  changes so the release script regression suite gates PRs
- Add Test 11 covering prerelease tag rejection
This commit is contained in:
Cheney 2026-05-19 14:57:16 +08:00
parent efcf0ee19d
commit 7847e0aa33
4 changed files with 49 additions and 6 deletions

19
.github/workflows/pr-scripts.yml vendored Normal file
View file

@ -0,0 +1,19 @@
name: PR Scripts
on:
pull_request:
paths:
- 'scripts/**'
- '.github/workflows/pr-scripts.yml'
jobs:
publish-cli-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: '21'
- run: bash scripts/tests/publish-cli-test.sh

View file

@ -77,11 +77,13 @@ Review and merge the PR on GitHub as usual.
After the PR is merged:
```bash
git pull origin main
git tag cli-vX.Y.Z # replace with the actual version
git fetch origin main
git tag cli-vX.Y.Z origin/main # replace with the actual version
git push origin cli-vX.Y.Z
```
This ensures the tag is always placed on the merge commit on `origin/main`, regardless of your local branch state.
Pushing the tag triggers CI which builds, publishes to npm, and creates a GitHub Release.
### CI Workflow

View file

@ -140,6 +140,13 @@ log_stage "computing next version from latest cli-v* tag"
LATEST_TAG="$(git -C "$REPO_ROOT" tag --list 'cli-v*' --sort=-version:refname | head -n1)"
if [[ -n "$LATEST_TAG" ]]; then
BASE_VERSION="${LATEST_TAG#cli-v}"
# Reject prerelease tags (e.g., cli-v0.2.0-rc.1). Only pure X.Y.Z is supported.
if [[ "$BASE_VERSION" =~ [^0-9.] ]]; then
echo "latest tag $LATEST_TAG contains prerelease suffix: $BASE_VERSION" >&2
echo "this script only supports pure X.Y.Z versions" >&2
echo "skip prerelease tags manually or use a different baseline" >&2
exit 1
fi
log_stage "baseline: $BASE_VERSION (from $LATEST_TAG)"
else
BASE_VERSION="$(PACKAGE_JSON="$PACKAGE_JSON" node -p "require(process.env.PACKAGE_JSON).version")"
@ -251,8 +258,10 @@ Local build-and-test passed (lint, typecheck, test, build).
After merging, tag and push to trigger the release:
\`\`\`bash
git pull origin main
git tag $TAG
git fetch origin main
git checkout main
git merge --ff-only origin/main
git tag $TAG origin/main
git push origin $TAG
\`\`\`
@ -271,7 +280,7 @@ git -C "$REPO_ROOT" branch -D "$RELEASE_BRANCH"
log_stage "done — PR opened. After merge, tag manually:"
echo ""
echo " git pull origin main"
echo " git tag $TAG"
echo " git fetch origin main"
echo " git tag $TAG origin/main"
echo " git push origin $TAG"
echo ""

View file

@ -411,4 +411,17 @@ if [[ -f "$REPO10/gh-stub.log" ]] && grep -F "pr create" "$REPO10/gh-stub.log" >
fail "gh pr create ran despite push failure"
fi
# ----------------------------------------------------------------------------
# Test 11: prerelease tag → abort with clear message
# ----------------------------------------------------------------------------
echo "[test] prerelease tag aborts with message"
REPO11="$(new_tmp)"
init_repo "$REPO11" "0.1.0" "cli-v0.2.0-rc.1"
status="$(run_publish "$REPO11" "patch")"
[[ "$status" -ne 0 ]] || fail "expected non-zero exit for prerelease tag"
grep -F "contains prerelease suffix" "$REPO11/stderr.log" >/dev/null \
|| { cat "$REPO11/stderr.log" >&2; fail "expected prerelease rejection message"; }
grep -F "only supports pure X.Y.Z" "$REPO11/stderr.log" >/dev/null \
|| fail "expected X.Y.Z hint in error"
echo "all tests passed"