Skip to content

Commit 989b2c2

Browse files
Merge pull request #59 from marius-bughiu/infra/release-on-tag-push
Trigger release workflow on tag push
2 parents 09b3cd6 + 573e858 commit 989b2c2

2 files changed

Lines changed: 62 additions & 9 deletions

File tree

.github/workflows/release.yml

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
name: Release
22

3-
on: workflow_dispatch
3+
on:
4+
push:
5+
tags: ['v*']
6+
workflow_dispatch:
47

58
env:
69
NuGetDirectory: ${{ github.workspace}}/nuget
@@ -47,7 +50,7 @@ jobs:
4750
if-no-files-found: error
4851
retention-days: 7
4952
path: ${{ env.NuGetDirectory }}/*.nupkg
50-
53+
5154
deploy:
5255
runs-on: ubuntu-latest
5356
needs: [ build ]
@@ -64,5 +67,52 @@ jobs:
6467
run: |
6568
foreach($file in (Get-ChildItem "${{ env.NuGetDirectory }}" -Recurse -Include *.nupkg)) {
6669
dotnet nuget push $file --api-key "${{ secrets.NUGET_APIKEY }}" --source https://api.nuget.org/v3/index.json --skip-duplicate
67-
}
68-
70+
}
71+
72+
github-release:
73+
name: Create GitHub Release
74+
runs-on: ubuntu-latest
75+
needs: [ deploy ]
76+
if: startsWith(github.ref, 'refs/tags/v')
77+
permissions:
78+
contents: write
79+
steps:
80+
- uses: actions/checkout@v4
81+
with:
82+
fetch-depth: 0
83+
84+
- uses: actions/download-artifact@v4
85+
with:
86+
name: nuget
87+
path: ${{ env.NuGetDirectory }}
88+
89+
- name: Extract release notes from CHANGELOG.md
90+
shell: bash
91+
run: |
92+
set -euo pipefail
93+
tag="${GITHUB_REF_NAME}"
94+
version="${tag#v}"
95+
# Extract the section under "## [<version>]" up to (but not including)
96+
# the next "## [" heading. Empty output means the CHANGELOG was not
97+
# updated for this version — fail loudly so the maintainer notices.
98+
awk -v ver="$version" '
99+
$0 ~ "^## \\[" ver "\\]" { capture = 1; next }
100+
capture && /^## \[/ { exit }
101+
capture { print }
102+
' CHANGELOG.md > release-notes.md
103+
if [ ! -s release-notes.md ]; then
104+
echo "::error::No CHANGELOG.md section found for [$version]. Move the [Unreleased] block to [$version] and re-tag." >&2
105+
exit 1
106+
fi
107+
echo "--- Release notes for $tag ---"
108+
cat release-notes.md
109+
110+
- name: Create GitHub Release
111+
env:
112+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
113+
shell: bash
114+
run: |
115+
gh release create "$GITHUB_REF_NAME" \
116+
--title "$GITHUB_REF_NAME" \
117+
--notes-file release-notes.md \
118+
${{ env.NuGetDirectory }}/*.nupkg

CONTRIBUTING.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,19 @@ git tag -l 'v*' --sort=-v:refname | head -1
9797

9898
### Cutting a release
9999

100+
Releases are automated. Pushing a `v`-prefixed tag fires `.github/workflows/release.yml`, which builds, packs, publishes to NuGet.org, and creates a matching GitHub Release with notes extracted from `CHANGELOG.md`.
101+
100102
```bash
101-
# 1. Merge the release PR (which updates CHANGELOG.md)
102-
# 2. Tag the merge commit on main
103+
# 1. Move the CHANGELOG [Unreleased] block to [X.Y.Z] (with today's date if you
104+
# want one — the workflow does not require a date), commit, and merge to main.
105+
# 2. Tag the merge commit and push the tag.
103106
git tag -a v1.2.0 -m "Release 1.2.0"
104107
git push origin v1.2.0
105-
106-
# 3. Trigger the Release workflow via GitHub Actions UI (workflow_dispatch)
107108
```
108109

109-
The `Release` workflow (`.github/workflows/release.yml`) builds, packs, and publishes to NuGet.org.
110+
The workflow extracts the `## [X.Y.Z]` section of `CHANGELOG.md` and uses it as the GitHub Release body. If no matching section exists for the tag's version, the workflow fails loudly — the fix is to update `CHANGELOG.md` and re-tag.
111+
112+
`workflow_dispatch` is still wired up as a manual fallback for ad-hoc re-publishes (e.g. if a NuGet push fails partway through), but the normal flow is tag-push.
110113

111114
## Scope
112115

0 commit comments

Comments
 (0)