-
Notifications
You must be signed in to change notification settings - Fork 18
168 lines (154 loc) · 6.89 KB
/
Copy pathrelease.yml
File metadata and controls
168 lines (154 loc) · 6.89 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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
name: Release
on:
workflow_dispatch:
inputs:
bump:
description: Version bump type (ignored when republish_tag is set)
required: true
type: choice
options:
- patch
- minor
- major
- prerelease
- finalize
prerelease_stage:
description: With major/minor/patch — start a prerelease line (e.g. major + alpha → 2.0.0a1). With prerelease — advance the stage forward-only (e.g. prerelease + rc on 2.0.0a6 → 2.0.0rc1).
required: false
default: none
type: choice
options:
- none
- alpha
- beta
- rc
republish_tag:
description: Existing tag to re-publish (e.g. v2.0.0a1). Skips bump/commit/tag and the GitHub Release creation; only builds, publishes to PyPI, and notifies downstream consumers.
required: false
type: string
jobs:
release:
# Pure-Python package: the wheel is platform-independent, so a single
# Ubuntu runner is sufficient. Cross-platform compatibility is already
# validated on every push by dev.yml.
runs-on: ubuntu-latest
permissions:
contents: write
# Required for PyPI trusted publishing via OIDC (no API token).
id-token: write
# Required for the GITHUB_TOKEN-based docs deploy (peaceiris/actions-gh-pages).
pages: write
steps:
- name: Checkout
uses: actions/checkout@v7
with:
# For republish: check out the tagged commit so the build picks up
# the exact pyproject.toml/uv.lock state that was originally released.
ref: ${{ inputs.republish_tag || github.ref }}
# Full history + all tags so scripts/release.py's `git describe` can
# find the previous version tag and walk every commit in the range.
# With the default shallow depth-1 clone, git describe fails, the
# generator falls back to logging only HEAD, and CHANGELOG sections
# come out empty whenever HEAD is a merge commit (silently lost
# historical entries; see the fetch-depth bug behind v2.0.2 / 2.0.3
# / 2.1.0a2 empty sections that this commit also backfills).
fetch-depth: 0
- name: Set up uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
enable-cache: true
- name: Determine version
id: version
env:
BUMP: ${{ inputs.bump }}
PRERELEASE_STAGE: ${{ inputs.prerelease_stage }}
REPUBLISH_TAG: ${{ inputs.republish_tag }}
run: |
if [ -n "$REPUBLISH_TAG" ]; then
# Republish path: derive version from the tag, skip the bump.
NEW="${REPUBLISH_TAG#v}"
else
CURRENT=$(uv version --short)
# `prerelease_stage=none` (or unset) means no prerelease flag passed.
if [ -n "$PRERELEASE_STAGE" ] && [ "$PRERELEASE_STAGE" != "none" ]; then
NEW=$(python3 scripts/release.py bump "$CURRENT" "$BUMP" --prerelease "$PRERELEASE_STAGE")
else
NEW=$(python3 scripts/release.py bump "$CURRENT" "$BUMP")
fi
uv version "$NEW"
uv lock
fi
echo "version=$NEW" >> $GITHUB_OUTPUT
# Expose whether this is a prerelease so downstream steps can mark it.
if [[ "$NEW" =~ (a|b|rc)[0-9]+$ ]]; then
echo "prerelease=true" >> $GITHUB_OUTPUT
else
echo "prerelease=false" >> $GITHUB_OUTPUT
fi
- name: Generate CHANGELOG section
if: inputs.republish_tag == ''
id: changelog
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
BODY=$(python3 scripts/release.py generate "$VERSION")
{
echo 'body<<EOF'
echo "$BODY"
echo 'EOF'
} >> $GITHUB_OUTPUT
- name: Commit and tag
if: inputs.republish_tag == ''
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add pyproject.toml CHANGELOG.md uv.lock
git commit -m "chore: release ${{ steps.version.outputs.version }}"
git tag "v${{ steps.version.outputs.version }}"
git push
git push origin "v${{ steps.version.outputs.version }}"
- name: Build
run: uv build
- name: Create GitHub Release
if: inputs.republish_tag == ''
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
with:
tag_name: v${{ steps.version.outputs.version }}
name: v${{ steps.version.outputs.version }}
body: ${{ steps.changelog.outputs.body }}
files: dist/*.whl
draft: false
prerelease: ${{ steps.version.outputs.prerelease == 'true' }}
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
with:
skip-existing: true
# Downstream consumers (givenergy-cli, givenergy-hass) are notified of new
# releases via maintainer-side coordinator messaging, NOT an automated
# repository_dispatch. The old auto-notify raced PyPI's eventual-consistency
# window — the JSON index API would report the version while the file CDN uv
# resolves against was still stale, so the downstream `uv lock` refresh failed
# intermittently (observed on hass for 2.5.7). The agent now confirms PyPI
# genuinely serves the version before asking each consumer to bump its pin.
# Skip docs publishing for prereleases (site stays pinned to latest stable)
# and for republish runs (re-publishing an old tag must not roll the live
# docs back to that tag's snapshot).
- name: Install docs dependencies
if: steps.version.outputs.prerelease != 'true' && inputs.republish_tag == ''
run: uv sync --group docs
- name: Build documentation
if: steps.version.outputs.prerelease != 'true' && inputs.republish_tag == ''
run: uv run mkdocs build
- name: Publish documentation
if: steps.version.outputs.prerelease != 'true' && inputs.republish_tag == ''
# SHA-pinned to v4.1.0: the floating @v4 tag still resolves to a Node 20
# build; v4.1.0 (2026-05-12) is the first release on Node 24. Revisit once
# peaceiris re-points @v4.
uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0
with:
# GITHUB_TOKEN (+ pages: write on the job) replaces the long-lived
# PERSONAL_TOKEN — the action only needs contents:write to push to the
# gh-pages branch. If a future release regresses Pages deploy, revert to
# personal_token: ${{ secrets.PERSONAL_TOKEN }}.
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./site