-
Notifications
You must be signed in to change notification settings - Fork 59
249 lines (218 loc) · 9.49 KB
/
release.yml
File metadata and controls
249 lines (218 loc) · 9.49 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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
name: "Release"
on:
pull_request:
types: [closed]
branches: [master]
workflow_dispatch:
permissions:
contents: read
# Concurrency control: only one release process can run at a time
# This prevents race conditions if multiple PRs with 'release' label merge simultaneously
concurrency:
group: release
cancel-in-progress: false
jobs:
check-release-label:
name: Check for release label
runs-on: ubuntu-latest
# Run when PR with 'release' label is merged to master
if: |
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'pull_request' &&
github.event.pull_request.merged == true &&
contains(github.event.pull_request.labels.*.name, 'release'))
outputs:
should-release: ${{ steps.check.outputs.should-release }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: master
fetch-depth: 0
- name: Check release conditions
id: check
run: |
changeset_count=$(find .sampo/changesets -name '*.md' 2>/dev/null | wc -l)
if [ "$changeset_count" -gt 0 ]; then
echo "should-release=true" >> "$GITHUB_OUTPUT"
echo "Found $changeset_count changeset(s), ready to release"
else
echo "should-release=false" >> "$GITHUB_OUTPUT"
echo "No changesets to release"
fi
notify-approval-needed:
name: Notify Slack - Approval Needed
needs: check-release-label
if: needs.check-release-label.outputs.should-release == 'true'
uses: posthog/.github/.github/workflows/notify-approval-needed.yml@main
with:
slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }}
slack_user_group_id: ${{ vars.GROUP_CLIENT_LIBRARIES_SLACK_GROUP_ID }}
secrets:
slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }}
posthog_project_api_key: ${{ secrets.POSTHOG_PROJECT_API_KEY }}
release:
name: Release and publish
needs: [check-release-label, notify-approval-needed]
runs-on: ubuntu-latest
# Use `always()` to ensure the job runs even if notify-approval-needed is skipped,
# but still depend on it to access `needs.notify-approval-needed.outputs.slack_ts`
if: always() && needs.check-release-label.outputs.should-release == 'true'
environment: "Release" # This will require an approval from a maintainer, they are notified in Slack above
permissions:
contents: write
actions: write
id-token: write
steps:
- name: Notify Slack - Approved
if: needs.notify-approval-needed.outputs.slack_ts != ''
uses: posthog/.github/.github/actions/slack-thread-reply@main
with:
slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }}
slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }}
thread_ts: ${{ needs.notify-approval-needed.outputs.slack_ts }}
message: "✅ Release approved! Version bump in progress..."
emoji_reaction: "white_check_mark"
- name: Get GitHub App token
id: releaser
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.GH_APP_POSTHOG_PYTHON_RELEASER_APP_ID }}
private-key: ${{ secrets.GH_APP_POSTHOG_PYTHON_RELEASER_PRIVATE_KEY }}
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: master
fetch-depth: 0
token: ${{ steps.releaser.outputs.token }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11.11
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
pyproject-file: "pyproject.toml"
- name: Install Rust
uses: dtolnay/rust-toolchain@0b1efabc08b657293548b77fb76cc02d26091c7e
with:
toolchain: 1.91.1
components: cargo
- name: Cache Sampo CLI
id: cache-sampo
uses: actions/cache@v3
with:
path: ~/.cargo/bin/sampo
key: sampo-${{ runner.os }}-${{ runner.arch }}
- name: Install Sampo CLI
if: steps.cache-sampo.outputs.cache-hit != 'true'
run: cargo install sampo
- name: Install dependencies
run: uv sync --extra dev
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Prepare release with Sampo
id: sampo-release
env:
GITHUB_TOKEN: ${{ steps.releaser.outputs.token }}
run: |
sampo release
new_version=$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")
echo "new_version=$new_version" >> "$GITHUB_OUTPUT"
- name: Sync version to posthog/version.py
run: |
echo 'VERSION = "${{ steps.sampo-release.outputs.new_version }}"' > posthog/version.py
- name: Commit release changes
id: commit-release
env:
GITHUB_TOKEN: ${{ steps.releaser.outputs.token }}
run: |
git add -A
if git diff --staged --quiet; then
echo "No changes to commit"
echo "committed=false" >> "$GITHUB_OUTPUT"
else
git commit -m "chore: Release v${{ steps.sampo-release.outputs.new_version }}"
git push origin master
echo "committed=true" >> "$GITHUB_OUTPUT"
fi
# Publishing is done manually (not via `sampo publish`) because we need to
# publish both `posthog` and `posthoganalytics` packages to PyPI.
# Sampo only knows about the `posthog` package, so we handle both here.
# Both packages use PyPI OIDC trusted publishing (no API tokens needed).
- name: Build posthog
if: steps.commit-release.outputs.committed == 'true'
run: uv run make build_release
- name: Publish posthog to PyPI
if: steps.commit-release.outputs.committed == 'true'
uses: pypa/gh-action-pypi-publish@release/v1
# The `posthoganalytics` package is a mirror of `posthog` published under
# a different name for backwards compatibility. The make target handles
# copying, renaming imports, and building the dist automatically.
- name: Build posthoganalytics
if: steps.commit-release.outputs.committed == 'true'
run: uv run make build_release_analytics
- name: Publish posthoganalytics to PyPI
if: steps.commit-release.outputs.committed == 'true'
uses: pypa/gh-action-pypi-publish@release/v1
# We skip `sampo publish` (which normally creates the tag) because we
# need to publish both posthog and posthoganalytics manually, so we
# create the tag ourselves.
- name: Tag release
if: steps.commit-release.outputs.committed == 'true'
run: git tag "v${{ steps.sampo-release.outputs.new_version }}"
- name: Push tags
if: steps.commit-release.outputs.committed == 'true'
run: git push origin --tags
- name: Create GitHub Release
if: steps.commit-release.outputs.committed == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release create "v${{ steps.sampo-release.outputs.new_version }}" --generate-notes
- name: Dispatch generate-references
if: steps.commit-release.outputs.committed == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh workflow run generate-references.yml --ref master
# Notify in case of a failure
- name: Send failure event to PostHog
if: ${{ failure() }}
uses: PostHog/posthog-github-action@v0.1
with:
posthog-token: "${{ secrets.POSTHOG_PROJECT_API_KEY }}"
event: "posthog-python-github-release-workflow-failure"
properties: >-
{
"commitSha": "${{ github.sha }}",
"jobStatus": "${{ job.status }}",
"ref": "${{ github.ref }}",
"version": "v${{ steps.sampo-release.outputs.new_version }}"
}
- name: Notify Slack - Failed
if: ${{ failure() && needs.notify-approval-needed.outputs.slack_ts != '' }}
uses: posthog/.github/.github/actions/slack-thread-reply@main
with:
slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }}
slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }}
thread_ts: ${{ needs.notify-approval-needed.outputs.slack_ts }}
message: "❌ Failed to release `posthog-python@v${{ steps.sampo-release.outputs.new_version }}`! <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|View logs>"
emoji_reaction: "x"
notify-released:
name: Notify Slack - Released
needs: [check-release-label, notify-approval-needed, release]
runs-on: ubuntu-latest
if: always() && needs.release.result == 'success' && needs.notify-approval-needed.outputs.slack_ts != ''
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Notify Slack - Released
uses: posthog/.github/.github/actions/slack-thread-reply@main
with:
slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }}
slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }}
thread_ts: ${{ needs.notify-approval-needed.outputs.slack_ts }}
message: "🚀 posthog-python released successfully!"
emoji_reaction: "rocket"