mirror of
https://github.com/gorazenxu/pimate.git
synced 2026-07-22 07:32:35 +00:00
92 lines
3.1 KiB
Bash
92 lines
3.1 KiB
Bash
#!/bin/bash
|
|
# 2-push release workflow. Use: ./release.sh
|
|
#
|
|
# NOTE: We force C.UTF-8 locale inline because Git for Windows' alias
|
|
# shell runs with an empty locale, which makes grep treat the file
|
|
# as Latin-1 and silently fail to match the 🛠 emoji in CHANGELOG.
|
|
#
|
|
# What it does:
|
|
# 1. Verifies the working tree is clean AND CHANGELOG Working section is empty.
|
|
# 2. Bumps version (npm version patch), commits the version bump.
|
|
# 3. Pushes main (1).
|
|
# 4. Tags the bump commit and pushes the tag (2).
|
|
#
|
|
# If you need to amend (CHANGELOG typo, etc.) after step 4:
|
|
# git commit --amend --no-edit
|
|
# git tag -d 1.0.xx
|
|
# git push origin :refs/tags/1.0.xx
|
|
# git tag 1.0.xx
|
|
# git push origin 1.0.xx
|
|
set -e
|
|
|
|
# Make sure we're in the repo root regardless of how the script was invoked
|
|
cd "$(git rev-parse --show-toplevel)"
|
|
|
|
if [ -n "$(git status --porcelain)" ]; then
|
|
echo "ERROR: working tree is dirty. Commit/stash first."
|
|
git status --short
|
|
exit 1
|
|
fi
|
|
|
|
# Find the line of the actual `## ... Working / Uncommitted ...` heading
|
|
# (line 13 in CHANGELOG, after the preamble bullets).
|
|
if ! grep -qE "^## .*Working / Uncommitted" CHANGELOG.md; then
|
|
echo "ERROR: CHANGELOG missing the Working section heading."
|
|
exit 1
|
|
fi
|
|
|
|
# Take everything after the first Working heading and look for a non-empty
|
|
# line before the next '## ...' heading. If found, the Working section
|
|
# still has un-released items.
|
|
WORKING_HAS_ITEMS=$(awk '
|
|
/^## .*Working \/ Uncommitted/ { in_working=1; next }
|
|
in_working && /^## / { exit }
|
|
in_working && NF { print; exit }
|
|
' CHANGELOG.md)
|
|
if [ -n "$WORKING_HAS_ITEMS" ] && ! echo "$WORKING_HAS_ITEMS" | grep -q "_当前没有未提交的修改"; then
|
|
echo "ERROR: CHANGELOG Working section still has items."
|
|
echo "Move them under a \"## 📦 vX.Y.Z\" heading first."
|
|
echo "First item: $WORKING_HAS_ITEMS"
|
|
exit 1
|
|
fi
|
|
|
|
# Compute the version that will be released (= current version + 1 patch).
|
|
# The script's job is to bump and release, so the only thing that matters
|
|
# is whether the *next* version's tag already exists.
|
|
CUR_VER=$(node -p "require('./package.json').version")
|
|
NEXT_VER=$(node -e "
|
|
const [a,b,c] = '$CUR_VER'.split('.').map(Number);
|
|
console.log(\`\${a}.\${b}.\${c+1}\`);
|
|
")
|
|
|
|
if git rev-parse "$NEXT_VER" >/dev/null 2>&1; then
|
|
echo "ERROR: tag $NEXT_VER already exists locally (current package.json is $CUR_VER)."
|
|
echo "Either delete the tag and re-run, or update CHANGELOG with a new section."
|
|
git rev-parse "$NEXT_VER"
|
|
exit 1
|
|
fi
|
|
|
|
VER="$NEXT_VER"
|
|
|
|
ORIGIN_SHA=$(git rev-parse origin/main 2>/dev/null || echo "no-origin-main")
|
|
LOCAL_SHA=$(git rev-parse HEAD)
|
|
if [ "$ORIGIN_SHA" != "no-origin-main" ] && [ "$ORIGIN_SHA" != "$LOCAL_SHA" ]; then
|
|
echo "ERROR: origin/main ($ORIGIN_SHA) is not at HEAD ($LOCAL_SHA). Pull/rebase first."
|
|
exit 1
|
|
fi
|
|
|
|
echo "== Releasing v$VER =="
|
|
echo "Step 1/3: bump version + commit"
|
|
npm version patch --no-git-tag-version
|
|
npm run version
|
|
git add manifest.json package.json package-lock.json versions.json
|
|
git commit -m "Bump to v$VER"
|
|
|
|
echo "Step 2/3: push main"
|
|
git push origin main
|
|
|
|
echo "Step 3/3: push tag"
|
|
git tag "$VER"
|
|
git push origin "$VER"
|
|
|
|
echo "== Done. v$VER published. =="
|