-
Notifications
You must be signed in to change notification settings - Fork 0
141 lines (127 loc) · 5.04 KB
/
release.yml
File metadata and controls
141 lines (127 loc) · 5.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# Release workflow — bumps the version in pyproject.toml, commits, creates a tag,
# pushes, and publishes a GitHub Release. Triggered manually via workflow_dispatch
# or automatically on a tag push (e.g. from an external CI step).
#
# References:
# GitHub Releases: https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository
# Security hardening: https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions
# Concurrency best practices: https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/using-concurrency
# Workflow permissions: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token
name: Release
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
bump:
description: "Which semver part to bump (ignored if version is set)"
type: choice
required: false
default: patch
options:
- patch
- minor
- major
version:
description: "Explicit version to set (X.Y.Z). If set, overrides bump."
type: string
required: false
prerelease:
description: "Mark the GitHub Release as a pre-release"
type: boolean
required: false
default: false
# contents:write is required to commit the version bump, push the tag, and create a release.
permissions:
contents: write
# Serialise releases: never cancel an in-progress release run.
concurrency:
group: release
cancel-in-progress: false
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
# Shallow clone: `gh release create --generate-notes` uses the API; no full git walk.
fetch-depth: 1
- name: Install uv
uses: astral-sh/setup-uv@v8.0.0
with:
enable-cache: true
- name: Set up Python
run: uv python install 3.11
- name: Sync dependencies
run: uv sync --frozen --extra dev
- name: Configure git author
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Determine version
id: bump
env:
INPUT_VERSION: ${{ inputs.version }}
INPUT_BUMP: ${{ inputs.bump }}
run: |
set -euo pipefail
# If this workflow was triggered by pushing a tag (vX.Y.Z), use that version.
if [ "${GITHUB_EVENT_NAME}" = "push" ]; then
ref="${GITHUB_REF_NAME}"
if echo "${ref}" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "version=${ref#v}" >> "${GITHUB_OUTPUT}"
exit 0
fi
echo "Unexpected tag ref: ${ref}" >&2
exit 1
fi
if [ -n "${INPUT_VERSION}" ]; then
NEW_VERSION="$(uv run --active python scripts/bump_version.py --new-version "${INPUT_VERSION}")"
else
NEW_VERSION="$(uv run --active python scripts/bump_version.py --bump "${INPUT_BUMP}")"
fi
if [ -z "${NEW_VERSION}" ]; then
echo "Error: version bump script returned an empty version string" >&2
exit 1
fi
echo "version=${NEW_VERSION}" >> "${GITHUB_OUTPUT}"
- name: Commit version bump
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
set -euo pipefail
git add pyproject.toml
git commit -m "chore(release): v${{ steps.bump.outputs.version }}"
- name: Create tag
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
set -euo pipefail
git tag "v${{ steps.bump.outputs.version }}"
- name: Push commit and tag
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
set -euo pipefail
git push origin HEAD
git push origin "v${{ steps.bump.outputs.version }}"
# workflow_dispatch pushes a tag, which starts a second run of this workflow. That run
# must not call `gh release create` again. Skip when the tag push run sees an existing
# release; the dispatch run always creates it (preserving prerelease inputs).
- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
TAG="v${{ steps.bump.outputs.version }}"
PRERELEASE_FLAG=""
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.prerelease }}" = "true" ]; then
PRERELEASE_FLAG="--prerelease"
fi
if [ "${{ github.event_name }}" = "push" ] && gh release view "${TAG}" >/dev/null 2>&1; then
echo "Release ${TAG} already exists; skipping duplicate create."
exit 0
fi
gh release create "${TAG}" \
--title "${TAG}" \
--generate-notes \
${PRERELEASE_FLAG}