Skip to content

Commit f5b567a

Browse files
authored
fix: gate release on a release-worthy conventional commit (#13)
* fix: gate release on a release-worthy conventional commit release.yml fired on every non-[skip ci] push to main and defaulted to a patch bump, so docs:/chore:/ci: commits cut spurious patch releases -- contradicting AGENTS.md/CONTRIBUTING.md which say those skip the release path. The bump step now sets a release output: true only when a commit subject since the last tag matches feat:/feat!:/fix:/fix!:/BREAKING CHANGE (or there is no prior tag = initial release); otherwise false. All five mutating steps (VERSION write, doc-sync, bump commit, tag, GitHub release) are gated on release == 'true', mirroring the existing skip guard. A mixed push (docs + a real fix) still releases. The [skip ci] guard is kept as an optional override. Initial-release hold and floating-tag/force-push paths are unchanged. Decision logic unit-tested across docs-only/chore/ci/fix/feat/feat!/mixed/initial/refactor. AGENTS.md and CONTRIBUTING.md reworded to match. Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.com> * ci: re-trigger PR checks (pull_request event was not scheduled) Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.com> --------- Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.com>
1 parent be66a85 commit f5b567a

3 files changed

Lines changed: 34 additions & 14 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,31 @@ jobs:
4343
echo "Commits since last release:"
4444
echo "$commits"
4545
46+
# Release ONLY when a commit subject since the last tag carries a release-worthy
47+
# conventional prefix. docs/chore/ci/refactor/test/style/build/perf land WITHOUT
48+
# cutting a release. A mixed push (docs + a real fix) still releases: the scan
49+
# matches any release-worthy commit in the range regardless of the others.
50+
# [skip ci] (guarded on the job) remains an optional belt-and-suspenders override.
4651
bump="patch"
47-
if echo "$commits" | grep -qiE "^(feat|feature)(\(.+\))?!:|BREAKING CHANGE"; then
48-
bump="major"
52+
release="false"
53+
if [ -z "$last_tag" ]; then
54+
# Initial release: no prior tag -> cut the first release at the current VERSION.
55+
release="true"
56+
elif echo "$commits" | grep -qiE "^(feat|feature|fix)(\(.+\))?!:|BREAKING[ -]CHANGE"; then
57+
bump="major"; release="true"
4958
elif echo "$commits" | grep -qiE "^(feat|feature)(\(.+\))?:"; then
50-
bump="minor"
59+
bump="minor"; release="true"
60+
elif echo "$commits" | grep -qiE "^fix(\(.+\))?:"; then
61+
bump="patch"; release="true"
5162
fi
5263
5364
echo "bump=$bump" >> "$GITHUB_OUTPUT"
54-
echo "Bump type: $bump"
65+
echo "release=$release" >> "$GITHUB_OUTPUT"
66+
if [ "$release" = "true" ]; then
67+
echo "Release decision: RELEASE (bump=$bump)"
68+
else
69+
echo "Release decision: SKIP - no feat:/fix:/feat!: commit since ${last_tag:-<none>}; docs/chore/ci do not cut a release"
70+
fi
5571
5672
- name: Compute new version
5773
id: new
@@ -92,22 +108,22 @@ jobs:
92108
fi
93109
94110
- name: Update VERSION file
95-
if: steps.check.outputs.skip == 'false'
111+
if: steps.check.outputs.skip == 'false' && steps.bump.outputs.release == 'true'
96112
env:
97113
NEW_VERSION: ${{ steps.new.outputs.version }}
98114
run: |
99115
echo "$NEW_VERSION" > VERSION
100116
101117
- name: Sync release docs
102-
if: steps.check.outputs.skip == 'false'
118+
if: steps.check.outputs.skip == 'false' && steps.bump.outputs.release == 'true'
103119
uses: TMHSDigital/Developer-Tools-Directory/.github/actions/release-doc-sync@v1
104120
with:
105121
plugin-version: ${{ steps.new.outputs.version }}
106122
previous-version: ${{ steps.current.outputs.version }}
107123
meta-repo-ref: v1.15.1
108124

109125
- name: Commit version bump
110-
if: steps.check.outputs.skip == 'false'
126+
if: steps.check.outputs.skip == 'false' && steps.bump.outputs.release == 'true'
111127
run: |
112128
git config user.name "github-actions[bot]"
113129
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
@@ -120,7 +136,7 @@ jobs:
120136
fi
121137
122138
- name: Create and push tag
123-
if: steps.check.outputs.skip == 'false'
139+
if: steps.check.outputs.skip == 'false' && steps.bump.outputs.release == 'true'
124140
run: |
125141
new_version="${{ steps.new.outputs.version }}"
126142
IFS='.' read -r major minor _patch <<< "$new_version"
@@ -134,7 +150,7 @@ jobs:
134150
git push origin "v$major.$minor" --force
135151
136152
- name: Create GitHub Release
137-
if: steps.check.outputs.skip == 'false'
153+
if: steps.check.outputs.skip == 'false' && steps.bump.outputs.release == 'true'
138154
env:
139155
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
140156
run: |

‎AGENTS.md‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,16 @@ Blender-Developer-Tools/
4646
## Branching and commit model
4747

4848
- Single `main` branch. No develop or release branches.
49-
- Conventional commits drive the auto-release workflow:
49+
- Conventional commits drive the auto-release workflow. It scans the commit subjects since
50+
the last tag and releases only when at least one is release-worthy:
5051
- `feat:` triggers a minor bump
5152
- `fix:` triggers a patch bump
52-
- `feat!:` or `BREAKING CHANGE` triggers a major bump
53-
- Other types (`chore:`, `docs:`, etc.) skip the release path entirely
54-
when only those non-content paths change.
53+
- `feat!:` / `fix!:` / `BREAKING CHANGE` triggers a major bump
54+
- Other types (`chore:`, `docs:`, `ci:`, `refactor:`, etc.) do **not** cut a release: the
55+
workflow runs, decides there is nothing to release, and exits without a tag or version
56+
bump. A mixed push still releases if any commit in range is a `feat:`/`fix:`.
57+
- `[skip ci]` in the head commit still bypasses the workflow entirely. With the commit-type
58+
gate above it is now an optional override, not a requirement for non-release commits.
5559
- Commit messages should describe the why, not the what.
5660

5761
## Blender version targeting

‎CONTRIBUTING.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ The drift-check workflow enforces these on every push and PR.
116116

117117
1. **Update docs** if you change skill or rule lists, content counts, or versioning (`README.md`, `CLAUDE.md`, `ROADMAP.md` as appropriate). The release workflow rewrites `CHANGELOG.md`, `CLAUDE.md` `**Version:**` line, and `ROADMAP.md` `**Current:**` line automatically when a `feat:` or `fix:` commit lands on `main`, so only edit those files for content beyond the version markers.
118118
2. **Open a PR** against `main` with a clear title and summary of changes.
119-
3. **Use Conventional Commits** for the PR title (and ideally the merge commit). Prefixes: `feat:` (minor bump), `fix:` (patch bump), `feat!:` or `BREAKING CHANGE` (major bump), `chore:` / `docs:` / `refactor:` (no release).
119+
3. **Use Conventional Commits** for the PR title (and the squash-merge subject, which is what the release workflow scans). Prefixes: `feat:` (minor bump), `fix:` (patch bump), `feat!:` / `fix!:` / `BREAKING CHANGE` (major bump), `chore:` / `docs:` / `ci:` / `refactor:` (no release — the workflow runs and exits without tagging). A mixed range still releases if any commit since the last tag is a `feat:`/`fix:`. `[skip ci]` remains an optional override and is no longer required to avoid a release for non-release commits.
120120
4. **Respond to review** feedback; CI must pass before merge.
121121

122122
## Developer Certificate of Origin and Inbound License Grant

0 commit comments

Comments
 (0)