forked from mirror/crumbs-original
ci: add automated version bump, tag, and release script
Add scripts/release.sh that infers bump type from conventional commits (major/minor/patch), bumps package.json, commits, tags, and pushes. Includes safety checks for branch, clean tree, and remote sync. Also adds a workflow_dispatch GitHub Actions workflow (bump.yml) and Makefile targets (release, release-patch, release-minor, release-major). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
e93bbda136
commit
46e8b2e529
@@ -0,0 +1,37 @@
|
||||
name: Bump & Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
bump:
|
||||
description: 'Override bump type (leave empty to auto-detect)'
|
||||
required: false
|
||||
type: choice
|
||||
options:
|
||||
- ''
|
||||
- patch
|
||||
- minor
|
||||
- major
|
||||
|
||||
jobs:
|
||||
bump:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Configure git
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
- name: Run release script
|
||||
run: bash scripts/release.sh ${{ github.event.inputs.bump }}
|
||||
@@ -67,6 +67,10 @@ A `Makefile` wraps all common tasks for tool-agnostic usage. Run `make help` to
|
||||
| `make docker-down` | — | Stop containers |
|
||||
| `make docker-logs` | — | Tail container logs |
|
||||
| `make clean` | — | Remove build artifacts + test DBs |
|
||||
| `make release` | — | Auto-bump version from commits, tag, and push |
|
||||
| `make release-patch` | — | Bump patch version, tag, and push |
|
||||
| `make release-minor` | — | Bump minor version, tag, and push |
|
||||
| `make release-major` | — | Bump major version, tag, and push |
|
||||
|
||||
## CI/CD
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
.PHONY: help dev build preview check test test-unit test-e2e lint \
|
||||
db-push db-generate db-migrate db-studio docs-api \
|
||||
install docker-build docker-up docker-down docker-logs clean
|
||||
install docker-build docker-up docker-down docker-logs clean \
|
||||
release release-patch release-minor release-major
|
||||
|
||||
help: ## List all targets
|
||||
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}'
|
||||
@@ -62,3 +63,15 @@ docker-logs: ## Tail container logs
|
||||
clean: ## Remove build artifacts and test DBs
|
||||
rm -rf build .svelte-kit node_modules/.vite
|
||||
rm -f data/test-crumbs.db
|
||||
|
||||
release: ## Auto-bump version from commits, tag, and push
|
||||
bash scripts/release.sh $(BUMP)
|
||||
|
||||
release-patch: ## Bump patch version, tag, and push
|
||||
bash scripts/release.sh patch
|
||||
|
||||
release-minor: ## Bump minor version, tag, and push
|
||||
bash scripts/release.sh minor
|
||||
|
||||
release-major: ## Bump major version, tag, and push
|
||||
bash scripts/release.sh major
|
||||
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Automate version bump, tag, and push based on conventional commits.
|
||||
# Usage: bash scripts/release.sh [patch|minor|major]
|
||||
# If no argument is given, the bump type is inferred from commits since the last tag.
|
||||
|
||||
BUMP="${1:-}"
|
||||
|
||||
# --- Safety checks ---
|
||||
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
if [[ "$BRANCH" != "main" ]]; then
|
||||
echo "Error: must be on the main branch (currently on '$BRANCH')" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -n "$(git status --porcelain)" ]]; then
|
||||
echo "Error: working tree is not clean" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git fetch origin main --tags --quiet
|
||||
LOCAL=$(git rev-parse HEAD)
|
||||
REMOTE=$(git rev-parse origin/main)
|
||||
if [[ "$LOCAL" != "$REMOTE" ]]; then
|
||||
echo "Error: local main is not in sync with origin/main" >&2
|
||||
echo " local: $LOCAL" >&2
|
||||
echo " remote: $REMOTE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Bump type inference ---
|
||||
|
||||
if [[ -z "$BUMP" ]]; then
|
||||
LAST_TAG=$(git describe --tags --abbrev=0 --match 'v*' 2>/dev/null || echo "")
|
||||
if [[ -z "$LAST_TAG" ]]; then
|
||||
echo "No previous v* tag found, defaulting to patch"
|
||||
BUMP="patch"
|
||||
else
|
||||
COMMITS=$(git log "$LAST_TAG"..HEAD --pretty=format:'%s%n%b')
|
||||
if echo "$COMMITS" | grep -qiE 'BREAKING CHANGE:|^[a-z]+(\(.*\))?!:'; then
|
||||
BUMP="major"
|
||||
elif echo "$COMMITS" | grep -qE '^feat(\(.*\))?:'; then
|
||||
BUMP="minor"
|
||||
else
|
||||
BUMP="patch"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$BUMP" != "patch" && "$BUMP" != "minor" && "$BUMP" != "major" ]]; then
|
||||
echo "Error: invalid bump type '$BUMP' (must be patch, minor, or major)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Bump, tag, push ---
|
||||
|
||||
echo "Bumping $BUMP version..."
|
||||
npm version "$BUMP" -m "chore: bump version to %s" --no-git-tag-version
|
||||
|
||||
NEW_VERSION=$(node -p "require('./package.json').version")
|
||||
git add package.json
|
||||
git commit -m "chore: bump version to $NEW_VERSION"
|
||||
git tag "v$NEW_VERSION"
|
||||
|
||||
echo "Pushing to origin..."
|
||||
git push origin main --tags
|
||||
|
||||
echo ""
|
||||
echo "Released v$NEW_VERSION ($BUMP bump)"
|
||||
echo "GitHub Actions release workflow will handle the rest."
|
||||
Reference in New Issue
Block a user