forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
213 lines (187 loc) · 8.58 KB
/
Copy pathdesktop_auto_release.yml
File metadata and controls
213 lines (187 loc) · 8.58 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
name: Build Desktop Release Candidate
on:
workflow_dispatch:
# Continuous deployment: plan a beta candidate on every macOS-affecting merge to
# main. The candidate flows through the two-machine qualification pipeline
# (desktop_qualify_beta.yml: Codemagic primary lane + self-hosted qualify-m1-studio
# and qualify-m4-mini fallbacks); on qualification success desktop_promote_beta.yml
# advances the beta channel to the Codemagic-built, notarized, Sparkle-signed
# artifact. The push filter is intentionally coarse (the planner does the precise
# releasable-change check, excluding CHANGELOG/AGENTS/changelog/Backend-Rust); the
# quiet-window, exact-SHA, and one-active-release fences still admit at most one
# candidate at a time, so bursts collapse to the newest SHA. Keep these paths in
# lockstep with DESKTOP_RELEASE_PATHS in plan-desktop-release.py; the alignment is
# enforced by test_push_paths_cover_releasable_desktop_paths.
push:
branches: [main]
paths:
- 'desktop/macos/**'
- 'codemagic.yaml'
- '.github/scripts/plan-desktop-release.py'
- '.github/workflows/desktop_auto_release.yml'
- '.github/workflows/desktop-swift-ci.yml'
schedule:
# Poll every 15 min. The push trigger fires immediately on merge, but at that
# instant the change is inside the quiet window AND its required CI checks
# (Build & Tests / Release Compile / Release Eligibility, ~10-20 min) are not
# yet green, so the planner fail-closes. This frequent backstop re-evaluates
# shortly after those checks settle and the active-release fence clears, so a
# candidate reliably cuts without waiting for the next hour. Builds stay
# serialized by the one-active-release fence, so this cannot pile up builds.
- cron: '*/15 * * * *'
permissions:
contents: write
pull-requests: write
jobs:
plan-release:
runs-on: ubuntu-latest
concurrency:
group: desktop-release-planner-main
cancel-in-progress: false
outputs:
should_release: ${{ steps.plan.outputs.should_release }}
reason: ${{ steps.plan.outputs.reason }}
source_sha: ${{ steps.plan.outputs.source_sha }}
steps:
- name: Checkout
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Generate Omi Bot token
id: app-token
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.OMI_BOT_APP_ID }}
private-key: ${{ secrets.OMI_BOT_PRIVATE_KEY }}
- name: Plan desktop release
id: plan
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
python3 .github/scripts/plan-desktop-release.py \
--repository "${{ github.repository }}"
- name: Show release plan
run: echo "${{ steps.plan.outputs.reason }}"
# Continuous deployment: candidate creation is gated only by the cheap, hosted
# CI checks the planner verifies (`Release Eligibility`, `Desktop Swift Build &
# Tests`, `Desktop Swift Release Compile` on the exact source SHA). The heavy
# validation runs AFTER the candidate exists, in the two-machine qualification
# pipeline (desktop_qualify_beta.yml) — a candidate that fails qualification is
# simply never promoted to Beta, so no self-hosted pre-candidate gate is needed.
# (The former trusted-M1 pre-tag-readiness gate was a single point of failure in
# front of immutable tag creation and contradicted "create on every change, then
# qualify"; desktop/macos/scripts/pre-tag-readiness.sh remains for local use.)
tag-release:
needs: [plan-release]
if: needs.plan-release.outputs.should_release == 'true'
runs-on: ubuntu-latest
concurrency:
group: desktop-auto-release-tag-main
cancel-in-progress: false
steps:
- name: Checkout
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Generate Omi Bot token
id: app-token
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.OMI_BOT_APP_ID }}
private-key: ${{ secrets.OMI_BOT_PRIVATE_KEY }}
- name: Recheck desktop release queue before tagging
id: recheck
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
if [ -z "${GH_TOKEN:-}" ]; then
echo "Omi Bot token not available; cannot inspect previous release build status."
exit 1
fi
python3 .github/scripts/plan-desktop-release.py \
--repository "${{ github.repository }}"
- name: Checkout exact releasable desktop source
if: steps.recheck.outputs.should_release == 'true'
uses: actions/checkout@v7
with:
ref: ${{ steps.recheck.outputs.source_sha }}
fetch-depth: 0
- name: Compute next version and consolidate changelog
if: steps.recheck.outputs.should_release == 'true'
id: version
run: |
# Get latest desktop release tag
LATEST=$(git tag -l 'v*-macos' | sort -V | tail -1)
if [ -z "$LATEST" ]; then
VERSION="0.0.1"
else
# Strip v prefix and +build-macos suffix e.g. v0.11.11+11011-macos -> 0.11.11
VER=$(echo "$LATEST" | sed -E 's/^v([0-9.]+)\+[0-9]+-macos$/\1/')
MAJOR=$(echo "$VER" | cut -d. -f1)
MINOR=$(echo "$VER" | cut -d. -f2)
PATCH=$(echo "$VER" | cut -d. -f3)
PATCH=$((${PATCH:-0} + 1))
VERSION="$MAJOR.$MINOR.$PATCH"
fi
# Build number: 0.11.12 -> 11012 (each component * 1000, summed)
BUILD_NUMBER=$(echo "$VERSION" | tr '.' '\n' | awk '{s=s*1000+$1}END{print s}')
RELEASE_TAG="v${VERSION}+${BUILD_NUMBER}-macos"
echo "Latest tag : ${LATEST:-none}"
echo "New version: $VERSION"
echo "New tag : $RELEASE_TAG"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "release_tag=$RELEASE_TAG" >> "$GITHUB_OUTPUT"
# Consolidate unreleased changelog fragments into a versioned release
TODAY=$(date -u +%Y-%m-%d)
python3 .github/scripts/desktop-changelog.py consolidate \
--version "$VERSION" \
--date "$TODAY" \
--write
- name: Commit changelog and create tag
if: steps.recheck.outputs.should_release == 'true'
run: |
VERSION="${{ steps.version.outputs.version }}"
RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add desktop/macos/CHANGELOG.json desktop/macos/changelog
git commit -m "chore: consolidate changelog for v${VERSION}" || echo "No changelog changes to commit"
# The planner checked and this job checked out the newest queued
# releasable desktop source SHA.
# Tag this commit so Codemagic receives the consolidated release notes too.
# NOTE: commit message must NOT contain [skip ci].
git tag "$RELEASE_TAG"
git push origin "$RELEASE_TAG"
- name: Create and auto-merge PR to sync changelog back to main
if: steps.recheck.outputs.should_release == 'true'
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
if [ -z "${GH_TOKEN:-}" ]; then
echo "Omi Bot token not available; cannot auto-merge changelog PR."
exit 1
fi
VERSION="${{ steps.version.outputs.version }}"
BRANCH="changelog/v${VERSION}"
git checkout -B "$BRANCH"
git push --force-with-lease origin "$BRANCH"
PR_NUMBER=$(gh pr list \
--head "$BRANCH" \
--base main \
--state open \
--json number \
--jq '.[0].number')
if [ -z "$PR_NUMBER" ]; then
PR_URL=$(gh pr create \
--title "Update desktop changelog for v${VERSION} [skip ci]" \
--body "Auto-generated: consolidates unreleased changelog fragments into v${VERSION} and regenerates CHANGELOG.json." \
--base main \
--head "$BRANCH")
PR_NUMBER=$(echo "$PR_URL" | awk -F/ '{print $NF}')
fi
# Merge changelog PR in protected branches:
# 1) admin merge if allowed, 2) auto-merge if repo supports it, 3) regular merge if already mergeable.
gh pr merge "$PR_NUMBER" --merge --admin || \
gh pr merge "$PR_NUMBER" --merge --auto || \
gh pr merge "$PR_NUMBER" --merge || \
echo "Changelog PR #$PR_NUMBER requires manual merge."