-
Notifications
You must be signed in to change notification settings - Fork 0
223 lines (201 loc) · 9.5 KB
/
Copy pathdeploy-pages.yml
File metadata and controls
223 lines (201 loc) · 9.5 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
name: Deploy Pages
on:
# Deploy immediately when main is updated.
push:
branches:
- main
# Re-deploy whenever any service build finishes (on any branch).
workflow_run:
workflows: ["Spring API", "Python Help Service", "Python Recipe Service", "Web Client"]
types: [completed]
# Clean up coverage store when a PR is closed.
pull_request:
types: [closed]
# Manual trigger to force-refresh all coverage for main.
workflow_dispatch:
concurrency:
group: pages
cancel-in-progress: false
permissions:
contents: write # push to coverage-data store branch
pages: write
id-token: write
actions: read # download artifacts from other workflow runs
jobs:
# ── Remove a closed PR's coverage from the store ───────────────────────────
cleanup:
if: github.event_name == 'pull_request' && github.event.action == 'closed'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: coverage-data
path: store
continue-on-error: true
- name: Remove branch from store
run: |
[ -d store ] || exit 0
KEY="${{ github.event.pull_request.head.ref }}"
KEY="${KEY//\//-}"
rm -rf "store/coverage/$KEY"
cd store
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add .
git diff --staged --quiet || \
git commit -m "Remove coverage: $KEY (PR #${{ github.event.pull_request.number }} closed)"
git push origin coverage-data
# ── Update coverage store and redeploy Pages ───────────────────────────────
deploy:
if: >
github.event_name == 'workflow_dispatch' ||
github.event_name == 'push' ||
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
# ── Identify what triggered this run ─────────────────────────────────────
- name: Set context
run: |
if [ "${{ github.event_name }}" = "workflow_run" ]; then
BRANCH="${{ github.event.workflow_run.head_branch }}"
echo "COVERAGE_KEY=${BRANCH//\//-}" >> $GITHUB_ENV
case "${{ github.event.workflow_run.name }}" in
"Spring API") echo "ARTIFACT=spring-api-coverage" && echo "SERVICE=spring-api" ;;
"Python Help Service") echo "ARTIFACT=help-service-coverage" && echo "SERVICE=py-help" ;;
"Python Recipe Service") echo "ARTIFACT=recipe-service-coverage" && echo "SERVICE=py-recipe" ;;
"Web Client") echo "ARTIFACT=web-client-coverage" && echo "SERVICE=web-client" ;;
esac >> $GITHUB_ENV
else
echo "COVERAGE_KEY=main" >> $GITHUB_ENV
fi
# ── Check out (or initialise) the coverage-data store branch ─────────────
- uses: actions/checkout@v4
id: checkout-store
with:
ref: coverage-data
path: store
fetch-depth: 1
continue-on-error: true
- name: Init store branch
if: steps.checkout-store.outcome == 'failure'
run: |
mkdir store && cd store
git init
git remote add origin https://x-access-token:${{ github.token }}@github.com/${{ github.repository }}.git
git checkout -b coverage-data
mkdir -p coverage
git -c user.name="github-actions[bot]" -c user.email="github-actions[bot]@users.noreply.github.com" \
commit --allow-empty -m "Initialize coverage store"
# ── Download coverage ─────────────────────────────────────────────────────
# workflow_run: download the one service that just built, from that exact run.
- name: Download service coverage
if: github.event_name == 'workflow_run'
uses: dawidd6/action-download-artifact@v6
with:
run_id: ${{ github.event.workflow_run.id }}
name: ${{ env.ARTIFACT }}
path: store/coverage/${{ env.COVERAGE_KEY }}/${{ env.SERVICE }}
if_no_artifact_found: ignore
# push/workflow_dispatch: pull latest coverage for all services on main.
- name: Download Spring API coverage
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
uses: dawidd6/action-download-artifact@v6
with:
workflow: build-spring-api.yml
branch: main
name: spring-api-coverage
path: store/coverage/main/spring-api
if_no_artifact_found: ignore
- name: Download Help Service coverage
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
uses: dawidd6/action-download-artifact@v6
with:
workflow: build-help-service.yml
branch: main
name: help-service-coverage
path: store/coverage/main/py-help
if_no_artifact_found: ignore
- name: Download Recipe Service coverage
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
uses: dawidd6/action-download-artifact@v6
with:
workflow: build-recipe-service.yml
branch: main
name: recipe-service-coverage
path: store/coverage/main/py-recipe
if_no_artifact_found: ignore
- name: Download Web Client coverage
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
uses: dawidd6/action-download-artifact@v6
with:
workflow: build-client.yml
branch: main
name: web-client-coverage
path: store/coverage/main/web-client
if_no_artifact_found: ignore
# ── Persist updated coverage to the store ────────────────────────────────
- name: Commit to store
run: |
cd store
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add .
git diff --staged --quiet && echo "No coverage changes" && exit 0
git commit -m "Update coverage: ${{ env.COVERAGE_KEY || 'main (rebuild)' }}"
# Rebase in case another branch committed while we were running.
REMOTE="https://x-access-token:${{ github.token }}@github.com/${{ github.repository }}.git"
git pull --rebase "$REMOTE" coverage-data 2>/dev/null || true
git push "$REMOTE" HEAD:coverage-data
# ── Assemble Pages site ───────────────────────────────────────────────────
- name: Assemble site
run: |
mkdir -p site
[ -d store/coverage ] && cp -r store/coverage/. site/
# API docs
npx --yes @redocly/cli@2.34.0 build-docs api/openapi.yaml --output site/api/index.html
# Per-branch index (links to each service subfolder)
for branch_dir in site/*/; do
[ -d "$branch_dir" ] || continue
branch=$(basename "$branch_dir")
[ "$branch" = "api" ] && continue
{
printf '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8">'
printf '<title>Coverage: %s</title>' "$branch"
echo '<style>body{font-family:sans-serif;max-width:600px;margin:4rem auto}a{color:#0969da}ul{line-height:2}</style>'
echo '</head><body>'
printf '<h1>Coverage: %s</h1><p><a href="../">← All</a></p><ul>' "$branch"
for svc_dir in "$branch_dir"*/; do
[ -d "$svc_dir" ] || continue
svc=$(basename "$svc_dir")
printf '<li><a href="%s/">%s</a></li>' "$svc" "$svc"
done
echo '</ul></body></html>'
} > "$branch_dir/index.html"
done
# Top-level index
{
echo '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8">'
echo '<title>Team DevSecOps</title>'
echo '<style>body{font-family:sans-serif;max-width:600px;margin:4rem auto}a{color:#0969da}ul{line-height:2}h2{margin-top:2rem}</style>'
echo '</head><body><h1>Team DevSecOps</h1>'
echo '<h2>API</h2><ul><li><a href="api/">API Documentation</a></li></ul>'
echo '<h2>Coverage</h2><ul>'
for branch_dir in site/*/; do
[ -d "$branch_dir" ] || continue
branch=$(basename "$branch_dir")
[ "$branch" = "api" ] && continue
printf '<li><a href="%s/">%s</a></li>\n' "$branch" "$branch"
done
echo '</ul></body></html>'
} > site/index.html
# ── Deploy ────────────────────────────────────────────────────────────────
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v4
with:
path: site
- id: deployment
uses: actions/deploy-pages@v4