Repository navigation
277 lines (244 loc) · 10.7 KB
/
Copy pathdeploy.yaml
File metadata and controls
277 lines (244 loc) · 10.7 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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
name: deploy
# =======================
# FORRT Website Deployment
# =======================
# Purpose: Build and deploy the FORRT Hugo website to production
# Triggers: Push to main, manual dispatch, or data updates
# Target: Production (forrt.org)
# Note: Staging deployments are handled by staging-aggregate.yaml
on:
push:
branches:
- main
workflow_dispatch:
repository_dispatch:
types: [data-update]
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
# Note: PR staging deployments are handled by staging-aggregate.yaml
# This workflow focuses on production deployments
jobs:
build:
name: Build
runs-on: ubuntu-22.04
permissions:
contents: read
actions: read # Needed for artifact access
env:
HUGO_VERSION: "0.158.0"
HUGO_EXTENDED: true
steps:
# =======================
# Repository Setup
# =======================
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
# Hugo derives page dates from `git log --name-only`, and Git quotes
# non-ASCII paths (glossary terms, accented resource titles) unless this
# is off. Quoted paths never match, leaving those pages without a date.
- name: Let Git report non-ASCII paths unquoted
run: git config core.quotepath false
# =======================
# Data Artifact Retrieval
# =======================
# The repository contains a generated seed copy of curated resources.
# Remove it before overlaying the artifact so rows removed from the
# source sheet cannot survive in the deployed site.
- name: Clear generated curated resources
run: |
find content/curated_resources -maxdepth 1 -type f ! -name '_index.md' -delete
- name: Try to download data artifact
id: download-artifact
uses: dawidd6/action-download-artifact@07ab29fd4a977ae4d2b275087cf67563dfdf0295
continue-on-error: true
with:
workflow: data-processing.yml
name: data-artifact
path: .
github_token: ${{ secrets.GITHUB_TOKEN }}
search_artifacts: true
if_no_artifact_found: warn
# =======================
# Data Processing (Fallback)
# =======================
- name: Run data processing if artifact missing
id: data-processing
if: steps.download-artifact.outcome == 'failure'
env:
GITHUB_TOKEN: ${{ secrets.FORRT_PAT }}
run: |
set -e
# If this is a pull request, we can't easily trigger the external workflow and wait for it
# in the same way (or maybe we can, but let's stick to the plan).
# Actually, for PRs, we might want to just warn and proceed if it's not critical,
# OR trigger it if we really need the data.
# The original logic skipped it for PRs.
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo "::warning::Data artifact missing in PR. Skipping trigger."
echo "data_processing_triggered=false" >> $GITHUB_OUTPUT
exit 0
fi
# Determine branch ref to dispatch (must be a branch or tag)
REF="${GITHUB_REF#refs/heads/}"
if [ -z "$REF" ]; then
REF="main"
fi
echo "🚀 Dispatching data-processing workflow for ref: $REF because artifact was missing"
curl -s -X POST \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${{ github.repository }}/actions/workflows/data-processing.yml/dispatches" \
-d "{\"ref\":\"$REF\", \"inputs\": {\"skip_deploy\": \"true\"}}" \
|| { echo "::error::Failed to dispatch data-processing workflow"; exit 1; }
echo "data_processing_triggered=true" >> $GITHUB_OUTPUT
echo "⏳ Waiting for data-processing workflow run to start and complete..."
attempts=0
max_attempts=180
interval=10
# Wait a bit for the run to be created
sleep 10
while [ $attempts -lt $max_attempts ]; do
# Get the latest run triggered by workflow_dispatch
runs_json=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" -H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${{ github.repository }}/actions/workflows/data-processing.yml/runs?event=workflow_dispatch&branch=$REF&per_page=1")
run_id=$(echo "$runs_json" | jq -r '.workflow_runs[0].id')
status=$(echo "$runs_json" | jq -r '.workflow_runs[0].status')
conclusion=$(echo "$runs_json" | jq -r '.workflow_runs[0].conclusion')
if [ -n "$run_id" ] && [ "$run_id" != "null" ]; then
echo "Tracking data-processing run: $run_id (Status: $status)"
if [ "$status" = "completed" ]; then
if [ "$conclusion" = "success" ]; then
echo "✅ data-processing workflow completed successfully"
echo "run_id=$run_id" >> $GITHUB_OUTPUT
exit 0
else
echo "::error::data-processing workflow completed with conclusion: $conclusion"
exit 1
fi
fi
fi
attempts=$((attempts + 1))
sleep $interval
done
echo "::error::Timed out waiting for data-processing workflow"
exit 1
# =======================
# Data Artifact Retrieval (Retry)
# =======================
- name: Download data artifact (Retry)
id: download-artifact-retry
if: steps.download-artifact.outcome == 'failure' && steps.data-processing.outputs.data_processing_triggered == 'true'
uses: dawidd6/action-download-artifact@07ab29fd4a977ae4d2b275087cf67563dfdf0295
with:
workflow: data-processing.yml
name: data-artifact
path: .
github_token: ${{ secrets.GITHUB_TOKEN }}
run_id: ${{ steps.data-processing.outputs.run_id }}
# =======================
# Announcements (generated by create_announcements.yml, delivered as an artifact)
# =======================
- name: Download announcements artifact
id: download-announcements
uses: dawidd6/action-download-artifact@07ab29fd4a977ae4d2b275087cf67563dfdf0295
continue-on-error: true
with:
workflow: create_announcements.yml
name: announcements-artifact
path: .announcements
github_token: ${{ secrets.GITHUB_TOKEN }}
search_artifacts: true
if_no_artifact_found: warn
- name: Apply announcements
if: steps.download-announcements.outcome == 'success'
run: |
if [ -f .announcements/announcements.tar.gz ]; then
echo "📥 Applying announcement posts from artifact..."
# The artifact holds the full current set of announcements. Replace
# the committed seed bundles entirely so a post removed from the
# sheet (or set to Show = "no") is taken down rather than lingering
# from the checkout — tar extraction adds files but never deletes
# ones the archive no longer contains. The section index and any
# non-bundle files are preserved. Only runs when we actually have an
# artifact to apply, so announcements are never wiped without a
# replacement.
find content/post -mindepth 1 -maxdepth 1 -type d -exec rm -rf {} +
tar xzf .announcements/announcements.tar.gz
else
echo "::warning::announcements artifact present but tarball missing; skipping."
fi
# =======================
# Hugo Build Environment
# =======================
- name: Setup Hugo
uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f
with:
hugo-version: ${{ env.HUGO_VERSION }}
extended: ${{ env.HUGO_EXTENDED }}
# =======================
# Website Build
# =======================
- name: Build site
run: |
hugo --gc --minify --cleanDestinationDir --destination public
env:
HUGO_ENV: production
# =======================
# Sitemap Quality Check
# =======================
# Reports pages missing a <lastmod>, a timestamp stamped on most of the
# site, and a sample of pages whose date disagrees with their source
# (front-matter lastmod or Git). Warns only: a stale sitemap date must
# not block a deployment.
- name: Check sitemap lastmod
continue-on-error: true
run: python3 scripts/check_sitemap_lastmod.py public/sitemap.xml --compare-source --sample 200
# =======================
# Deployment Artifact
#========================================
# Upload built website as artifact for deployment
#========================================
- name: Upload site artifact
uses: actions/upload-artifact@v7
with:
name: forrt-website-${{ github.run_number }}
path: public/
retention-days: 1
# =======================
# Built HTML Regression Checks
# =======================
- name: Check built HTML (headings, conditional assets, image alt and dimensions)
run: |
python3 scripts/check_seo_html.py public
#========================================
# Deploy website to production GitHub Pages
# Note: Staging deployments are handled by staging-aggregate.yaml
#========================================
deploy-prod:
name: Deploy - Production
runs-on: ubuntu-22.04
permissions:
contents: write
needs: build
if: github.event.repository.fork == false
steps:
#========================================
# Download website artifact for production deployment
#========================================
- name: Download Artifact - Website
uses: actions/download-artifact@v7
with:
name: forrt-website-${{ github.run_number }}
path: ${{ github.repository }}/forrt-website
#========================================
# Deploy website to production GitHub Pages
#========================================
- name: Deploy - GitHub Pages
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ${{ github.repository }}/forrt-website
publish_branch: gh-pages
cname: forrt.org