From 13f43ebc4749ba71fceedb4f76a1ce02d4ac2fdc Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 14 Mar 2026 21:35:47 +0000 Subject: [PATCH 1/2] Add release script, workflow, and versioning docs - Create scripts/release.sh to tag semver + floating major tags - Add .github/workflows/release.yml to auto-create GitHub Releases - Document versioning convention and breaking change policy in CLAUDE.md https://claude.ai/code/session_015h9iYcSULNLdxvk8aZ8v3g --- .github/workflows/release.yml | 22 +++++++++++++++ CLAUDE.md | 35 ++++++++++++++++++++++++ scripts/release.sh | 51 +++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 .github/workflows/release.yml create mode 100755 scripts/release.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..b821405 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,22 @@ +name: Release + +on: + push: + tags: + - "v*.*.*" + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.ref_name }} + generate_release_notes: true diff --git a/CLAUDE.md b/CLAUDE.md index c5ff692..ba23865 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -65,6 +65,41 @@ not just this one. Every change we make must account for the experience of those - **Discuss trade-offs**: if a feature requires consumers to make non-trivial changes (new secrets, new workflow jobs, new permissions), flag it in the PR for a deliberate decision. +## Versioning & Releases + +We follow the standard GitHub Actions versioning convention using semantic versioning tags +alongside floating major tags. + +- **Semantic tags** (`v1.0.0`, `v1.2.3`) are immutable and mark exact releases. +- **Floating major tags** (`v1`, `v2`) always point to the latest non-breaking release + in that major line. Consumers use `uses: DeDuckProject/git-glimpse@v1` to stay on the + latest compatible version. +- Only cut `v2` (bump the major version) for **breaking changes**. + +### What counts as a breaking change + +- Removing or renaming an existing action input or output +- Changing the default behavior of an existing input in a way that alters results +- Requiring a new permission, secret, or workflow event that consumers must add +- Dropping support for a previously supported runner OS or Node version + +### How to release + +```bash +./scripts/release.sh # e.g. ./scripts/release.sh 1.0.0 +``` + +The script will: +1. Create the immutable tag `v` +2. Force-move the floating major tag (`v1`, `v2`, etc.) to the same commit +3. Push both tags to origin + +A GitHub Actions workflow (`.github/workflows/release.yml`) automatically creates a +GitHub Release with auto-generated release notes when a `v*.*.*` tag is pushed. + +**Important:** Never push a release without updating both the semantic and floating tags. +The release script handles this automatically — always use it instead of manual tagging. + ## Branching Convention - Features: `feat/` diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 0000000..1811616 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [ $# -ne 1 ]; then + echo "Usage: $0 " + echo "Example: $0 1.0.0" + exit 1 +fi + +VERSION="$1" + +# Strip leading 'v' if provided +VERSION="${VERSION#v}" + +# Validate semver format +if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Error: '$VERSION' is not a valid semantic version (expected X.Y.Z)" + exit 1 +fi + +MAJOR="${VERSION%%.*}" +TAG="v${VERSION}" +MAJOR_TAG="v${MAJOR}" + +# Ensure we're on a clean working tree +if [ -n "$(git status --porcelain)" ]; then + echo "Error: working tree is not clean. Commit or stash changes first." + exit 1 +fi + +# Create the immutable semver tag +if git rev-parse "$TAG" >/dev/null 2>&1; then + echo "Error: tag '$TAG' already exists. Semver tags are immutable." + exit 1 +fi + +git tag "$TAG" +echo "Created tag $TAG" + +# Force-move the floating major tag +git tag -f "$MAJOR_TAG" +echo "Moved tag $MAJOR_TAG -> $(git rev-parse --short HEAD)" + +# Push both tags +git push origin "$TAG" +git push origin "$MAJOR_TAG" --force + +echo "" +echo "Release complete:" +echo " $TAG (immutable semver tag)" +echo " $MAJOR_TAG (floating major tag, force-updated)" From 1ad9278b02724de57a3784d7826ba7dfbb462eea Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 14 Mar 2026 21:38:48 +0000 Subject: [PATCH 2/2] Trim versioning section in CLAUDE.md to repo-specific essentials https://claude.ai/code/session_015h9iYcSULNLdxvk8aZ8v3g --- CLAUDE.md | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index ba23865..9d5e6cb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -67,38 +67,16 @@ not just this one. Every change we make must account for the experience of those ## Versioning & Releases -We follow the standard GitHub Actions versioning convention using semantic versioning tags -alongside floating major tags. +We use semver tags (`v1.0.0`) alongside a floating major tag (`v1`) — consumers pin to `@v1`. +Only bump the major version for breaking changes (e.g. removed/renamed inputs, new required secrets). -- **Semantic tags** (`v1.0.0`, `v1.2.3`) are immutable and mark exact releases. -- **Floating major tags** (`v1`, `v2`) always point to the latest non-breaking release - in that major line. Consumers use `uses: DeDuckProject/git-glimpse@v1` to stay on the - latest compatible version. -- Only cut `v2` (bump the major version) for **breaking changes**. - -### What counts as a breaking change - -- Removing or renaming an existing action input or output -- Changing the default behavior of an existing input in a way that alters results -- Requiring a new permission, secret, or workflow event that consumers must add -- Dropping support for a previously supported runner OS or Node version - -### How to release +To release: ```bash -./scripts/release.sh # e.g. ./scripts/release.sh 1.0.0 +./scripts/release.sh 1.0.0 ``` -The script will: -1. Create the immutable tag `v` -2. Force-move the floating major tag (`v1`, `v2`, etc.) to the same commit -3. Push both tags to origin - -A GitHub Actions workflow (`.github/workflows/release.yml`) automatically creates a -GitHub Release with auto-generated release notes when a `v*.*.*` tag is pushed. - -**Important:** Never push a release without updating both the semantic and floating tags. -The release script handles this automatically — always use it instead of manual tagging. +Always use the script — it handles both tags atomically. Never tag manually. ## Branching Convention