-
Notifications
You must be signed in to change notification settings - Fork 1
177 lines (157 loc) · 6.55 KB
/
Copy pathpublish-docs.yml
File metadata and controls
177 lines (157 loc) · 6.55 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: Publish @my-own-web-services/react-components docs
# Deploys to https://my-own-web-services.github.io/mows-react-components/
#
# Publishing model: this workflow builds the docs SPA, then pushes it into
# the org Pages repo `my-own-web-services/my-own-web-services.github.io`
# under the `mows-react-components/` subdirectory. That repo hosts every
# project's docs as siblings (mows-react-components/, mows-vm-supervisor/,
# …) so each docs workflow only owns its own subdir and never touches the
# others.
#
# Prerequisites (one-time, done out-of-band):
# 1. Org Pages repo `my-own-web-services/my-own-web-services.github.io`
# exists, public, Pages enabled with Source = "Deploy from a branch"
# (main, /).
# 2. An SSH deploy key has been generated. The PUBLIC half is added to
# the org Pages repo as a deploy key with write access. The PRIVATE
# half is stored on THIS repo as the `DOCS_DEPLOY_KEY` secret.
on:
push:
branches:
- main
paths:
- 'components/react/**'
- '.github/workflows/publish-docs.yml'
pull_request:
paths:
- 'components/react/**'
- '.github/workflows/publish-docs.yml'
workflow_dispatch:
inputs:
site_base:
description: 'Public base path the site is served from (must start AND end with "/"). Default "/mows-react-components/" matches the org Pages layout.'
required: false
default: '/mows-react-components/'
type: string
# Serialise pushes to the org Pages repo so a newer commit on main always
# wins. PRs run the build alone (no deploy) so they cancel freely.
concurrency:
group: publish-docs-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
permissions:
contents: read
env:
# Slug used both as the URL path prefix and the subdirectory inside the
# org Pages repo. Changing this in one place keeps the build and the
# deploy in sync.
DOCS_SLUG: mows-react-components
PAGES_REPO: my-own-web-services/my-own-web-services.github.io
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
- name: Set up Node.js
uses: actions/setup-node@26961cf329f22f6837d5f54c3efd76b480300ace # v4
with:
node-version: '22'
- name: Set up pnpm
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4
with:
version: 9.15.9
run_install: false
- name: Get pnpm store path
id: pnpm-store
run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
- name: Cache pnpm store
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v4
with:
path: ${{ steps.pnpm-store.outputs.path }}
key: ${{ runner.os }}-pnpm-${{ hashFiles('components/react/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
- name: Build docs site
env:
SITE_BASE: ${{ github.event.inputs.site_base || format('/{0}/', env.DOCS_SLUG) }}
run: |
cd components/react
bash scripts/build-docs.sh
# Hand the built `dist-site/` to the deploy job via the standard
# artifact channel. Plain workflow artifact — NOT a Pages artifact —
# since we publish to a different repo, not this repo's Pages.
- name: Upload built site
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: docs-site
path: components/react/dist-site
retention-days: 7
if-no-files-found: error
deploy:
needs: build
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment:
name: docs-publish
url: https://my-own-web-services.github.io/${{ env.DOCS_SLUG }}/
steps:
- name: Download built site
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: docs-site
path: dist-site
- name: Configure SSH for org Pages repo
env:
DEPLOY_KEY: ${{ secrets.DOCS_DEPLOY_KEY }}
run: |
if [ -z "${DEPLOY_KEY}" ]; then
echo "::error::DOCS_DEPLOY_KEY secret is not configured on this repo."
echo "Generate an ed25519 keypair, add the public half as a deploy key"
echo "(with write access) on ${PAGES_REPO}, and add the private half as"
echo "the DOCS_DEPLOY_KEY secret on this repo."
exit 1
fi
mkdir -p ~/.ssh
chmod 700 ~/.ssh
printf '%s\n' "${DEPLOY_KEY}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan -t ed25519,rsa github.com >> ~/.ssh/known_hosts 2>/dev/null
- name: Publish to org Pages repo
env:
SOURCE_SHA: ${{ github.sha }}
run: |
set -euo pipefail
# Shallow clone to keep the deploy fast; we only need HEAD to make
# one new commit on top of it.
git clone --depth 1 "git@github.com:${PAGES_REPO}.git" pages-repo
cd pages-repo
# Replace only OUR subdir; siblings (other docs projects) stay
# untouched. rsync --delete prunes files that disappeared
# between builds, but the --include patterns confine all
# deletes to ${DOCS_SLUG}/.
rm -rf "${DOCS_SLUG}"
mkdir "${DOCS_SLUG}"
cp -a ../dist-site/. "${DOCS_SLUG}/"
git config user.name "mows-docs-bot"
git config user.email "mows-docs-bot@users.noreply.github.com"
git add "${DOCS_SLUG}"
if git diff --staged --quiet; then
echo "No changes to publish (build is byte-identical to the live site)."
exit 0
fi
SHORT_SHA="${SOURCE_SHA:0:7}"
git commit -m "docs(${DOCS_SLUG}): publish ${SHORT_SHA}"
# Retry on push rejection — another docs workflow (e.g. a sibling
# project) may have pushed concurrently. We only touch our own
# subdir, so a rebase is always trivial; bail after a few tries
# to avoid burning runner time on a genuinely broken state.
for attempt in 1 2 3 4 5; do
if git push origin HEAD:main; then
echo "Published ${DOCS_SLUG}@${SHORT_SHA} -> ${PAGES_REPO}"
exit 0
fi
echo "Push attempt ${attempt} rejected; rebasing on latest main…"
git fetch --depth 1 origin main
git rebase origin/main
done
echo "::error::Failed to push after 5 attempts."
exit 1