-
Notifications
You must be signed in to change notification settings - Fork 0
172 lines (155 loc) · 7.58 KB
/
Copy pathsync-cli-guide.yml
File metadata and controls
172 lines (155 loc) · 7.58 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
name: Sync CLI User Guide
# Regenerates the CLI User Guide (src/org/cli/*.md) from @imqueue/cli's wiki/
# and commits the result to master — which deploys the site. It runs when the
# cli repo signals a release (repository_dispatch, see the snippet at the bottom
# of this file), and can also be triggered by hand.
on:
repository_dispatch:
types: [cli-released]
workflow_dispatch:
inputs:
ref:
description: "@imqueue/cli git ref (tag/branch) to sync from"
default: master
# Never let two syncs race on a push to master.
concurrency:
group: sync-cli-guide
cancel-in-progress: false
permissions:
contents: write
# For `gh workflow run indexnow.yml` in the last step. contents:write alone
# cannot dispatch a workflow.
actions: write
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Checkout imqueue.com
uses: actions/checkout@v7
with:
# REQUIRED by the verify step. check:dates reads git history
# (`git log --follow --diff-filter=A`) for every page's publication
# date; the default shallow fetch has one commit, so every file looks
# as though that commit added it and the check fails on every run.
# Same reason refresh-api-docs.yml sets it.
fetch-depth: 0
- name: Resolve cli ref
id: ref
run: echo "ref=${{ github.event.client_payload.ref || github.event.inputs.ref || 'master' }}" >> "$GITHUB_OUTPUT"
- name: Checkout @imqueue/cli wiki source
uses: actions/checkout@v7
with:
repository: imqueue/cli
ref: ${{ steps.ref.outputs.ref }}
path: .cli-src
sparse-checkout: wiki
# Only needed if imqueue/cli is private. For a public repo the default
# token is enough and you can delete this line (and the secret).
token: ${{ secrets.CLI_SYNC_TOKEN || github.token }}
- uses: actions/setup-node@v7
with:
node-version: 22
cache: npm
# The sync script itself needs no dependencies, but everything after it
# does — and `npm ci` also runs `prepare`, which points core.hooksPath at
# .githooks.
- run: npm ci
- name: Regenerate CLI User Guide from the wiki
run: node scripts/sync-cli-wiki.js --wiki .cli-src/wiki
- name: Anything to do?
id: changed
run: |
if [ -z "$(git status --porcelain -- src/org/cli)" ]; then
echo "No changes — the guide is already in sync."
echo "any=false" >> "$GITHUB_OUTPUT"
else
echo "any=true" >> "$GITHUB_OUTPUT"
fi
- name: Commit the guide
if: steps.changed.outputs.any == 'true'
env:
REF: ${{ steps.ref.outputs.ref }}
run: |
git config user.name "imqueue-bot"
git config user.email "bot@imqueue.com"
# An explicit path, not `git add -A`: this working tree also holds
# .cli-src/ from the sparse checkout above, plus (on a self-hosted
# runner) the untracked local-only promotion/ and *-PLAN.md material.
git add -- src/org/cli
# --no-verify here and below on purpose: the "Verify" step is the gate,
# and it runs on the exact tree that gets pushed. Letting the hook run
# would execute the same suite three times for one sync, and on the
# first of those runs a BRAND-NEW guide page is staged-but-uncommitted,
# so gen-page-dates reports it untracked and check:dates cannot see it
# either way.
git commit --no-verify -m "docs(cli): sync CLI User Guide from @imqueue/cli@${REF}"
- name: Record dates for new or changed guide pages
if: steps.changed.outputs.any == 'true'
# AFTER the commit, never before. gen-page-dates derives `published` from
# the commit that ADDED a file (`git log --diff-filter=A`), so a page that
# is only staged resolves to null and is omitted from pageDates.json — and
# then check:dates fails on the *next* commit with "has no entry — it would
# render with no date". Running it here, then amending, is what keeps a
# newly synced page from shipping with no datePublished at all.
run: |
npm run gen-page-dates
if [ -n "$(git status --porcelain -- src/_data/pageDates.json)" ]; then
git add -- src/_data/pageDates.json
git commit --no-verify --amend --no-edit
echo "Folded pageDates.json into the sync commit."
else
echo "pageDates.json unchanged."
fi
- name: Verify — redirects, analytics, dates, links, sitemap
if: steps.changed.outputs.any == 'true'
# This is the gate, and it has to be here. A push made with GITHUB_TOKEN
# does not trigger other workflows, so checks.yml will NOT run for the
# commit this job creates — while Cloudflare Pages deploys from the git
# push itself. Without this step an unverified guide goes straight to
# production. Same reasoning as refresh-api-docs.yml.
run: npm test
- name: Push
if: steps.changed.outputs.any == 'true'
run: git push
- name: Announce the new guide to IndexNow
if: steps.changed.outputs.any == 'true'
# indexnow.yml is triggered by `push: branches: [master]`, which a
# GITHUB_TOKEN push does not fire — so a synced guide used to wait for the
# next unrelated human push before Bing/Yandex heard about it. /cli/ pages
# are submitted (only /api/ is excluded, via --exclude=/api/), so there is
# something real to announce.
#
# Dispatching that workflow rather than calling `npm run indexnow:org`
# here: indexnow-ping.js does NOT wait for anything ("Run AFTER a deploy,
# once the new content is actually live"), and the ~12-minute
# built-vs-live sitemap parity gate that makes it correct lives in
# indexnow.yml. Pinging from this job would submit a brand-new guide page
# before Cloudflare Pages had deployed it, and IndexNow would fetch a 404.
#
# workflow_dispatch is one of the two events GitHub explicitly EXEMPTS
# from the "GITHUB_TOKEN cannot trigger workflows" rule (the other is
# repository_dispatch), so this does start a run — which is the whole
# reason it is a dispatch and not a push.
#
# Non-fatal: the sync itself has already landed and the sitemap covers the
# slow path, so a dispatch failure must not fail the sync.
continue-on-error: true
env:
GH_TOKEN: ${{ github.token }}
run: gh workflow run indexnow.yml --ref master
# ---------------------------------------------------------------------------
# To fire this automatically on every @imqueue/cli npm publish, add a step to
# the cli repo's release/publish workflow (AFTER the successful `npm publish`):
#
# - name: Notify imqueue.com to refresh the CLI User Guide
# run: |
# curl -sSf -X POST \
# -H "Authorization: Bearer ${{ secrets.SITE_DISPATCH_TOKEN }}" \
# -H "Accept: application/vnd.github+json" \
# https://api.github.com/repos/imqueue/imqueue.com/dispatches \
# -d "{\"event_type\":\"cli-released\",\"client_payload\":{\"ref\":\"${GITHUB_REF_NAME}\"}}"
#
# SITE_DISPATCH_TOKEN is a fine-grained PAT (or classic PAT with `repo` scope)
# that can send dispatches to imqueue/imqueue.com, stored as a secret in the
# cli repo. That is the only credential you need to create by hand.
# ---------------------------------------------------------------------------