Skip to content

Commit 0a997e9

Browse files
ritwik-gclaude
andauthored
[MISC] Reject no-op OSS releases when there are no new commits (#2117)
* [MISC] Reject no-op OSS releases when there are no new commits create-release.yaml computed and published a new tag even when the branch had no commits beyond the last release, producing empty releases (e.g. v0.177.1 points at the exact same commit as v0.177.0). Add a guard after "Fetch base release version": use the compare API's ahead_by (the workflow has no local checkout) to count commits on the branch beyond the latest release tag. If zero, abort with a clear error (dry-run only warns). Works for main and hotfix branches alike. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * [MISC] Harden no-op guard: validate ahead_by, fail loudly on unexpected value PR review (Greptile + internal): `[[ "$AHEAD" -eq 0 ]]` mishandled a non-integer ahead_by — an empty value evaluated true ([[ "" -eq 0 ]]) and would wrongly reject a legitimate release, and a literal "null" aborted with a cryptic "integer expression expected" / unbound-variable error. Use `--jq '.ahead_by // empty'`, fail loudly if the compare API call fails, and require ahead_by to match ^[0-9]+$ (error out otherwise) before a string compare against "0". A transient/auth/shape error now fails the step with a clear message instead of being mistaken for "no new commits". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 7321a7c commit 0a997e9

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

.github/workflows/create-release.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,38 @@ jobs:
126126
echo "latest_tag=$LATEST_TAG" >> "$GITHUB_OUTPUT"
127127
echo "Base release: $LATEST_TAG"
128128
129+
- name: Ensure there are new commits to release
130+
env:
131+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
132+
LATEST_TAG: ${{ steps.get-latest.outputs.latest_tag }}
133+
BRANCH: ${{ github.ref_name }}
134+
DRY_RUN: ${{ github.event.inputs.dry_run }}
135+
run: |
136+
# Reject a no-op release: if the branch has no commits beyond the last release
137+
# tag (e.g. main is already at v0.177.0), there is nothing to release. This
138+
# prevents empty releases such as v0.177.1 pointing at the same commit as
139+
# v0.177.0. The workflow has no local checkout, so use the compare API's
140+
# `ahead_by` (commits on BRANCH not in LATEST_TAG). `// empty` stops a null/
141+
# absent value from reaching the comparison as the literal "null"; we then
142+
# require a non-negative integer and fail loudly on anything unexpected, so a
143+
# transient API error is never mistaken for "no new commits".
144+
AHEAD=$(gh api "repos/${{ github.repository }}/compare/${LATEST_TAG}...${BRANCH}" --jq '.ahead_by // empty') \
145+
|| { echo "::error::Could not query commits since $LATEST_TAG (compare API failed)."; exit 1; }
146+
if ! [[ "$AHEAD" =~ ^[0-9]+$ ]]; then
147+
echo "::error::Unexpected ahead_by='${AHEAD:-<empty>}' from compare ${LATEST_TAG}...${BRANCH}; refusing to guess."
148+
exit 1
149+
fi
150+
if [[ "$AHEAD" == "0" ]]; then
151+
if [[ "$DRY_RUN" == "true" ]]; then
152+
echo "::warning::No new commits on '$BRANCH' since $LATEST_TAG — a real run would be rejected (nothing to release)."
153+
else
154+
echo "::error::No new commits on '$BRANCH' since $LATEST_TAG — nothing to release. Aborting to avoid an empty release."
155+
exit 1
156+
fi
157+
else
158+
echo "✅ $AHEAD new commit(s) on '$BRANCH' since $LATEST_TAG"
159+
fi
160+
129161
- name: Compute next version
130162
id: compute-version
131163
env:

0 commit comments

Comments
 (0)