-
Notifications
You must be signed in to change notification settings - Fork 3
198 lines (171 loc) · 6.44 KB
/
Copy pathrelease.yml
File metadata and controls
198 lines (171 loc) · 6.44 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
name: Promote Main to Release Branches
permissions:
contents: write
on:
workflow_dispatch:
inputs:
target:
description: "Promote target release branch selection"
required: true
default: "all"
type: choice
options:
- all
- web
- admin
- university
force_redeploy:
description: "When up to date, skip divergence and print manual redeploy guidance"
required: true
default: false
type: boolean
jobs:
resolve_targets:
name: Resolve release targets
runs-on: ubuntu-latest
outputs:
targets: ${{ steps.resolve.outputs.targets }}
steps:
- name: Resolve selected targets
id: resolve
run: |
set -euo pipefail
TARGET="${{ github.event.inputs.target }}"
case "$TARGET" in
web)
TARGETS='["web"]'
;;
admin)
TARGETS='["admin"]'
;;
university)
TARGETS='["university"]'
;;
all)
TARGETS='["web","admin","university"]'
;;
*)
echo "Unsupported target: $TARGET" >&2
exit 1
;;
esac
echo "targets=$TARGETS" >> "$GITHUB_OUTPUT"
release_target:
name: Release ${{ matrix.target }}
runs-on: ubuntu-latest
needs: resolve_targets
strategy:
fail-fast: false
matrix:
target: ${{ fromJson(needs.resolve_targets.outputs.targets) }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Resolve app release config
id: app
env:
CREATE_TAG: "false"
TARGET: ${{ matrix.target }}
run: bash .github/scripts/create-headver-tag.sh
- name: Detect target changes
id: changes
env:
FORCE_REDEPLOY: ${{ github.event.inputs.force_redeploy }}
PATH_REGEX: ${{ steps.app.outputs.path_regex }}
RELEASE_BRANCH: ${{ steps.app.outputs.release_branch }}
TARGET: ${{ matrix.target }}
run: |
set -euo pipefail
git fetch origin main
MAIN_SHA=$(git rev-parse origin/main)
if git fetch origin "$RELEASE_BRANCH"; then
RELEASE_SHA=$(git rev-parse "origin/$RELEASE_BRANCH")
else
RELEASE_SHA=""
fi
{
echo "## Release target: $TARGET"
echo "- Release branch: $RELEASE_BRANCH"
echo "- Main SHA: $MAIN_SHA"
} >> "$GITHUB_STEP_SUMMARY"
if [ -n "$RELEASE_SHA" ]; then
echo "- Current release SHA: $RELEASE_SHA" >> "$GITHUB_STEP_SUMMARY"
fi
echo "main_sha=$MAIN_SHA" >> "$GITHUB_OUTPUT"
echo "release_sha=$RELEASE_SHA" >> "$GITHUB_OUTPUT"
if [ -z "$RELEASE_SHA" ]; then
echo "should_release=true" >> "$GITHUB_OUTPUT"
echo "- Decision: release branch does not exist; creating it from main" >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
if [ "$MAIN_SHA" = "$RELEASE_SHA" ]; then
echo "should_release=false" >> "$GITHUB_OUTPUT"
{
echo "- Decision: already up to date"
if [ "$FORCE_REDEPLOY" = "true" ]; then
echo "- force_redeploy=true requested"
echo "- Skipped empty commit to keep release branch ancestry clean"
echo "- Trigger redeploy manually in Vercel if needed"
fi
} >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
CHANGED_FILES=$(git diff --name-only "origin/$RELEASE_BRANCH" origin/main)
RELEVANT_FILES=$(echo "$CHANGED_FILES" | grep -E "$PATH_REGEX" || true)
if [ -z "$RELEVANT_FILES" ]; then
echo "should_release=false" >> "$GITHUB_OUTPUT"
{
echo "- Decision: skipped; no $TARGET or shared changes"
echo "- Changed files were outside this target"
} >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
echo "should_release=true" >> "$GITHUB_OUTPUT"
{
echo "- Decision: release required"
echo "- Relevant changed files:"
echo "$RELEVANT_FILES" | sed 's/^/ - /'
} >> "$GITHUB_STEP_SUMMARY"
- name: Create app HeadVer tag
id: create_tag
if: steps.changes.outputs.should_release == 'true'
env:
TARGET: ${{ matrix.target }}
run: bash .github/scripts/create-headver-tag.sh
- name: Create GitHub Release
if: steps.changes.outputs.should_release == 'true'
uses: ncipollo/release-action@v1
with:
tag: ${{ steps.create_tag.outputs.tag }}
release_name: "${{ steps.create_tag.outputs.display_name }} Release ${{ steps.create_tag.outputs.tag }}"
body: |
Automated release created for ${{ steps.create_tag.outputs.display_name }}.
- Target: ${{ matrix.target }}
- Tag: ${{ steps.create_tag.outputs.tag }}
- Version: ${{ steps.create_tag.outputs.version }}
- Release branch: ${{ steps.app.outputs.release_branch }}
- Promoted main SHA: ${{ steps.changes.outputs.main_sha }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: Promote main branch to target release branch
if: steps.changes.outputs.should_release == 'true'
env:
RELEASE_BRANCH: ${{ steps.app.outputs.release_branch }}
RELEASE_SHA: ${{ steps.changes.outputs.release_sha }}
run: |
set -euo pipefail
if [ -z "$RELEASE_SHA" ]; then
git push origin origin/main:"refs/heads/$RELEASE_BRANCH"
echo "- $RELEASE_BRANCH: created from main" >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
if ! git merge-base --is-ancestor "origin/$RELEASE_BRANCH" origin/main; then
echo "- $RELEASE_BRANCH: non-ancestor detected, forcing reset to main" >> "$GITHUB_STEP_SUMMARY"
fi
git push --force-with-lease origin origin/main:"refs/heads/$RELEASE_BRANCH"
echo "- $RELEASE_BRANCH: updated" >> "$GITHUB_STEP_SUMMARY"
- name: Deployment note
if: steps.changes.outputs.should_release == 'true'
run: |
echo "- Note: Vercel production deploy is triggered by corresponding release branch update" >> "$GITHUB_STEP_SUMMARY"