Skip to content

Commit 57b09a8

Browse files
authored
add auto hotfix bump on PR merge to main (#22)
1 parent be1ef27 commit 57b09a8

File tree

4 files changed

+247
-16
lines changed

4 files changed

+247
-16
lines changed
Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
1-
---
2-
name: Bug report
3-
about: Create a report to help us improve
4-
title: ''
5-
labels: ''
6-
assignees: ''
7-
---
1+
## What does this PR do?
82

9-
**Please describe the bug this fixes or the feature this adds.**
3+
<!-- Brief description of the change. -->
104

11-
**Please describe how you tested this change. Include unit tests whenever possible.**
5+
## Breaking changes
126

13-
**Did you create or modify any associated documentation with this change? If documentation is not included in PR, please link to related documentation.**
7+
<!-- List any backwards-incompatible changes, or write "None". -->
148

15-
**If you added or modified HTML, did you check that it was 508 compliant?**
9+
None
1610

17-
**Please tag any specific reviewers you would like to review this PR**
11+
## New features
1812

19-
**Please include the following checks for open source contributing?**
13+
<!-- List any new capabilities added, or write "None". -->
2014

21-
* [ ] Did you check for sensitive data, and remove any?
22-
* [ ] Are additional approvals needed for this change?
23-
* [ ] Are there potential vulnerabilities or licensing issues with any new dependencies introduced?
15+
None
16+
17+
## How was this tested?
18+
19+
<!-- Describe how you verified the change works. Include unit tests when possible. -->
20+
21+
## Checklist
22+
23+
- [ ] No sensitive data (keys, tokens, credentials) included
24+
- [ ] Tests added or updated (if applicable)
25+
- [ ] Documentation updated (if applicable)
26+
- [ ] No new vulnerabilities or licensing issues with new dependencies

.github/workflows/auto-version.yml

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
name: Auto Version on PR Merge
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
branches: [main]
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
version-and-release:
13+
name: Version & Tag
14+
if: github.event.pull_request.merged == true
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout main with full history
19+
uses: actions/checkout@v5
20+
with:
21+
ref: main
22+
fetch-depth: 0
23+
fetch-tags: true
24+
token: ${{ secrets.RELEASE_TOKEN }}
25+
26+
- name: Get latest semver tag from main
27+
id: latest
28+
run: |
29+
LATEST=$(git tag --sort=-v:refname \
30+
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \
31+
| head -n1)
32+
33+
if [ -z "$LATEST" ]; then
34+
echo "No existing semver tags found, starting from v0.0.0"
35+
LATEST="v0.0.0"
36+
fi
37+
38+
VERSION="${LATEST#v}"
39+
{
40+
echo "tag=$LATEST"
41+
echo "version=$VERSION"
42+
echo "major=$(echo "$VERSION" | cut -d. -f1)"
43+
echo "minor=$(echo "$VERSION" | cut -d. -f2)"
44+
echo "patch=$(echo "$VERSION" | cut -d. -f3)"
45+
} >> "$GITHUB_OUTPUT"
46+
echo "Latest tag on main: $LATEST"
47+
48+
- name: Check for version tag on PR commits
49+
id: pr-tag
50+
env:
51+
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
52+
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
53+
run: |
54+
# Fetch the PR head ref to ensure we have all PR commits and their tags
55+
git fetch origin "$PR_HEAD_SHA" --tags 2>/dev/null || true
56+
57+
# Find the merge base between main and the PR head
58+
MERGE_BASE=$(git merge-base "$PR_BASE_SHA" "$PR_HEAD_SHA" 2>/dev/null || echo "$PR_BASE_SHA")
59+
60+
echo "Merge base: $MERGE_BASE"
61+
echo "PR head: $PR_HEAD_SHA"
62+
63+
PR_TAG=""
64+
for SHA in $(git log --format=%H "${MERGE_BASE}..${PR_HEAD_SHA}" 2>/dev/null); do
65+
TAG=$(git tag --points-at "$SHA" 2>/dev/null \
66+
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$' \
67+
| head -n1)
68+
if [ -n "$TAG" ]; then
69+
PR_TAG="$TAG"
70+
echo "Found version tag on PR commit $SHA: $TAG"
71+
break
72+
fi
73+
done
74+
75+
if [ -n "$PR_TAG" ]; then
76+
echo "tag=$PR_TAG" >> "$GITHUB_OUTPUT"
77+
echo "has_tag=true" >> "$GITHUB_OUTPUT"
78+
else
79+
echo "No version tag found on PR commits"
80+
echo "tag=" >> "$GITHUB_OUTPUT"
81+
echo "has_tag=false" >> "$GITHUB_OUTPUT"
82+
fi
83+
84+
- name: Calculate next version
85+
id: next
86+
run: |
87+
if [ "${{ steps.pr-tag.outputs.has_tag }}" == "true" ]; then
88+
NEXT="${{ steps.pr-tag.outputs.tag }}"
89+
echo "Using version from PR tag: $NEXT"
90+
else
91+
MAJOR=${{ steps.latest.outputs.major }}
92+
MINOR=${{ steps.latest.outputs.minor }}
93+
PATCH=${{ steps.latest.outputs.patch }}
94+
NEXT="v${MAJOR}.${MINOR}.$((PATCH + 1))"
95+
echo "Auto-bumping patch: ${{ steps.latest.outputs.tag }} -> $NEXT"
96+
fi
97+
98+
echo "version=${NEXT#v}" >> "$GITHUB_OUTPUT"
99+
echo "tag=$NEXT" >> "$GITHUB_OUTPUT"
100+
101+
- name: Update CHANGELOG (tagged PRs only)
102+
if: steps.pr-tag.outputs.has_tag == 'true'
103+
env:
104+
PR_TITLE: ${{ github.event.pull_request.title }}
105+
PR_BODY: ${{ github.event.pull_request.body }}
106+
PR_NUMBER: ${{ github.event.pull_request.number }}
107+
PR_URL: ${{ github.event.pull_request.html_url }}
108+
NEXT_VERSION: ${{ steps.next.outputs.version }}
109+
run: |
110+
DATE=$(date +%Y-%m-%d)
111+
112+
# Build the changelog entry in a temp file (using env vars to avoid injection)
113+
{
114+
echo ""
115+
echo "## [v${NEXT_VERSION}] - ${DATE}"
116+
echo ""
117+
echo "### ${PR_TITLE} ([#${PR_NUMBER}](${PR_URL}))"
118+
echo ""
119+
echo "${PR_BODY}"
120+
echo ""
121+
} > /tmp/changelog-entry.md
122+
123+
# Insert after the marker line in CHANGELOG.md
124+
if [ -f CHANGELOG.md ]; then
125+
# Find the marker line number
126+
MARKER_LINE=$(grep -n '<!-- auto-managed' CHANGELOG.md | head -n1 | cut -d: -f1)
127+
if [ -n "$MARKER_LINE" ]; then
128+
# Split file at marker, insert entry between
129+
head -n "$MARKER_LINE" CHANGELOG.md > /tmp/changelog-top.md
130+
tail -n +"$((MARKER_LINE + 1))" CHANGELOG.md > /tmp/changelog-bottom.md
131+
cat /tmp/changelog-top.md /tmp/changelog-entry.md /tmp/changelog-bottom.md > CHANGELOG.md
132+
else
133+
# No marker found, prepend after first line (the heading)
134+
head -n 1 CHANGELOG.md > /tmp/changelog-top.md
135+
tail -n +2 CHANGELOG.md > /tmp/changelog-bottom.md
136+
cat /tmp/changelog-top.md /tmp/changelog-entry.md /tmp/changelog-bottom.md > CHANGELOG.md
137+
fi
138+
else
139+
echo "::warning::CHANGELOG.md not found, creating it"
140+
{
141+
echo "# Changelog"
142+
echo ""
143+
echo "All notable changes to the PRIME FHIR Converter will be documented in this file."
144+
echo ""
145+
echo "The format is based on [Keep a Changelog](https://keepachangelog.com/)."
146+
echo ""
147+
echo "<!-- auto-managed: new entries are prepended below this line -->"
148+
cat /tmp/changelog-entry.md
149+
} > CHANGELOG.md
150+
fi
151+
152+
git config user.name "github-actions[bot]"
153+
git config user.email "github-actions[bot]@users.noreply.github.com"
154+
git add CHANGELOG.md
155+
git commit -m "docs: update CHANGELOG for v${NEXT_VERSION}"
156+
git push origin main
157+
158+
- name: Create and push version tag
159+
run: |
160+
TAG="${{ steps.next.outputs.tag }}"
161+
162+
# Check if tag already exists
163+
if git rev-parse "$TAG" >/dev/null 2>&1; then
164+
echo "::error::Tag $TAG already exists"
165+
exit 1
166+
fi
167+
168+
git tag "$TAG"
169+
git push origin "$TAG"
170+
echo "Created and pushed tag: $TAG"
171+
172+
- name: Trigger build-and-publish workflow
173+
env:
174+
GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
175+
run: |
176+
VERSION="${{ steps.next.outputs.version }}"
177+
echo "Triggering build-and-publish with version=${VERSION}, publish=true"
178+
gh workflow run build-and-publish.yml \
179+
-f version="${VERSION}" \
180+
-f publish=true
181+
182+
- name: Summary
183+
run: |
184+
{
185+
echo "### Auto Version Complete"
186+
echo ""
187+
echo "| Detail | Value |"
188+
echo "|--------|-------|"
189+
echo "| Previous tag | \`${{ steps.latest.outputs.tag }}\` |"
190+
echo "| New tag | \`${{ steps.next.outputs.tag }}\` |"
191+
echo "| PR had version tag | ${{ steps.pr-tag.outputs.has_tag }} |"
192+
echo "| CHANGELOG updated | ${{ steps.pr-tag.outputs.has_tag }} |"
193+
echo "| Build triggered | yes |"
194+
} >> "$GITHUB_STEP_SUMMARY"

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Changelog
2+
3+
All notable changes to the PRIME FHIR Converter will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/).
6+
7+
<!-- auto-managed: new entries are apppended below this line -->

