Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
cache: maven

- name: Auto-tag
if: github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
if: (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.repository == 'nbclaudecodegui/NetbeansClaudeCodeGui'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
Expand Down Expand Up @@ -60,9 +60,21 @@ jobs:
fi
UPLOAD_URL=$(gh release view "$REL_TAG" --json uploadUrl -q .uploadUrl)
else
BASE_TAG=$(git tag | grep -E '^[0-9]+\.[0-9]+$' | sort -V | tail -1 || echo "0.0")
N=$(git rev-list "${BASE_TAG}..HEAD" --count 2>/dev/null || echo "0")
VER="${BASE_TAG}.${N}"
POM_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout | sed 's/-.*//')
MM=$(echo "$POM_VERSION" | cut -d. -f1-2)
MM_ESC="${MM//./\\.}"
LAST_REL=$(git tag | grep -E "^${MM_ESC}\.[0-9]+$" | sort -V | tail -1)
BASE_TAG=$(git tag | grep -E "^${MM_ESC}$" | sort -V | tail -1 || echo "")
if [[ -n "$LAST_REL" ]]; then
START=$(echo "$LAST_REL" | cut -d. -f3)
N=$(git rev-list "${LAST_REL}..HEAD" --count 2>/dev/null || echo "0")
VER="${MM}.$((START + N))"
elif [[ -n "$BASE_TAG" ]]; then
N=$(git rev-list "${BASE_TAG}..HEAD" --count 2>/dev/null || echo "0")
VER="${MM}.${N}"
else
VER="${MM}.0"
fi
RELEASE=OFF
UPLOAD_URL=""
REL_TAG=""
Expand Down
24 changes: 23 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,32 @@ A release has an explicit **start** and **finish**:
**Finishing a release** (only this, nothing else):
- Update `CHANGELOG.md` heading to `# MAJOR.MINOR` (matching current `pom.xml`) → CI sees this as the release signal, creates release tag `MAJOR.MINOR.N`, and publishes a GitHub Release

**After a published release** — any push without bumping `pom.xml` → **build error**. Start a new release first.
**After a published release** — CI auto-edits `CHANGELOG.md`: the release heading `# MAJOR.MINOR (date)` is replaced with `# MAJOR.MINOR.N (date)`. Development can continue immediately; patch versions increment from the last released N.

Implemented in `build-scripts/autotag.sh` and `.github/workflows/build.yml`.

### Side releases (patch releases on an old branch)

Use when a critical fix must be shipped for an older version while `main` has already moved to a newer `MAJOR.MINOR`.

**Setup (once per side branch):**
```bash
git checkout -b release/0.17 0.18^ # commit just before the next base tag (0.18, 0.19, etc.)
git push origin release/0.17
```
`pom.xml` on this branch already has `0.17.0-SNAPSHOT` — no change needed.

**Development:** push fixes to `release/0.17`; CI builds snapshot versions automatically.
Version numbers continue from the last released patch: if `0.17.3` was the last release, the next builds are `0.17.4`, `0.17.5`, etc.

**Releasing a patch:**
- Add `# 0.17 (YYYY-MM-DD)` at the top of `CHANGELOG.md` (together with the fix's bullet)
- Push → CI creates tag `0.17.N`, publishes GitHub Release, and auto-edits `CHANGELOG.md` to `# 0.17.N (YYYY-MM-DD)`

**Next patch:** add `# 0.17 (YYYY-MM-DD)` again and repeat.

`main` is fully unaffected throughout.

### CHANGELOG.md rules

The heading `# MAJOR.MINOR (YYYY-MM-DD)` is the CI release signal — **only add it when finishing a release**. Always include the release date in parentheses (e.g. `# 0.18 (2026-04-04)`).
Expand Down
37 changes: 24 additions & 13 deletions build-scripts/autotag.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,15 @@ echo "POM MM=$MM BASE_TAG=$BASE_TAG RELEASE_TAG=$RELEASE_TAG"
# If release tag exists — check its status
if [[ -n "$RELEASE_TAG" ]]; then
IS_DRAFT=$(gh release view "$RELEASE_TAG" --json isDraft -q .isDraft 2>/dev/null || echo "notfound")
if [[ "$IS_DRAFT" == "false" ]]; then
echo "ERROR: Release $RELEASE_TAG already published. Bump MAJOR.MINOR in pom.xml."
exit 1
if [[ "$IS_DRAFT" == "true" ]]; then
# Tag exists but release not published — delete tag and draft, recalculate
echo "Removing unpublished release tag $RELEASE_TAG"
git tag -d "$RELEASE_TAG" || true
git push origin ":refs/tags/$RELEASE_TAG" || true
gh release delete "$RELEASE_TAG" --yes 2>/dev/null || true
RELEASE_TAG=
fi
# Tag exists but release not published — delete tag and draft, recalculate N
echo "Removing unpublished release tag $RELEASE_TAG"
git tag -d "$RELEASE_TAG" || true
git push origin ":refs/tags/$RELEASE_TAG" || true
gh release delete "$RELEASE_TAG" --yes 2>/dev/null || true
RELEASE_TAG=
# If published: continue — CHANGELOG no longer has the release signal (auto-edited after release)
fi

# Create base tag if missing
Expand All @@ -42,12 +41,18 @@ if [[ -z "$BASE_TAG" ]]; then
BASE_TAG="$MM"
fi

# N = number of commits since base tag
N=$(git rev-list "${BASE_TAG}..HEAD" --count)
FULL_VER="${MM}.${N}"
# Version: count from last release tag (3-comp) if available, else from base tag (2-comp)
if [[ -n "$RELEASE_TAG" ]]; then
START_PATCH=$(echo "$RELEASE_TAG" | cut -d. -f3)
N=$(git rev-list "${RELEASE_TAG}..HEAD" --count)
FULL_VER="${MM}.$((START_PATCH + N))"
else
N=$(git rev-list "${BASE_TAG}..HEAD" --count)
FULL_VER="${MM}.${N}"
fi
echo "FULL_VER=$FULL_VER"

# Release signal: CHANGELOG starts with "# MAJOR.MINOR"
# Release signal: CHANGELOG starts with "# MAJOR.MINOR (..."
CHANGELOG_MM=""
FIRST_LINE=$(head -n 1 "$CHANGELOG" 2>/dev/null || echo "")
if [[ "$(echo "$FIRST_LINE" | cut -d' ' -f1)" == "#" ]]; then
Expand All @@ -59,4 +64,10 @@ if [[ "$CHANGELOG_MM" == "$MM" ]]; then
sed '0,/^#/d;/^#/Q' "$CHANGELOG" > "$RELEASE_NOTES" || echo "Release $FULL_VER" > "$RELEASE_NOTES"
git tag "$FULL_VER"
git push origin "$FULL_VER"

# Auto-edit CHANGELOG: replace "# MM (date)" with "# FULL_VER (date)" to clear the release signal
sed -i "s|^# ${MM_ESCAPED} |# ${FULL_VER} |" "$CHANGELOG"
git add "$CHANGELOG"
git commit -m "Released ${FULL_VER}"
git push origin HEAD
fi
Loading