-
Notifications
You must be signed in to change notification settings - Fork 0
112 lines (101 loc) · 4.14 KB
/
Copy pathpromote-develop-to-main.yml
File metadata and controls
112 lines (101 loc) · 4.14 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
name: promote-develop-to-main
# Promotes develop to main automatically after all CI checks pass.
#
# Security model:
# - Only triggers on CI success on develop — never on failed CI.
# - PR creation uses GITHUB_TOKEN (github-actions[bot]).
# - Auto-approval uses PROMOTE_TOKEN (an admin PAT or App token with repo
# scope) — a different actor from the PR creator, so GitHub allows the
# approval. PROMOTE_TOKEN and RELEASE_TOKEN are sourced from `meta/envctl`
# and injected as repository/org secrets. They may point to the same credential,
# but they are distinct roles: PROMOTE_TOKEN approves develop→main promotion,
# RELEASE_TOKEN is used by release.yml to cut releases.
# - Without PROMOTE_TOKEN the PR is created but waits for a human reviewer.
# - Rebase merge preserves individual conventional commits so release-please
# can compute the correct version bump from the full commit history.
on:
workflow_run:
workflows: [ci]
branches: [develop]
types: [completed]
workflow_dispatch:
permissions:
contents: write
pull-requests: write
concurrency:
group: promote-develop-to-main
cancel-in-progress: false
jobs:
promote:
name: Promote develop → main
runs-on: ubuntu-latest
timeout-minutes: 10
if: "github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success'"
steps:
- name: Find or create promote PR
id: pr
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const { data: prs } = await github.rest.pulls.list({
owner,
repo,
state: 'open',
head: `${owner}:develop`,
base: 'main',
});
if (prs.length > 0) {
const existing = prs[0];
core.setOutput('number', String(existing.number));
core.setOutput('url', existing.html_url);
core.info(`Found existing promote PR #${existing.number}: ${existing.html_url}`);
return;
}
const { data: pr } = await github.rest.pulls.create({
owner,
repo,
title: 'chore: promote develop → main',
body: [
'Automated promotion of `develop` to `main` after CI passed.',
'',
'This PR is managed by the `promote-develop-to-main` workflow and',
'stays open perpetually — it is updated each time `develop` advances.',
'',
'**Do not close this PR manually.** The workflow will recreate it.',
].join('\n'),
head: 'develop',
base: 'main',
});
core.setOutput('number', String(pr.number));
core.setOutput('url', pr.html_url);
core.info(`Created promote PR #${pr.number}: ${pr.html_url}`);
- name: Auto-approve (requires PROMOTE_TOKEN)
if: steps.pr.outputs.number != ''
env:
GH_TOKEN: ${{ secrets.PROMOTE_TOKEN }}
PR_NUMBER: ${{ steps.pr.outputs.number }}
PR_URL: ${{ steps.pr.outputs.url }}
run: |
if [ -z "$GH_TOKEN" ]; then
echo "::notice title=Manual approval required::PROMOTE_TOKEN secret is not set." \
"PR #${PR_NUMBER} needs a human approval before it can auto-merge." \
"Add a PROMOTE_TOKEN repository/org secret (admin PAT or App token with repo scope)" \
"to enable fully automated promotion. PR: ${PR_URL}"
exit 0
fi
gh pr review "$PR_NUMBER" \
--repo "${{ github.repository }}" \
--approve \
--body "Auto-approved: CI passed on \`develop\`. Promoting to \`main\`."
- name: Enable auto-merge (rebase)
if: steps.pr.outputs.number != ''
env:
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ steps.pr.outputs.number }}
run: |
gh pr merge "$PR_NUMBER" \
--repo "${{ github.repository }}" \
--auto \
--rebase