-
Notifications
You must be signed in to change notification settings - Fork 3.6k
177 lines (154 loc) · 6.87 KB
/
Copy pathsite-publish-live.yml
File metadata and controls
177 lines (154 loc) · 6.87 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
name: '🌐 Landing Site · 🚀 Publish (Live)'
# =============================================================================
# Unified Site — Publish to mlsysbook.ai
# =============================================================================
#
# Builds the unified site (landing + about + community + newsletter) and
# deploys to the live site via gh-pages. Syncs newsletter from Buttondown
# before building so posts are always current.
#
# Flow:
# 1. SYNC — Fetch latest newsletter posts from Buttondown API
# 2. BUILD — Quarto render entire site
# 3. VALIDATE — Verify all expected pages exist
# 4. DEPLOY — Push to gh-pages branch (only site subsites, preserves others)
#
# Triggers:
# - Manual: workflow_dispatch
# - Called by: publish-all-live.yml (orchestrator)
#
# Deploys to: gh-pages → mlsysbook.ai/{about,community,newsletter}/
# Secrets: BUTTONDOWN_API_KEY, GITHUB_TOKEN
#
# Related:
# - site-preview-dev.yml — Same site, deployed to dev preview
# - sync-newsletter.yml — Dedicated daily newsletter sync
# - publish-all-live.yml — Orchestrates all live deploys
#
# =============================================================================
on:
workflow_dispatch: {}
workflow_call: {}
permissions:
contents: write
actions: read
# NB: gh-pages-deploy concurrency is declared on the build-and-deploy job
# only. The guard runs without holding the lock.
jobs:
# Block publish unless the latest dev validate run for this site is green.
# See .github/workflows/infra-publish-guard.yml for guard semantics.
guard:
name: '🛡️ Validate-Dev Green Gate'
uses: ./.github/workflows/infra-publish-guard.yml
with:
validate_workflow: site-validate-dev.yml
build-and-deploy:
name: '🌐 Deploy Landing Site'
needs: [guard]
runs-on: ubuntu-latest
concurrency:
group: gh-pages-deploy
cancel-in-progress: false
steps:
- name: 📥 Checkout
uses: actions/checkout@v6
- name: 🐍 Setup Python
uses: actions/setup-python@v6
with:
python-version: ${{ vars.PYTHON_VERSION || '3.12' }}
- name: 📬 Sync newsletter from Buttondown
env:
BUTTONDOWN_API_KEY: ${{ secrets.BUTTONDOWN_API_KEY }}
run: |
pip install -r site/newsletter/requirements.txt
python3 site/newsletter/bin/news pull
echo "✅ Newsletter posts synced"
- name: 🔧 Setup Quarto
uses: quarto-dev/quarto-actions/setup@v2
- name: 📊 Install stats dependencies
run: pip install -r site/scripts/requirements.txt
- name: 🔨 Build unified site
working-directory: site
env:
# See site-validate-dev.yml for why the token matters here: the
# pre-render stats step calls the GitHub search API, which is
# rate-limited to 10 req/min per IP when unauthenticated.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUTTONDOWN_API_KEY: ${{ secrets.BUTTONDOWN_API_KEY }}
# Readership from the GA4 property behind the Looker Studio report.
# Absent the secret the build keeps the committed figures rather than
# failing, so a credential lapse degrades quietly instead of blocking
# a deploy. Deliberately not set in site-validate-dev.yml, which runs
# on pull_request and would expose it to forks.
GA4_SERVICE_ACCOUNT_JSON: ${{ secrets.GA4_SERVICE_ACCOUNT_JSON }}
run: |
quarto render
touch _build/.nojekyll
echo "✅ Site rendered: $(find _build -name '*.html' | wc -l) pages"
- name: 🔍 Validate build
run: |
for page in index.html about/index.html community/index.html newsletter/index.html; do
if [ ! -f "site/_build/$page" ]; then
echo "❌ CRITICAL: $page missing from build. Aborting."
exit 1
fi
done
echo "✅ All site pages validated"
- name: 🚀 Deploy to gh-pages
run: |
rm -rf gh-pages-repo
git clone --depth=1 --branch=gh-pages \
https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git \
gh-pages-repo
cd gh-pages-repo
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
BUILD_DIR="${{ github.workspace }}/site/_build"
# Deploy subsites to their directories
for subsite in about community newsletter; do
rm -rf "$subsite"
cp -r "$BUILD_DIR/$subsite" .
done
# Deploy landing page to root (preserve directories managed by other workflows).
# site_libs MUST be deployed at root: the about/community/newsletter HTML
# references ../site_libs/... which resolves to /site_libs/ at runtime.
# Skipping it (as we did before 2026-04-28) leaves those subsites without
# Bootstrap/Quarto CSS — the navbar collapses to a raw <ul>, the hero
# disappears into 3000 px of empty whitespace, and dark mode is unstyled.
for item in "$BUILD_DIR"/*; do
basename="$(basename "$item")"
if [[ -d "$basename" ]] && [[ "$basename" =~ ^(book|kits|tinytorch|labs|mlsysim|slides|instructors|interviews|staffml|about|community|newsletter)$ ]]; then
continue
fi
rm -rf "./$basename"
cp -r "$item" .
done
touch .nojekyll
[ -f "index.html" ] || { echo "❌ CRITICAL: Landing index.html missing."; exit 1; }
git add .
git commit -m "🌐 Deploy site live - ${{ github.sha }}" --allow-empty || echo "🟡 Nothing to commit"
PUSHED=false
for i in 1 2 3; do
if git push origin gh-pages 2>/dev/null; then
echo "✅ Push succeeded on attempt $i"
PUSHED=true
break
fi
echo "⚠️ Push failed (attempt $i/3), pulling with rebase..."
git pull --rebase origin gh-pages || true
done
if [ "$PUSHED" != "true" ]; then
echo "❌ Push failed after 3 attempts."
exit 1
fi
echo "✅ Site deployed to mlsysbook.ai"
- name: 📊 Summary
run: |
echo "## 🌐 Landing Site Publish Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Page | URL |" >> $GITHUB_STEP_SUMMARY
echo "|------|-----|" >> $GITHUB_STEP_SUMMARY
echo "| 🏠 Landing | https://mlsysbook.ai/ |" >> $GITHUB_STEP_SUMMARY
echo "| 📋 About | https://mlsysbook.ai/about/ |" >> $GITHUB_STEP_SUMMARY
echo "| 🌍 Community | https://mlsysbook.ai/community/ |" >> $GITHUB_STEP_SUMMARY
echo "| 📬 Newsletter | https://mlsysbook.ai/newsletter/ |" >> $GITHUB_STEP_SUMMARY