Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Configuration for auto-generated release notes.
# See: https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes#configuration-options
#
# This file is consumed by both the Releases UI and by `gh release create
# --generate-notes` (used by .github/workflows/release.yml).
changelog:
exclude:
authors:
- dependabot[bot]
- github-actions[bot]
- renovate[bot]
- renovate-sh-app[bot]
99 changes: 99 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Repo-internal: cuts a new release (annotated tag + GitHub Release with
# auto-generated notes) from main. Dispatch manually and pick the semver bump.
name: Release

on:
workflow_dispatch:
inputs:
bump:
description: 'Which semver part to bump.'
required: true
default: patch
type: choice
options:
- patch
- minor
- major

permissions:
contents: read

concurrency:
group: release
cancel-in-progress: false

jobs:
release:
name: Cut new release
runs-on: ubuntu-latest
permissions:
contents: write # to create the tag and the GitHub Release
steps:
- name: Enforce main branch
env:
REF: ${{ github.ref }}
run: |
if [[ "$REF" != "refs/heads/main" ]]; then
echo "::error::Release must be cut from main. Got: $REF"
exit 1
fi

- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
fetch-tags: true
# zizmor: ignore[artipacked] — we need the token persisted to push the annotated tag below.
persist-credentials: true

- name: Compute next version
id: compute
env:
BUMP: ${{ inputs.bump }}
run: |
set -euo pipefail
latest=$(git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname | head -n 1)
if [[ -z "$latest" ]]; then
latest="v0.0.0"
fi
echo "Latest tag: $latest"
ver="${latest#v}"
IFS='.' read -r major minor patch <<< "$ver"
case "$BUMP" in
major) major=$((major + 1)); minor=0; patch=0 ;;
minor) minor=$((minor + 1)); patch=0 ;;
patch) patch=$((patch + 1)) ;;
*) echo "::error::unknown bump: $BUMP"; exit 1 ;;
esac
new="v${major}.${minor}.${patch}"
echo "New version: $new"
echo "new_version=$new" >> "$GITHUB_OUTPUT"

- name: Create annotated tag
env:
NEW_VERSION: ${{ steps.compute.outputs.new_version }}
TARGET_SHA: ${{ github.sha }}
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag -a "$NEW_VERSION" -m "Release $NEW_VERSION" "$TARGET_SHA"
git push origin "$NEW_VERSION"

- name: Create release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NEW_VERSION: ${{ steps.compute.outputs.new_version }}
TARGET_SHA: ${{ github.sha }}
run: |
set -euo pipefail
# The annotated tag was pushed in the previous step; --verify-tag
# tells gh to attach the Release to it rather than creating a new
# (lightweight) tag.
gh release create "$NEW_VERSION" \
--title "$NEW_VERSION" \
--generate-notes \
--latest \
--verify-tag \
--target "$TARGET_SHA"
echo "Created release $NEW_VERSION at $TARGET_SHA"