-
Notifications
You must be signed in to change notification settings - Fork 4
133 lines (119 loc) · 5.06 KB
/
Copy pathstlc-promote.yml
File metadata and controls
133 lines (119 loc) · 5.06 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
name: Promote SDK changes
# Staging is the generator's integration history. Production `next` is the
# developer-facing queue for the next release. This workflow combines the
# latest released state with validated staging changes, then advances `next`.
# Release automation maintains the single versioned PR from `next` to `main`.
on:
push:
branches: [main]
workflow_dispatch: {}
permissions:
contents: read
jobs:
promote:
if: github.repository == 'kernel/kernel-python-sdk-staging'
runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
concurrency:
group: stlc-promote
cancel-in-progress: true
steps:
- name: Check out staging
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: Mint production token
id: production-token
uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1
with:
app-id: ${{ secrets.ADMIN_APP_ID }}
private-key: ${{ secrets.ADMIN_APP_PRIVATE_KEY }}
owner: kernel
repositories: kernel-python-sdk
permission-contents: write
permission-pull-requests: write
permission-workflows: write
- name: Fetch production branches
id: production
env:
GH_TOKEN: ${{ steps.production-token.outputs.token }}
PRODUCTION_REPO: kernel/kernel-python-sdk
run: |
set -euo pipefail
git remote add production \
"https://x-access-token:${GH_TOKEN}@github.com/${PRODUCTION_REPO}.git"
git fetch production main
if git ls-remote --exit-code --heads production next >/dev/null 2>&1; then
git fetch production next
echo "has_next=true" >> "$GITHUB_OUTPUT"
else
echo "has_next=false" >> "$GITHUB_OUTPUT"
fi
- name: Prepare the next release branch
env:
APP_SLUG: ${{ steps.production-token.outputs.app-slug }}
GH_TOKEN: ${{ steps.production-token.outputs.token }}
HAS_NEXT: ${{ steps.production.outputs.has_next }}
PRODUCTION_REPO: kernel/kernel-python-sdk
run: |
set -euo pipefail
bot_id=$(gh api "/users/${APP_SLUG}[bot]" --jq .id)
git config user.name "${APP_SLUG}[bot]"
git config user.email "${bot_id}+${APP_SLUG}[bot]@users.noreply.github.com"
open_conflict_pr() {
source_ref=$1
source_name=$2
advance_next=$3
conflict_branch=stlc/promotion-conflict
git merge --abort
existing=$(gh pr list --repo "$PRODUCTION_REPO" --base next \
--head "$conflict_branch" --state open --json url --jq '.[0].url // ""')
if [ -n "$existing" ]; then
echo "::error title=SDK promotion blocked::Resolve the existing recovery PR: $existing"
exit 1
fi
if [ "$advance_next" = "true" ]; then
git push production HEAD:refs/heads/next
fi
git push production "$source_ref:refs/heads/$conflict_branch" --force
body=$(mktemp)
printf '%s\n' \
'## SDK promotion conflict' \
'' \
"The automated promotion could not merge $source_name into the pending next release." \
'' \
'Resolve the conflicts on this branch, validate the SDK, mark this PR ready, and merge it with a merge commit.' \
'' \
'After merging, rerun the staging Promote SDK changes workflow to include any newer generated changes.' \
> "$body"
recovery_url=$(gh pr create --repo "$PRODUCTION_REPO" --draft \
--base next --head "$conflict_branch" \
--title 'chore: resolve SDK promotion conflict' --body-file "$body")
echo "::error title=SDK promotion conflict::Resolve the recovery PR: $recovery_url"
exit 1
}
if [ "$HAS_NEXT" = "true" ]; then
git checkout -B stlc/promote-next production/next
else
git checkout -B stlc/promote-next production/main
fi
if ! git merge-base --is-ancestor production/main HEAD; then
if ! git merge --no-edit production/main; then
open_conflict_pr production/main 'production main' false
fi
fi
if ! git merge-base --is-ancestor origin/main HEAD; then
if ! git merge --no-edit origin/main; then
open_conflict_pr origin/main 'validated staging changes' true
fi
fi
if [ "$HAS_NEXT" = "true" ]; then
git merge-base --is-ancestor production/next HEAD
fi
- name: Update the pending release
env:
GH_TOKEN: ${{ steps.production-token.outputs.token }}
run: |
set -euo pipefail
git push production HEAD:refs/heads/next
echo "Updated production next; the versioned release PR will be opened or refreshed."