Skip to content

Commit 1acb5c4

Browse files
Release automation improvements stolen from michaelklishin/frm
1 parent 7a5a538 commit 1acb5c4

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

.github/workflows/release.yaml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Release
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
tags:
7+
- 'v*.*.*'
8+
9+
defaults:
10+
run:
11+
shell: bash
12+
13+
permissions:
14+
contents: write
15+
16+
jobs:
17+
validate_version:
18+
name: Validate Release Version
19+
runs-on: ubuntu-24.04
20+
steps:
21+
- uses: actions/checkout@v6
22+
23+
- name: Install Nu Shell
24+
uses: hustcer/setup-nu@v3
25+
with:
26+
version: '0.100'
27+
env:
28+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29+
30+
- name: Validate NEXT_RELEASE_VERSION matches tag
31+
run: nu ./scripts/validate-release-version.nu
32+
env:
33+
NEXT_RELEASE_VERSION: ${{ vars.NEXT_RELEASE_VERSION }}
34+
GITHUB_REF_NAME: ${{ github.ref_name }}
35+
36+
create_gh_release:
37+
name: Create GitHub Release
38+
needs: [validate_version]
39+
runs-on: ubuntu-24.04
40+
steps:
41+
- name: Checkout repository
42+
uses: actions/checkout@v6
43+
44+
- name: Install Nu Shell
45+
uses: hustcer/setup-nu@v3
46+
with:
47+
version: '0.100'
48+
env:
49+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50+
51+
- name: Extract changelog for release
52+
run: nu ./scripts/extract-changelog.nu
53+
env:
54+
VERSION: ${{ vars.NEXT_RELEASE_VERSION }}
55+
56+
- name: Publish GitHub release
57+
uses: softprops/action-gh-release@v2
58+
with:
59+
tag_name: v${{ vars.NEXT_RELEASE_VERSION }}
60+
draft: false
61+
body_path: release_notes.md
62+
env:
63+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

scripts/extract-changelog.nu

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env nu
2+
3+
let version = $env.VERSION? | default ""
4+
if $version == "" {
5+
print "ERROR: VERSION environment variable is not set"
6+
exit 1
7+
}
8+
9+
let header = $'## v($version)'
10+
11+
let lines = open CHANGELOG.md | lines
12+
let start_idx = $lines | enumerate | where { |it| $it.item | str starts-with $header } | get -i 0.index
13+
14+
if $start_idx == null {
15+
print $"ERROR: Version header '($header)' not found in CHANGELOG.md"
16+
exit 1
17+
}
18+
19+
let remaining = $lines | skip ($start_idx + 1)
20+
let end_offset = $remaining | enumerate | where { |it| $it.item | str starts-with '## v' } | get -i 0.index | default ($remaining | length)
21+
22+
let section = $lines | skip $start_idx | take ($end_offset + 1)
23+
24+
$section | str join "\n" | save --force release_notes.md
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env nu
2+
3+
# Validates that NEXT_RELEASE_VERSION matches the git tag
4+
5+
let expected = $env.NEXT_RELEASE_VERSION? | default ""
6+
let tag = $env.GITHUB_REF_NAME? | default ""
7+
8+
if $expected == "" {
9+
print "ERROR: NEXT_RELEASE_VERSION variable is not set"
10+
print ""
11+
print "Set it at: Settings > Secrets and variables > Actions > Variables"
12+
exit 1
13+
}
14+
15+
if $tag == "" {
16+
print "ERROR: GITHUB_REF_NAME is not available"
17+
exit 1
18+
}
19+
20+
# Check if this looks like a version tag
21+
if not ($tag | str starts-with 'v') {
22+
print $"ERROR: This workflow should be triggered by a version tag \(v*.*.*\), not '($tag)'"
23+
print ""
24+
print "Push a tag like: git tag v($expected) && git push origin v($expected)"
25+
exit 1
26+
}
27+
28+
# Extract version from tag (v0.14.0 -> 0.14.0)
29+
let tag_version = $tag | str substring 1..
30+
31+
if $expected == $tag_version {
32+
print $"Version validated: ($expected) matches tag ($tag)"
33+
} else {
34+
print $"ERROR: NEXT_RELEASE_VERSION \(($expected)\) does not match tag \(($tag)\)"
35+
print ""
36+
print "Either:"
37+
print $" 1. Update NEXT_RELEASE_VERSION to '($tag_version)' at: Settings > Secrets and variables > Actions > Variables"
38+
print $" 2. Or push the correct tag: git tag v($expected) && git push origin v($expected)"
39+
exit 1
40+
}

0 commit comments

Comments
 (0)