CONTRIBUTING.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,30 @@ to merge a pull request, it must:
3636
* Receive a +1 from a majority of team members associated with the request.
3737
If there is significant dissent between the team, a meeting will be held to
3838
discuss a plan of action for the pull request.
39+
40+
## Versioning
41+
42+
This project uses [semantic versioning](https://semver.org/) (MAJOR.MINOR.PATCH).
43+
44+
**For most PRs**, you don't need to do anything special. When your PR is merged
45+
to `main`, the patch version bumps automatically (e.g., 1.2.3 -> 1.2.4).
46+
47+
**For new features or breaking changes**, create a version tag on your branch
48+
before opening your PR:
49+
50+
```bash
51+
git tag v1.3.0
52+
git push origin v1.3.0
53+
```
54+
55+
When a version tag is present on your PR branch, the CI pipeline will:
56+
- Use that version instead of the default patch bump
57+
- Update the [CHANGELOG](CHANGELOG.md) automatically from your PR title and description
58+
59+
To help keep the changelog useful, please include the following in your PR
60+
description when tagging a new version:
61+
- A brief summary of what changed
62+
- Any breaking changes (backwards-incompatible changes)
63+
- Any new features added
64+
65+
That's it -- the pipeline handles the rest.

0 commit comments

Comments
 (0)