Skip to content

Commit 7c6c8a3

Browse files
cschleidenCopilot
andcommitted
Add nightly release workflow
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d0990f3 commit 7c6c8a3

1 file changed

Lines changed: 174 additions & 0 deletions

File tree

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
name: Nightly Release
2+
3+
on:
4+
schedule:
5+
- cron: "17 5 * * *"
6+
workflow_dispatch:
7+
inputs:
8+
force:
9+
description: "Publish even when no commits were merged since the previous release point"
10+
required: false
11+
default: false
12+
type: boolean
13+
14+
permissions:
15+
contents: write
16+
17+
concurrency:
18+
group: nightly-release
19+
cancel-in-progress: false
20+
21+
jobs:
22+
detect_changes:
23+
name: Detect changes
24+
runs-on: ubuntu-latest
25+
if: github.ref == 'refs/heads/main'
26+
27+
outputs:
28+
should_publish: ${{ steps.detect.outputs.should_publish }}
29+
previous_tag: ${{ steps.detect.outputs.previous_tag }}
30+
release_tag: ${{ steps.detect.outputs.release_tag }}
31+
commit_count: ${{ steps.detect.outputs.commit_count }}
32+
33+
steps:
34+
- uses: actions/checkout@v4
35+
with:
36+
fetch-depth: 0
37+
fetch-tags: true
38+
39+
- name: Fetch tags
40+
run: git fetch --force --tags
41+
42+
- name: Detect releasable changes
43+
id: detect
44+
shell: bash
45+
env:
46+
FORCE_PUBLISH: ${{ inputs.force || false }}
47+
run: |
48+
set -euo pipefail
49+
50+
stable_tag_pattern='^v[0-9]+\.[0-9]+\.[0-9]+$'
51+
nightly_tag_pattern='^v[0-9]+\.[0-9]+\.[0-9]+-nightly\.[0-9]+(\.[0-9A-Za-z-]+)*$'
52+
release_tag_pattern='^v[0-9]+\.[0-9]+\.[0-9]+(-nightly\.[0-9]+(\.[0-9A-Za-z-]+)*)?$'
53+
54+
latest_stable_tag="$(git tag --list 'v*' --sort=-v:refname | grep -E "${stable_tag_pattern}" | head -n 1 || true)"
55+
latest_nightly_tag="$(git tag --list 'v*' --sort=-v:refname | grep -E "${nightly_tag_pattern}" | head -n 1 || true)"
56+
previous_tag="$(git for-each-ref --sort=-creatordate --format='%(refname:short)' refs/tags | grep -E "${release_tag_pattern}" | head -n 1 || true)"
57+
58+
if [[ -n "${latest_stable_tag}" && "${latest_stable_tag}" =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
59+
major="${BASH_REMATCH[1]}"
60+
minor="${BASH_REMATCH[2]}"
61+
patch="$((BASH_REMATCH[3] + 1))"
62+
else
63+
major="0"
64+
minor="0"
65+
patch="1"
66+
fi
67+
68+
timestamp="$(date -u +'%Y%m%d%H%M')"
69+
release_tag="v${major}.${minor}.${patch}-nightly.${timestamp}.${GITHUB_RUN_NUMBER}"
70+
71+
commit_count="0"
72+
should_publish="false"
73+
if [[ "${FORCE_PUBLISH}" == "true" ]]; then
74+
should_publish="true"
75+
elif [[ -z "${previous_tag}" ]]; then
76+
should_publish="true"
77+
else
78+
commit_count="$(git rev-list --count "${previous_tag}..HEAD")"
79+
if [[ "${commit_count}" -gt 0 ]]; then
80+
should_publish="true"
81+
fi
82+
fi
83+
84+
{
85+
echo "latest_stable_tag=${latest_stable_tag}"
86+
echo "latest_nightly_tag=${latest_nightly_tag}"
87+
echo "previous_tag=${previous_tag}"
88+
echo "release_tag=${release_tag}"
89+
echo "commit_count=${commit_count}"
90+
echo "should_publish=${should_publish}"
91+
} >> "${GITHUB_OUTPUT}"
92+
93+
if [[ "${should_publish}" == "true" ]]; then
94+
echo "Nightly release will publish ${release_tag}."
95+
else
96+
echo "No commits found since ${previous_tag}; nightly release will be skipped."
97+
fi
98+
99+
validate:
100+
name: Validate release
101+
runs-on: ubuntu-latest
102+
needs: detect_changes
103+
if: needs.detect_changes.outputs.should_publish == 'true'
104+
105+
steps:
106+
- uses: actions/checkout@v4
107+
108+
- name: Set up Go
109+
uses: actions/setup-go@v5
110+
with:
111+
go-version: 1.24
112+
check-latest: true
113+
cache: true
114+
115+
- name: Build
116+
run: make build
117+
118+
- name: Format
119+
run: |
120+
make fmt
121+
if [[ -n $(git status --porcelain) ]]; then
122+
echo "Code is not formatted. Please run 'make fmt'"
123+
git diff
124+
exit 1
125+
fi
126+
127+
- name: Lint
128+
uses: golangci/golangci-lint-action@v8
129+
with:
130+
version: v2.4.0
131+
132+
- name: Tests
133+
run: make test
134+
135+
publish:
136+
name: Publish release
137+
runs-on: ubuntu-latest
138+
needs:
139+
- detect_changes
140+
- validate
141+
if: needs.detect_changes.outputs.should_publish == 'true'
142+
143+
steps:
144+
- uses: actions/checkout@v4
145+
with:
146+
fetch-depth: 0
147+
fetch-tags: true
148+
149+
- name: Fetch tags
150+
run: git fetch --force --tags
151+
152+
- name: Create prerelease
153+
shell: bash
154+
env:
155+
GH_TOKEN: ${{ github.token }}
156+
RELEASE_TAG: ${{ needs.detect_changes.outputs.release_tag }}
157+
PREVIOUS_TAG: ${{ needs.detect_changes.outputs.previous_tag }}
158+
run: |
159+
set -euo pipefail
160+
161+
git tag "${RELEASE_TAG}" "${GITHUB_SHA}"
162+
git push origin "refs/tags/${RELEASE_TAG}"
163+
164+
notes_args=(--generate-notes)
165+
if [[ -n "${PREVIOUS_TAG}" ]]; then
166+
notes_args+=(--notes-start-tag "${PREVIOUS_TAG}")
167+
fi
168+
169+
gh release create "${RELEASE_TAG}" \
170+
--target "${GITHUB_SHA}" \
171+
--title "Nightly ${RELEASE_TAG}" \
172+
--prerelease \
173+
--latest=false \
174+
"${notes_args[@]}"

0 commit comments

Comments
 (0)