1010 workflow_dispatch :
1111 inputs :
1212 release_version :
13- description : " Optional tag/version to release after successful builds , for example 1.0.0. Leave empty for build-only ."
13+ description : " Optional release version , for example 1.0.0. Leave empty to use COLUMNAR_VERSION from columnar.c ."
1414 required : false
1515 type : string
1616 prerelease :
@@ -127,6 +127,33 @@ jobs:
127127
128128 - uses : actions/checkout@v4.2.2
129129
130+ - name : resolve release version
131+ id : release
132+ env :
133+ INPUT_RELEASE_VERSION : ${{ github.event.inputs.release_version }}
134+ run : |
135+ set -eu
136+ IS_RELEASE=false
137+ if [ "${GITHUB_REF#refs/tags/}" != "$GITHUB_REF" ]; then
138+ IS_RELEASE=true
139+ VERSION="$GITHUB_REF_NAME"
140+ elif [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then
141+ IS_RELEASE=true
142+ if [ -n "$INPUT_RELEASE_VERSION" ]; then
143+ VERSION="$INPUT_RELEASE_VERSION"
144+ else
145+ VERSION="$(sed -n 's/^# *define COLUMNAR_VERSION "\([^"]*\)".*/\1/p' columnar.c | head -n 1)"
146+ fi
147+ else
148+ VERSION=""
149+ fi
150+ if [ "$IS_RELEASE" = "true" ] && [ -z "$VERSION" ]; then
151+ echo "::error::Unable to resolve release version"
152+ exit 1
153+ fi
154+ echo "is_release=$IS_RELEASE" >> "$GITHUB_OUTPUT"
155+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
156+
130157 - name : setup MSYS2
131158 if : runner.os == 'Windows'
132159 uses : msys2/setup-msys2@v2.27.0
@@ -202,7 +229,7 @@ jobs:
202229 run : ' sqlite3 :memory: ".load ./dist/columnar" "SELECT columnar_version();"'
203230
204231 - name : validate macOS signing secrets
205- if : (startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.release_version != '')) && matrix.notarize
232+ if : steps.release.outputs.is_release == 'true' && matrix.notarize
206233 env :
207234 APPLE_CERTIFICATE : ${{ secrets.APPLE_CERTIFICATE }}
208235 CERTIFICATE_PASSWORD : ${{ secrets.CERTIFICATE_PASSWORD }}
@@ -222,7 +249,7 @@ jobs:
222249 exit "$missing"
223250
224251 - name : create keychain for macOS codesign
225- if : (startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.release_version != '')) && matrix.notarize
252+ if : steps.release.outputs.is_release == 'true' && matrix.notarize
226253 env :
227254 APPLE_CERTIFICATE : ${{ secrets.APPLE_CERTIFICATE }}
228255 CERTIFICATE_PASSWORD : ${{ secrets.CERTIFICATE_PASSWORD }}
@@ -241,7 +268,7 @@ jobs:
241268 security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
242269
243270 - name : codesign macOS dylib
244- if : (startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.release_version != '')) && matrix.notarize
271+ if : steps.release.outputs.is_release == 'true' && matrix.notarize
245272 env :
246273 APPLE_TEAM_ID : ${{ secrets.APPLE_TEAM_ID }}
247274 run : |
@@ -257,18 +284,14 @@ jobs:
257284 printf "%s\n" "${{ github.sha }}" > package/GIT_COMMIT
258285
259286 - name : notarize macOS release archive
260- if : (startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.release_version != '')) && matrix.notarize
287+ if : steps.release.outputs.is_release == 'true' && matrix.notarize
261288 env :
262289 APPLE_ID : ${{ secrets.APPLE_ID }}
263290 APPLE_PASSWORD : ${{ secrets.APPLE_PASSWORD }}
264291 APPLE_TEAM_ID : ${{ secrets.APPLE_TEAM_ID }}
265292 run : |
266293 set -euo pipefail
267- if [ "${GITHUB_REF#refs/tags/}" != "$GITHUB_REF" ]; then
268- VERSION="$GITHUB_REF_NAME"
269- else
270- VERSION="${{ github.event.inputs.release_version }}"
271- fi
294+ VERSION="${{ steps.release.outputs.version }}"
272295 RELEASE_DIR="release/${{ matrix.artifact }}-${VERSION}"
273296 RELEASE_ZIP="release/${{ matrix.artifact }}-${VERSION}.zip"
274297 mkdir -p "$RELEASE_DIR"
@@ -277,42 +300,52 @@ jobs:
277300 xcrun notarytool submit "$RELEASE_ZIP" --apple-id "$APPLE_ID" --password "$APPLE_PASSWORD" --team-id "$APPLE_TEAM_ID" --wait
278301
279302 - name : cleanup macOS signing keychain
280- if : always() && (startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.release_version != '')) && matrix.notarize
303+ if : always() && steps.release.outputs.is_release == 'true' && matrix.notarize
281304 run : |
282305 rm -f "$RUNNER_TEMP/developer_id_application.p12"
283306 security delete-keychain "$RUNNER_TEMP/columnar-signing.keychain-db" || true
284307
285308 - uses : actions/upload-artifact@v4.6.2
286- if : (startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.release_version != '')) && matrix.notarize
309+ if : steps.release.outputs.is_release == 'true' && matrix.notarize
287310 with :
288311 name : ${{ matrix.artifact }}
289312 path : release/*.zip
290313 if-no-files-found : error
291314 retention-days : 14
292315
293316 - uses : actions/upload-artifact@v4.6.2
294- if : ${{ !(startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.release_version != '')) || !matrix.notarize }}
317+ if : ${{ steps.release.outputs.is_release != 'true' || !matrix.notarize }}
295318 with :
296319 name : ${{ matrix.artifact }}
297320 path : package/
298321 if-no-files-found : error
299322 retention-days : 14
300323
301324 release :
302- if : startsWith(github.ref, 'refs/tags/') || ( github.event_name == 'workflow_dispatch' && github.event.inputs.release_version != '')
325+ if : startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch'
303326 needs : build
304327 runs-on : ubuntu-22.04
305328 permissions :
306329 contents : write
307330 steps :
331+ - uses : actions/checkout@v4.2.2
332+
308333 - name : resolve release version
309334 id : release
335+ env :
336+ INPUT_RELEASE_VERSION : ${{ github.event.inputs.release_version }}
310337 run : |
311338 set -euo pipefail
312339 if [ "${GITHUB_REF#refs/tags/}" != "$GITHUB_REF" ]; then
313340 VERSION="$GITHUB_REF_NAME"
341+ elif [ -n "$INPUT_RELEASE_VERSION" ]; then
342+ VERSION="$INPUT_RELEASE_VERSION"
314343 else
315- VERSION="${{ github.event.inputs.release_version }}"
344+ VERSION="$(sed -n 's/^# *define COLUMNAR_VERSION "\([^"]*\)".*/\1/p' columnar.c | head -n 1)"
345+ fi
346+ if [ -z "$VERSION" ]; then
347+ echo "::error::Unable to resolve release version"
348+ exit 1
316349 fi
317350 echo "version=$VERSION" >> "$GITHUB_OUTPUT"
318351
@@ -335,11 +368,48 @@ jobs:
335368 done
336369 (cd release && sha256sum * > SHA256SUMS)
337370
371+ - name : generate release notes
372+ env :
373+ GH_TOKEN : ${{ github.token }}
374+ VERSION : ${{ steps.release.outputs.version }}
375+ run : |
376+ set -euo pipefail
377+ GENERATED_NOTES="release/GENERATED_NOTES.md"
378+ RELEASE_BODY="release/RELEASE_BODY.md"
379+ gh api "repos/${GITHUB_REPOSITORY}/releases/generate-notes" \
380+ -f tag_name="$VERSION" \
381+ -f target_commitish="$GITHUB_SHA" \
382+ --jq .body > "$GENERATED_NOTES"
383+ {
384+ echo "## Builds"
385+ echo
386+ echo "All builds completed successfully for \`sqlite-columnar $VERSION\`. Download the archive matching your target platform:"
387+ echo
388+ } > "$RELEASE_BODY"
389+ for file in release/*.zip release/*.tar.gz; do
390+ [ -e "$file" ] || continue
391+ printf -- "- \`%s\`\n" "$(basename "$file")"
392+ done | sort >> "$RELEASE_BODY"
393+ {
394+ echo
395+ echo "## Checksums"
396+ echo
397+ echo "Use \`SHA256SUMS\` to verify the downloaded archives."
398+ echo
399+ echo "## Release Notes"
400+ echo
401+ } >> "$RELEASE_BODY"
402+ cat "$GENERATED_NOTES" >> "$RELEASE_BODY"
403+
338404 - uses : softprops/action-gh-release@v2
339405 with :
406+ name : sqlite-columnar ${{ steps.release.outputs.version }}
340407 tag_name : ${{ steps.release.outputs.version }}
341408 target_commitish : ${{ github.sha }}
342- generate_release_notes : true
409+ body_path : release/RELEASE_BODY.md
410+ draft : false
411+ make_latest : true
412+ overwrite_files : true
343413 prerelease : ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.prerelease == 'true' }}
344414 files : |
345415 release/*.zip
0 commit comments