Skip to content

Add make tag target for GitHub release - #334

Merged
drernie merged 5 commits into
mainfrom
tag-release-target
Apr 30, 2026
Merged

Add make tag target for GitHub release#334
drernie merged 5 commits into
mainfrom
tag-release-target

Conversation

@drernie

@drernie drernie commented Apr 30, 2026

Copy link
Copy Markdown
Member

Summary

  • Add wf/tag-release.sh that reads the current version from build.gradle, extracts the matching ## [x.y.z] section from CHANGELOG.md, creates an annotated git tag, pushes it, and runs gh release create with those notes.
  • Wire it up as make tag.

Complements make release (publishes to the Nextflow Plugin Registry) by handling the separate GitHub-release step.

Test plan

  • Verified the awk CHANGELOG extraction returns the 1.0.1 bullets
  • Run make tag after merge to cut the 1.0.1 GitHub release

🤖 Generated with Claude Code

Greptile Summary

This PR adds wf/tag-release.sh (wired as make tag) which reads the version from build.gradle, extracts the matching CHANGELOG.md section, creates an annotated git tag, pushes it, and calls gh release create.

  • Partial-failure gap (P1): git push origin "$VERSION" runs before gh release create. If the GitHub release step fails (auth error, release already exists, network timeout), the tag is already live on the remote but no release is attached. The "tag already exists" guard then prevents any re-run, leaving the repo in a half-released state without rollback.

Confidence Score: 3/5

Needs the partial-failure rollback fixed before running in production; the remaining issues are minor.

One P1 (tag pushed without rollback on release-creation failure) plus three P2s (ref scoping, awk dot escaping, whitespace check) pulls the score below the P1 ceiling of 4.

wf/tag-release.sh — specifically lines 30-33 around tag push / release create ordering

Important Files Changed

Filename Overview
wf/tag-release.sh New script to tag and publish a GitHub release; has a P1 partial-failure risk (tag pushed before release creation, no rollback), plus P2 issues with ref scoping, awk regex dot escaping, and incomplete whitespace trimming.
Makefile Adds tag to .PHONY and wires it to wf/tag-release.sh; straightforward and correct.

Sequence Diagram

sequenceDiagram
    participant Dev as Developer
    participant Script as tag-release.sh
    participant FS as Filesystem
    participant Git as Git (local+remote)
    participant GH as GitHub Releases

    Dev->>Script: make tag
    Script->>FS: grep version from build.gradle
    FS-->>Script: VERSION
    Script->>Git: git rev-parse refs/tags/VERSION
    Git-->>Script: not found → proceed
    Script->>FS: awk extract CHANGELOG section
    FS-->>Script: NOTES
    Script->>Git: git tag -a VERSION
    Script->>Git: git push origin VERSION
    Git-->>Script: tag pushed ✓
    Script->>GH: gh release create VERSION --notes NOTES
    GH-->>Script: release created ✓ (or ✗ → tag stranded)
    Script->>Dev: echo "Tagged and released VERSION"
Loading

Reviews (1): Last reviewed commit: "Make release depend on tag" | Re-trigger Greptile

Greptile also left 4 inline comments on this PR.

drernie and others added 2 commits April 30, 2026 15:37
Tags the current build.gradle version and creates a GitHub release
with the matching CHANGELOG section as notes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread wf/tag-release.sh Outdated
Comment on lines +13 to +15
if git rev-parse "$VERSION" >/dev/null 2>&1; then
echo "Tag $VERSION already exists" >&2
exit 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 git rev-parse may match non-tag refs

git rev-parse "$VERSION" succeeds for any ref with that name — branches, remotes, etc. — not just tags. If a branch 1.0.1 exists (unlikely but possible), the script exits with "tag already exists" when no tag has been created. Scoping the lookup to refs/tags/ avoids the ambiguity.

Suggested change
if git rev-parse "$VERSION" >/dev/null 2>&1; then
echo "Tag $VERSION already exists" >&2
exit 1
if git rev-parse "refs/tags/$VERSION" >/dev/null 2>&1; then
echo "Tag $VERSION already exists" >&2
exit 1
fi

