Repository navigation
245 lines (226 loc) · 10.6 KB
/
Copy pathsync-sdk-docs.yml
File metadata and controls
245 lines (226 loc) · 10.6 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
# Syncs SDK docs from /sdk/<lang>/ in this repo into MarketDataApp/sdk-<lang>/docs/
# by converting MDX → clean Markdown and opening a PR against the target repo.
#
# Pilot scope: sdk-js only. Adding more SDKs is a one-line matrix change.
#
# ────────────────────────────────────────────────────────────────────────────
# One-time setup (GitHub App auth — survives the eventual repo migration to
# the MarketData-App org without code changes):
#
# 1. Create a GitHub App owned by `MarketData-App` (org settings → Developer
# settings → GitHub Apps → New GitHub App). Suggested name:
# `marketdata-docs-sync`. Set "Where can this be installed?" to "Any
# account" so it can run against repos that still live under the
# MarketDataApp user (current home) and later the MarketData-App org.
# 2. Permissions: Contents = Read & write, Pull requests = Read & write,
# Metadata = Read. No webhook (uncheck "Active").
# 3. Generate a private key (.pem) and download it.
# 4. Install the App on `MarketDataApp` (user), granting access to
# `documentation` and `sdk-js`. (Add more SDK repos as the matrix grows.)
# 5. In this repo:
# - Repo variable `SDK_DOCS_APP_ID` = the App ID (a number)
# - Repo secret `SDK_DOCS_APP_PRIVATE_KEY` = the .pem contents
# 6. After repo migration to the org, change `TARGET_OWNER` below from
# `MarketDataApp` to `MarketData-App`.
# ────────────────────────────────────────────────────────────────────────────
name: "SDK Docs: Sync to SDK Repos"
on:
push:
# `main`, which is production: deploy-docs.yml builds a push to main as the
# production environment, and work reaches it as a `staging -> main`
# promotion pull request.
#
# This used to watch `staging`, the integration branch, so the SDK repos
# received documentation before it was published -- including anything that
# was changed again, or dropped, before the promotion. Tracking main means
# the docs vendored into each SDK are the docs the site is actually serving.
#
# It also removes a split: `main` is the repository default, so the
# `workflow_dispatch` below already checked out main. A dispatch and a push
# synced different content, and only the dispatch was right.
branches: [main]
paths:
- 'sdk/js/**'
- 'sdk/java/**'
- 'sdk/go/**'
- 'sdk/csharp/**'
- 'lib/mdx-to-md.js'
- 'scripts/export-sdk-docs.js'
- '.github/workflows/sync-sdk-docs.yml'
workflow_dispatch:
inputs:
sdk:
description: 'Which SDK to sync'
required: true
default: 'js'
type: choice
options: [js, java, go, csharp]
env:
SOURCE_OWNER: MarketDataApp
TARGET_OWNER: MarketDataApp # change to MarketData-App after repo migration
MANIFEST_FILE: docs/.sync-manifest.txt
jobs:
sync:
runs-on: ubuntu-latest
# Bounded so a hang reports rather than burning the runner. With no
# `timeout-minutes` a job inherits GitHub's 360-minute default, and a
# step that wedges on a network call takes six hours to say nothing.
# Sized well above the observed maximum (under 1 minute per matrix leg), because a cap that trips
# on a slow-but-working run gets raised and then removed.
timeout-minutes: 15
permissions:
contents: read
strategy:
fail-fast: false
matrix:
# `sdk` = source dir (sdk/<sdk>/) and exporter key; `repo` = target repo.
# These stay decoupled even though every pair now matches `sdk-${sdk}`:
# Go v2 was transplanted into sdk-go on 2026-09-02, so sdk/go/ targets
# sdk-go again. Keeping the explicit `repo` keeps the next divergence
# a one-line change.
include:
- sdk: js
repo: sdk-js
- sdk: java
repo: sdk-java
- sdk: go
repo: sdk-go
- sdk: csharp
repo: sdk-csharp
steps:
- name: Checkout documentation source
uses: actions/checkout@v4
with:
path: docs-source
# `package_json_file` is REQUIRED here and nowhere else in this repo.
# pnpm/action-setup takes its version from the `packageManager` field,
# and by default looks for ./package.json -- which does not exist in this
# job, because the checkout above puts the repository in `docs-source/`.
# Without this the step fails with "No pnpm version is specified".
- uses: pnpm/action-setup@v4
with:
package_json_file: docs-source/package.json
# pnpm/action-setup MUST come first: `cache: pnpm` makes setup-node run
# `pnpm store path`, which needs pnpm on PATH already.
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
cache-dependency-path: docs-source/pnpm-lock.yaml
- name: Install the conversion lib's dependencies
working-directory: docs-source
# lib/ and scripts/ require turndown and @mixmark-io/domino, both
# declared in package.json's `dependencies`. Nothing ever installed
# them: this job went from setup-node straight to `node --test`,
# which passed only while the lib was dependency-free. PR #199 added
# lib/html-to-md.js (turndown) on 2026-08-31, and every sync run
# failed on `Cannot find module 'turndown'` until this step existed.
# Uses pnpm against the committed lockfile, matching deploy-docs.yml,
# pr-checks.yml and post-deploy-tests.yml.
run: pnpm install --frozen-lockfile
- name: Run unit tests for the conversion lib
working-directory: docs-source
run: node --test lib/__tests__/*.test.js
- name: Convert sdk/<lang>/ → clean .md
working-directory: docs-source
env:
SDK: ${{ matrix.sdk }}
OUT_DIR: ${{ runner.temp }}/out
run: node scripts/export-sdk-docs.js --sdk "$SDK" --out "$OUT_DIR"
- name: Mint cross-repo token (GitHub App)
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.SDK_DOCS_APP_ID }}
private-key: ${{ secrets.SDK_DOCS_APP_PRIVATE_KEY }}
owner: ${{ env.TARGET_OWNER }}
repositories: ${{ matrix.repo }}
- name: Checkout target SDK repo
uses: actions/checkout@v4
with:
repository: ${{ env.TARGET_OWNER }}/${{ matrix.repo }}
token: ${{ steps.app-token.outputs.token }}
path: target
- name: Replace previously-generated docs with fresh export
# We DO NOT wipe target/docs/ wholesale — it may contain SDK-repo-owned
# content (ADRs, internal READMEs). The previous sync wrote a manifest
# at $MANIFEST_FILE listing every file it generated. Delete exactly
# those paths, then drop the fresh export in (which writes a new
# manifest).
env:
OUT_DIR: ${{ runner.temp }}/out
run: |
set -euo pipefail
mkdir -p target/docs
if [ -f "target/$MANIFEST_FILE" ]; then
while IFS= read -r rel; do
# Skip blank lines and comments (lines beginning with '#')
case "$rel" in
''|'#'*) continue ;;
esac
rm -f "target/docs/$rel"
done < "target/$MANIFEST_FILE"
fi
# Remove any now-empty directories left behind.
find target/docs -type d -empty -delete || true
mkdir -p target/docs
cp -R "$OUT_DIR/." target/docs/
- name: Compute diff summary for PR body
id: diff
working-directory: target
run: |
set -euo pipefail
git add -A docs/
{
echo "summary<<DIFFEOF"
if git diff --cached --quiet; then
echo "_No changes — docs are already in sync._"
else
git diff --cached --name-status -- docs/
fi
echo "DIFFEOF"
} >> "$GITHUB_OUTPUT"
- name: Open / update PR in target SDK repo
id: pr
uses: peter-evans/create-pull-request@v6
with:
path: target
token: ${{ steps.app-token.outputs.token }}
branch: sync/docs-from-documentation
delete-branch: true
commit-message: 'docs: sync from documentation@${{ github.sha }}'
title: 'docs: sync from documentation@${{ github.sha }}'
body: |
Automated sync from [`${{ env.SOURCE_OWNER }}/documentation@${{ github.sha }}`](https://github.com/${{ env.SOURCE_OWNER }}/documentation/commit/${{ github.sha }}).
**SDK:** `${{ matrix.sdk }}`
**Source path:** `sdk/${{ matrix.sdk }}/`
**Workflow run:** [#${{ github.run_id }}](https://github.com/${{ env.SOURCE_OWNER }}/documentation/actions/runs/${{ github.run_id }})
### Changed files
```
${{ steps.diff.outputs.summary }}
```
> **These files are auto-synced from
> [MarketDataApp/documentation](https://github.com/MarketDataApp/documentation/tree/main/sdk/${{ matrix.sdk }})** —
> edit the source `.mdx` there, not the rendered `.md` here.
> Hand-edits to files listed in `docs/.sync-manifest.txt` will
> be overwritten on the next sync.
- name: Let the PR merge itself once its checks pass
if: steps.pr.outputs.pull-request-number != ''
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
PR: ${{ steps.pr.outputs.pull-request-number }}
REPO: ${{ env.TARGET_OWNER }}/${{ matrix.repo }}
run: |
# Without this the sync PRs just accumulate. Four of them sat green,
# unreviewed and unmerged for up to a month -- sdk-js#76 and
# sdk-java#59 from 2026-08-19 -- while the anchor-link fixes they
# carried stayed broken on the published docs. Nothing blocked them;
# nobody owned merging them. An automated pipeline that needs a human
# to press the last button is not automated.
#
# `--auto` bypasses nothing. GitHub merges only when the branch's
# required checks pass, so a red `Tests passed` still blocks, and a
# rule that requires review still waits for the review. It is the
# merge queue, not a merge.
echo "Enabling auto-merge on ${REPO}#${PR}"
gh pr merge "$PR" --repo "$REPO" --squash --auto