Comment thread wf/tag-release.sh Outdated
Comment on lines +19 to +23
NOTES="$(awk -v v="$VERSION" '
$0 ~ "^## \\[" v "\\]" { found=1; next }
found && /^## \[/ { exit }
found { print }
' CHANGELOG.md)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Dots in version string are unescaped in awk regex

v is interpolated directly into an awk ERE, where . matches any character. 1.0.1 would also match 1X0Y1. While version numbers of that form are contrived, escaping the dots makes the match strict and avoids false positives if version components ever vary.

Suggested change
NOTES="$(awk -v v="$VERSION" '
$0 ~ "^## \\[" v "\\]" { found=1; next }
found && /^## \[/ { exit }
found { print }
' CHANGELOG.md)"
$0 ~ "^## \\[" gensub(/\./, "\\\\.", "g", v) "\\]" { found=1; next }

Alternatively, switch to a fixed-string index() comparison for the header detection.

Comment thread wf/tag-release.sh Outdated
Comment on lines +30 to +33
git tag -a "$VERSION" -m "Release $VERSION"
git push origin "$VERSION"

gh release create "$VERSION" --title "Version $VERSION" --notes "$NOTES"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 No rollback if gh release create fails after tag is pushed

The script pushes the tag on line 31, then calls gh release create on line 33. If the release creation fails (network error, release already exists, missing gh auth, etc.), the tag is already live on the remote but no GitHub release exists. Re-running the script will immediately fail at the "tag already exists" guard, leaving the repo in a half-released state.

Consider either checking for an existing GitHub release before tagging (gh release view "$VERSION"), or deleting the remote tag on failure:

git tag -a "$VERSION" -m "Release $VERSION"
git push origin "$VERSION"

if ! gh release create "$VERSION" --title "Version $VERSION" --notes "$NOTES"; then
    echo "Release creation failed; removing remote tag $VERSION" >&2
    git push origin --delete "$VERSION"
    git tag -d "$VERSION"
    exit 1
fi

Comment thread wf/tag-release.sh Outdated
Comment on lines +25 to +27
if [[ -z "${NOTES// }" ]]; then
echo "No CHANGELOG section found for [$VERSION]" >&2
exit 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Whitespace trimming misses tabs and newlines

${NOTES// } removes only ASCII space characters. If the CHANGELOG section between two headers contains only blank lines (i.e. NOTES is composed entirely of newline characters), the guard [[ -z "${NOTES// }" ]] evaluates to false and the script proceeds with effectively empty release notes. Use tr -d '[:space:]' to catch all whitespace.

Suggested change
if [[ -z "${NOTES// }" ]]; then
echo "No CHANGELOG section found for [$VERSION]" >&2
exit 1
if [[ -z "$(echo "$NOTES" | tr -d '[:space:]')" ]]; then

@github-actions

github-actions Bot commented Apr 30, 2026

Copy link
Copy Markdown

🦙 MegaLinter status: ✅ SUCCESS

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ BASH shellcheck 2 0 0 0.07s
✅ BASH shfmt 2 2 0 0 0.02s
✅ REPOSITORY checkov yes no no 10.08s
✅ REPOSITORY git_diff yes no no 0.01s
✅ REPOSITORY grype yes no no 39.12s
✅ REPOSITORY secretlint yes no no 0.41s
✅ REPOSITORY syft yes no no 1.03s
✅ REPOSITORY trivy yes no no 6.92s
✅ REPOSITORY trivy-sbom yes no no 0.08s
✅ REPOSITORY trufflehog yes no no 2.27s

See detailed report in MegaLinter reports
Set VALIDATE_ALL_CODEBASE: true in mega-linter.yml to validate all sources, not only the diff

MegaLinter is graciously provided by OX Security

drernie and others added 3 commits April 30, 2026 15:43
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Scope existence check to refs/tags/ to avoid matching branches
- Escape dots in version for awk regex
- Use tr -d '[:space:]' to catch tabs/newlines in notes guard
- Roll back tag if gh release create fails

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Same class of issue as the awk fix; address while reviewing PR #334.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@drernie
drernie merged commit 28ca7b7 into main Apr 30, 2026
10 checks passed
@drernie
drernie deleted the tag-release-target branch April 30, 2026 22:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant