diff --git a/.github/workflows/pull-external-snippets.yml b/.github/workflows/pull-external-snippets.yml index 55d48fa76..0b6099589 100644 --- a/.github/workflows/pull-external-snippets.yml +++ b/.github/workflows/pull-external-snippets.yml @@ -27,8 +27,6 @@ on: types: [update_snippets] env: - external_token: ${{ secrets.EXTERNAL_REPO_TOKEN }} - docs_pr_token: ${{ secrets.DOCS_PR_TOKEN }} artifact_id: ${{ inputs.artifact-id || github.event.client_payload.artifact-id }} run_id: ${{ inputs.run-id || github.event.client_payload.run-id }} repo_name: ${{ inputs.repo-name || github.event.client_payload.repo-name }} @@ -47,22 +45,35 @@ jobs: echo "external repo name: ${{ env.repo_name }}" echo "external repo org: ${{ env.repo_org }}" echo "external repo version: ${{ env.repo_version }}" - echo "Token is set: ${{ env.external_token != '' }}" - name: Checkout repository uses: actions/checkout@v5 - - name: pull artifacts + - name: Generate snippet reader app token + id: reader-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.CF_DOCS_SNIPPET_READER_APP_ID }} + private-key: ${{ secrets.CF_DOCS_SNIPPET_READER_PRIVATE_KEY }} + owner: ${{ env.repo_org }} + repositories: ${{ env.repo_name }} + - name: Pull artifacts uses: actions/download-artifact@v5 with: artifact-ids: ${{ env.artifact_id }} - path: snippets/external/${{ env.repo_name }}/${{ env.repo_version }} - github-token: ${{ env.external_token }} + path: docs-main/snippets/external/${{ env.repo_name }}/${{ env.repo_version }} + github-token: ${{ steps.reader-token.outputs.token }} repository: ${{ env.repo_org }}/${{ env.repo_name }} run-id: ${{ env.run_id }} + - name: Generate snippet writer app token + id: writer-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.CF_DOCS_SNIPPET_WRITER_APP_ID }} + private-key: ${{ secrets.CF_DOCS_SNIPPET_WRITER_PRIVATE_KEY }} - name: Create Pull Request uses: peter-evans/create-pull-request@v8 with: branch: external-snippet-update-${{ env.repo_name }}-${{ env.repo_version }} base: main - token: ${{ secrets.DOCS_PR_TOKEN }} + token: ${{ steps.writer-token.outputs.token }} title: External Snippet updates ${{ env.repo_name }} (${{ env.repo_version }}) [${{ env.trigger_sha_short }}] - commit-message: External Snippet updates ${{ env.repo_name }} (${{ env.repo_version }}) [${{ env.trigger_sha_short }}] \ No newline at end of file + commit-message: External Snippet updates ${{ env.repo_name }} (${{ env.repo_version }}) [${{ env.trigger_sha_short }}] diff --git a/config/snippet-config/app-install-checklist.md b/config/snippet-config/app-install-checklist.md new file mode 100644 index 000000000..8d58d8d6b --- /dev/null +++ b/config/snippet-config/app-install-checklist.md @@ -0,0 +1,224 @@ +# CF Docs snippet sync — GitHub App install checklist + +Use this checklist when setting up **cf-docs-snippet-reader** and **cf-docs-snippet-writer**. + +App registration is done in the **GitHub web UI only**. + +Related docs: [update-workflow-rev2.md](./update-workflow-rev2.md) · [source-repo-workflow-readme.md](./source-repo-workflow-readme.md) + +--- + +## Prerequisites + +- [ ] Org admin access on the org that **owns cf-docs** ([digital-asset/docs](https://github.com/digital-asset/docs)) +- [ ] Permission to install third-party/org apps on each **source** repository. + +--- + +## App 1: `cf-docs-snippet-reader` + +### Create the app + +**GitHub → Organization settings → Developer settings → GitHub Apps → New GitHub App** + +| Field | Value | +|-------|--------| +| GitHub App name | `cf-docs-snippet-reader` | +| Description | Read GHA artifacts from snippet source repos for cf-docs | +| Homepage URL | cf-docs repository URL | +| Callback URL | *(leave empty)* | +| Webhook | **Disable** (uncheck Active) | +| Repository permissions → **Actions** | **Read-only** | +| Repository permissions → **Metadata** | Read-only *(automatic)* | +| Where can this GitHub App be installed? | Only on this account, or allowlist partner orgs | + +- [ ] Click **Create GitHub App** +- [ ] Record **App ID**: `________________` +- [ ] **Generate a private key** → download `.pem` → store securely +- [ ] *(Optional)* Upload logo / set description for discoverability in org app requests + +### Install reader app on source repositories + +**GitHub App → Install App → Configure** + +Install on **each repository** that publishes snippets (select repositories): + +- [ ] [DACH-NY/canton](https://github.com/DACH-NY/canton) +- [ ] [canton-network/splice](https://github.com/canton-network/splice) +- [ ] [digital-asset/daml](https://github.com/digital-asset/daml) +- [ ] [digital-asset/cn-quickstart](https://github.com/digital-asset/cn-quickstart) +- [ ] [DACH-NY/daml-shell](https://github.com/DACH-NY/daml-shell) +- [ ] [digital-asset/dpm](https://github.com/digital-asset/dpm) +- [ ] [DACH-NY/scribe](https://github.com/DACH-NY/scribe) + +**Do not** install the reader app on cf-docs. + +--- + +## App 2: `cf-docs-snippet-writer` + +### Create the app + +**New GitHub App** (same org as above) + +| Field | Value | +|-------|--------| +| GitHub App name | `cf-docs-snippet-writer` | +| Description | Dispatch snippet updates and open PRs on cf-docs | +| Homepage URL | cf-docs repository URL | +| Webhook | **Disable** | +| Repository permissions → **Contents** | **Read and write** | +| Repository permissions → **Pull requests** | **Read and write** | +| Repository permissions → **Metadata** | Read-only *(automatic)* | + +- [ ] Click **Create GitHub App** +- [ ] Record **App ID**: `________________` +- [ ] **Generate a private key** → download `.pem` → store securely + +### Install writer app on cf-docs only + +- [ ] Install on [digital-asset/docs](https://github.com/digital-asset/docs) +- [ ] **Do not** install on source repositories + +--- + +## Secrets: cf-docs repository + +**Settings → Secrets and variables → Actions → New repository secret** + +| Secret name | Value | +|-------------|--------| +| `CF_DOCS_SNIPPET_READER_APP_ID` | Reader App ID | +| `CF_DOCS_SNIPPET_READER_PRIVATE_KEY` | Full PEM file contents (including `BEGIN` / `END` lines) | +| `CF_DOCS_SNIPPET_WRITER_APP_ID` | Writer App ID | +| `CF_DOCS_SNIPPET_WRITER_PRIVATE_KEY` | Full PEM file contents | + +- [ ] All four secrets configured +- [ ] Verified secret names match [pull-external-snippets.yml](/.github/workflows/pull-external-snippets.yml) + +Remove legacy PAT secrets after verification: + +- [ ] `EXTERNAL_REPO_TOKEN` revoked *(after successful app test)* +- [ ] `DOCS_PR_TOKEN` revoked *(after successful app test)* + +--- + +## Secrets: source repositories + +Each repo that **dispatches** `update_snippets` needs writer app credentials. + +**Prefer organization secrets** when repos share an org; use repository secrets for cross-org repos (e.g. Canton on `DACH-NY`). + +| Secret name | Value | +|-------------|--------| +| `CF_DOCS_SNIPPET_WRITER_APP_ID` | Writer App ID (same as cf-docs) | +| `CF_DOCS_SNIPPET_WRITER_PRIVATE_KEY` | Writer PEM (same key) | + +### Canton ([DACH-NY/canton](https://github.com/DACH-NY/canton)) + +CircleCI bridge — see [update-workflow-rev2.md § Canton](./update-workflow-rev2.md#canton-circleci--gha-bridge). + +- [ ] Writer app secrets on Canton repo (or `DACH-NY` org secret) +- [ ] `CIRCLECI_API_TOKEN` on Canton GHA +- [ ] `MAIN_REPO_ORG` / `MAIN_REPO_NAME` repository variables +- [ ] `ENABLE_CFDOCS_SNIPPET_SYNC` = `true` when ready +- [ ] CircleCI context: `GITHUB_TOKEN` (`canton-machine` PAT) for CCI → Canton GHA dispatch +- [ ] CircleCI: `FAIL_ON_CF_DOCS_ERROR` **not set** during initial rollout *(optional strict mode later)* + +Remove after verification: + +- [ ] `MAIN_DOCS_REPO_TOKEN` revoked on Canton + +### Splice ([canton-network/splice](https://github.com/canton-network/splice)) + +Standard GHA flow — see [update-workflow-rev2.md § Splice](./update-workflow-rev2.md#splice-gha-source) and [source-repo-workflow-readme.md](./source-repo-workflow-readme.md). + +- [ ] Reader app installed on [canton-network/splice](https://github.com/canton-network/splice) +- [ ] Writer app secrets on splice repo (or `canton-network` org secret) +- [ ] Repository variables: `MAIN_REPO_ORG` = `digital-asset`, `MAIN_REPO_NAME` = `docs` +- [ ] `ENABLE_SYNC_PROCESS` = `true` when ready +- [ ] `.github/workflows/publish-cfdocs-snippets.yml` merged +- [ ] Extraction scripts present under `gha-scripts/cf-docs/` (`generateOutputDocs.js`, `exportConfig.json`) + +### Other GHA source repos + +Repeat reader install, writer secrets, and variables per repo. See [source repo tracker](./update-workflow-rev2.md#source-repo-installation) and [source-repo-workflow-readme.md](./source-repo-workflow-readme.md). + +| Repository | Writer secrets | Variables | +|------------|----------------|-----------| +| [digital-asset/daml](https://github.com/digital-asset/daml) | org or repo | `MAIN_REPO_ORG`, `MAIN_REPO_NAME`, **`ENABLE_SYNC_PROCESS`** | +| [digital-asset/cn-quickstart](https://github.com/digital-asset/cn-quickstart) | org or repo | same | +| [DACH-NY/daml-shell](https://github.com/DACH-NY/daml-shell) | org or repo | same | +| [digital-asset/dpm](https://github.com/digital-asset/dpm) | org or repo | same | +| [DACH-NY/scribe](https://github.com/DACH-NY/scribe) | org or repo | same | + +Set **`ENABLE_SYNC_PROCESS`** = `true` only when the publish workflow, extraction scripts, and app credentials are verified. While unset, the workflow may trigger on `main` but the publish job is skipped. + +--- + +## Workflow PRs (merge after secrets exist) + +| Order | Repository | Workflow file | +|-------|------------|---------------| +| 1 | [digital-asset/docs](https://github.com/digital-asset/docs) | `.github/workflows/pull-external-snippets.yml` | +| 2 | [DACH-NY/canton](https://github.com/DACH-NY/canton) | [publish-cfdocs-snippets-canton-bridge.yml](/scripts/templates/publish-cfdocs-snippets-canton-bridge.yml) → `.github/workflows/publish-cfdocs-snippets.yml` | +| 3 | Each GHA source | [publish-cfdocs-snippets.yml](/scripts/templates/publish-cfdocs-snippets.yml) → `.github/workflows/publish-cfdocs-snippets.yml` | + +- [ ] cf-docs pull workflow merged +- [ ] Canton bridge workflow merged +- [ ] Source repo workflows updated + +--- + +## Verification + +### 1. Reader token (cf-docs) + +- [ ] Run **Pull external Snippet updates** via `workflow_dispatch` with a known `artifact-id`, `run-id`, `repo-org`, `repo-name`, `repo-version` from a recent source-repo GHA run +- [ ] Confirm artifact downloads and files land under `docs-main/snippets/external/{repo}/{version}/` + +### 2. Writer token (cf-docs PR) + +- [ ] Same run creates or updates `external-snippet-update-{repo}-{version}` PR + +### 3. Canton end-to-end + +- [ ] Green `main` build: CircleCI `export_mintlify_snippets` completes (soft-fail OK if `FAIL_ON_CF_DOCS_ERROR` unset) +- [ ] Canton GHA **Publish CF Docs Snippets** runs +- [ ] cf-docs **Pull external Snippet updates** runs → PR updated + +### 4. Splice end-to-end + +- [ ] Push to `main` touching a snippet source path (or `workflow_dispatch`) +- [ ] [canton-network/splice](https://github.com/canton-network/splice) **Publish CF Docs Snippets** runs → artifact uploaded → cf-docs dispatch +- [ ] cf-docs PR updated under `docs-main/snippets/external/splice/main/` + +### 5. Revoke PATs + +- [ ] Remove `EXTERNAL_REPO_TOKEN`, `DOCS_PR_TOKEN`, `MAIN_DOCS_REPO_TOKEN` from all repos +- [ ] Update [source repo installation](./update-workflow-rev2.md#source-repo-installation) tracker + +--- + +## Key rotation + +When rotating a private key: + +1. Generate new private key in GitHub App settings (old key remains valid until revoked) +2. Update all GitHub Secrets that reference the PEM +3. Run verification steps above +4. Revoke old private key in GitHub App settings + +--- + +## Troubleshooting + +| Symptom | Check | +|---------|--------| +| `401` / `403` on `download-artifact` | Reader app installed on **source** repo; token minted with correct `owner` / `repositories` | +| `403` on `create-pull-request` | Writer app installed on **cf-docs**; PEM matches writer app | +| `403` on source → cf-docs dispatch | Writer secrets on source repo; `MAIN_REPO_ORG` / `MAIN_REPO_NAME` correct | +| Bridge workflow skipped | `ENABLE_CFDOCS_SNIPPET_SYNC` = `true` on Canton | +| GHA source workflow skipped | `ENABLE_SYNC_PROCESS` = `true` on source repo | +| CCI dispatch failed but job green | Expected when `FAIL_ON_CF_DOCS_ERROR` is unset | +| CCI dispatch failed and job red | Set `FAIL_ON_CF_DOCS_ERROR` only when snippet sync must block `main` | diff --git a/config/snippet-config/daml-finance-snippet-list-remote.json b/config/snippet-config/daml-finance-snippet-list-remote.json deleted file mode 100644 index 39d3df600..000000000 --- a/config/snippet-config/daml-finance-snippet-list-remote.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "snippets": [] -} diff --git a/config/snippet-config/remote-snippet-lists.json b/config/snippet-config/remote-snippet-lists.json index db5b7df38..449f6f0bb 100644 --- a/config/snippet-config/remote-snippet-lists.json +++ b/config/snippet-config/remote-snippet-lists.json @@ -1,10 +1,8 @@ { "snippetLists": [ - "splice-wallet-kernel-snippet-list-remote.json", "canton-snippet-list-remote.json", "daml-snippet-list-remote.json", "daml-shell-snippet-list-remote.json", - "daml-finance-snippet-list-remote.json", "dpm-snippet-list-remote.json", "cn-quickstart-snippet-list-remote.json", "splice-snippet-list-remote.json", diff --git a/config/snippet-config/source-repo-workflow-readme.md b/config/snippet-config/source-repo-workflow-readme.md new file mode 100644 index 000000000..671953035 --- /dev/null +++ b/config/snippet-config/source-repo-workflow-readme.md @@ -0,0 +1,242 @@ +# CF Docs snippet sync — source repository guide + +How snippet publishing works **from the source repository side**: from a merge on `main` through artifact upload and the dispatch to [digital-asset/docs](https://github.com/digital-asset/docs) (cf-docs). + +This guide covers the standard **GHA source flow** used by splice, daml, cn-quickstart, daml-shell, dpm, and scribe. Canton uses a separate CircleCI bridge — see [update-workflow-rev2.md § Canton](./update-workflow-rev2.md#canton-circleci--gha-bridge). + +**Related:** [app-install-checklist.md](./app-install-checklist.md) · [update-workflow-rev2.md](./update-workflow-rev2.md) · [publish-cfdocs-snippets.yml](/scripts/templates/publish-cfdocs-snippets.yml) + +--- + +## What the source repo does + +1. Detect snippet source changes on `main` (or run manually) — **trigger `paths` must be configured per repo** (see [Triggers](#triggers)). +2. Extract configured snippets into `docs-output/` (a transient directory on the runner, not committed). +3. Upload `docs-output/` as a **GitHub Actions artifact** attached to the workflow run **in the source repository** (not in cf-docs). +4. Mint a short-lived **writer** app token scoped to cf-docs. +5. Dispatch `update_snippets` on cf-docs with artifact and repo metadata (`artifact-id`, `run-id`, `repo-org`, etc.). + +The artifact stays in the **source repo's Actions artifact storage** until cf-docs downloads it. Only after cf-docs runs `pull-external-snippets` do the snippet files appear under `docs-main/snippets/external/{repo}/…` in the main docs repo. That consumer flow is documented in [update-workflow-rev2.md § cf-docs](./update-workflow-rev2.md#cf-docs-pulling-snippets). + +**Do not confuse:** +- **GHA artifact** — temporary blob storage tied to a workflow run on the **calling (source) repo**; cf-docs fetches it via the reader app. +- **Snippet files in cf-docs** — the permanent `.mdx` files merged via PR into `digital-asset/docs`. + +--- + +## Files to add on the source repo + +| File | Purpose | +|------|---------| +| `.github/workflows/publish-cfdocs-snippets.yml` | Copy from [scripts/templates/publish-cfdocs-snippets.yml](/scripts/templates/publish-cfdocs-snippets.yml) | +| `generateOutputDocs.js` | Snippet extraction script (from cf-docs `scripts/helpers/`, paths adjusted per repo) | +| Snippet export config | JSON list of snippets (e.g. `exportConfig.json`, synced from cf-docs `*-snippet-list-remote.json`) | + +Layout varies by repo. Example (splice): scripts live under `gha-scripts/cf-docs/`. Other repos may use `scripts/docs/`. + +Generated output goes to `docs-output/` at the repo root during the workflow run. **Do not commit** `docs-output/` — it is uploaded as a GHA artifact on the source repo only; cf-docs receives the files later via its pull workflow. + +--- + +## Prerequisites on the source repo + +### GitHub App: reader + +Install **cf-docs-snippet-reader** on this source repository (Actions: Read). cf-docs uses this app later to download the artifact you upload here. + +### Secrets + +| Secret | Purpose | +|--------|---------| +| `CF_DOCS_SNIPPET_WRITER_APP_ID` | Writer app ID (same app as on cf-docs) | +| `CF_DOCS_SNIPPET_WRITER_PRIVATE_KEY` | Writer app private key PEM | + +The writer app is **installed on cf-docs only**; the source repo stores the PEM so it can mint dispatch tokens. Prefer org-level secrets when several repos in the same org publish snippets. + +### Repository variables + +| Variable | Typical value | Purpose | +|----------|---------------|---------| +| `MAIN_REPO_ORG` | `digital-asset` | cf-docs org — dispatch target | +| `MAIN_REPO_NAME` | `docs` | cf-docs repo name — dispatch target | +| `ENABLE_SYNC_PROCESS` | `true` when ready | **Master switch** — see below | + +Set variables under **Settings → Secrets and variables → Actions → Variables**. + +--- + +## `ENABLE_SYNC_PROCESS` + +The publish workflow job is gated: + +```yaml +if: vars.ENABLE_SYNC_PROCESS == 'true' +``` + +| Value | Behavior | +|-------|----------| +| unset or not `true` | Workflow triggers may appear in the Actions tab, but the **publish job is skipped**. Safe for rollout: merge the workflow and extraction scripts before going live. | +| `true` | Full publish runs: extract → artifact → dispatch cf-docs. | + +**Rollout recommendation:** + +1. Merge workflow + extraction scripts with `ENABLE_SYNC_PROCESS` **unset** (or `false`). +2. Configure reader app, writer secrets, and `MAIN_REPO_ORG` / `MAIN_REPO_NAME`. +3. Run a manual `workflow_dispatch` and confirm the job is skipped until the variable is set. +4. Set `ENABLE_SYNC_PROCESS` = `true` and verify end-to-end (cf-docs PR under `docs-main/snippets/external/{repo}/main/`). + +Canton uses a separate variable: `ENABLE_CFDOCS_SNIPPET_SYNC` on the bridge workflow. + +--- + +## Workflow: `publish-cfdocs-snippets.yml` + +### Triggers + +**You must adjust `on.push.paths` for every source repo.** The template lists placeholder paths; copy the workflow only after replacing them with the directories and files that actually affect snippet extraction in that repository. If paths are too narrow, merges that change snippet content will not trigger a publish. If too broad, unrelated pushes will trigger unnecessary runs. + +```yaml +on: + workflow_dispatch: + push: + branches: [main] + paths: + # REQUIRED: replace with paths relevant to THIS source repo + - docs/** + - scripts/docs/** + - gha-scripts/cf-docs/** +``` + +Include at minimum: +- Paths to **source files** referenced in the export config (RST, YAML, shell, etc.) +- The **export config** itself (e.g. `gha-scripts/cf-docs/exportConfig.json` or `scripts/docs/exportConfig.json`) +- The **extraction script** if changes there could alter output + +**Example — splice** (`canton-network/splice`): + +```yaml +paths: + - docs/src/** + - apps/app/src/pack/examples/** + - cluster/helm/** + - gha-scripts/cf-docs/** +``` + +**Example — typical digital-asset repo** (daml, cn-quickstart, dpm): + +```yaml +paths: + - docs/** + - scripts/docs/** +``` + +Also adjust the `run:` path in the extract step to match where `generateOutputDocs.js` lives in that repo. + +### Steps (in order) + +#### 1. Checkout + +Checks out the commit that triggered the workflow. + +#### 2. Extract snippet data + +Runs `generateOutputDocs.js`, which reads the export config and writes one `.mdx` file per snippet into `docs-output/`. + +Adjust the `run:` path to match where the script lives in your repo. + +#### 3. Store artifact output + +Uploads the entire `docs-output/` directory as a GitHub Actions artifact **on the source repository's workflow run** (Actions → artifact storage for that repo/run — **not** a commit or file in cf-docs): + +```yaml +name: ${{ github.event.repository.name }}-snippets +``` + +The artifact name is derived from the repository name (e.g. `splice-snippets`, `daml-shell-snippets`). No per-repo placeholder is required in the template. + +The step output `artifact-id`, together with `run-id` and `repo-org`, tells cf-docs where to download the artifact from the **source repo's** Actions storage via the reader app. + +#### 4. Prepare additional params + +Records `short_sha` for the PR title on cf-docs. + +#### 5. Generate snippet writer app token + +Mints a short-lived token via `actions/create-github-app-token@v2`, scoped to `${MAIN_REPO_ORG}/${MAIN_REPO_NAME}` (cf-docs). + +#### 6. Update main docs repo + +Calls cf-docs via `repository_dispatch` event `update_snippets`: + +| Payload field | Source | Used by cf-docs for | +|---------------|--------|---------------------| +| `artifact-id` | upload-artifact step | Identifying the artifact in **source repo** Actions storage | +| `run-id` | `${{ github.run_id }}` | Workflow run on the **source repo** that holds the artifact | +| `repo-name` | `${{ github.event.repository.name }}` | Target folder `snippets/external/{repo-name}/…` in cf-docs | +| `repo-org` | `${{ github.repository_owner }}` | Which **source repo** the reader app uses to download the artifact | +| `repo-version` | `main` | Target folder `…/{repo-version}/` in cf-docs | +| `trigger_sha_short` | git short SHA | PR title suffix | + +After this step completes successfully, cf-docs owns the rest of the pipeline. + +--- + +## Sequence (source repo only) + +```mermaid +sequenceDiagram + autonumber + participant Dev as Developer + participant GHA as publish-cfdocs-snippets + participant Script as generateOutputDocs.js + participant Art as GHA artifacts (source repo) + participant WApp as cf-docs-snippet-writer + participant CfDocs as digital-asset/docs + + Dev->>GHA: push to main (snippet paths) or workflow_dispatch + Note over GHA: Skipped unless ENABLE_SYNC_PROCESS=true + GHA->>Script: node …/generateOutputDocs.js + Script->>GHA: docs-output/*.mdx + GHA->>Art: upload-artifact on source repo run + GHA->>WApp: create-github-app-token + WApp-->>GHA: writer token + GHA->>CfDocs: repository_dispatch update_snippets + Note over CfDocs: Downloads artifact from source repo,
then PRs snippet files into cf-docs +``` + +--- + +## Local testing before enabling sync + +From a cf-docs checkout you can run extraction locally without dispatching: + +```bash +npm run generate:external-snippets -- splice --source-dir ../splice +``` + +Add `--copy-output --version main` to copy results into cf-docs for inspection. See [update-workflows.md](./update-workflows.md). + +--- + +## Checklist (source repo) + +- [ ] Reader app installed on this repository +- [ ] `CF_DOCS_SNIPPET_WRITER_*` secrets configured +- [ ] `MAIN_REPO_ORG` = `digital-asset`, `MAIN_REPO_NAME` = `docs` +- [ ] `.github/workflows/publish-cfdocs-snippets.yml` merged with **repo-specific `paths` and script path** +- [ ] Extraction script + export config in place +- [ ] Local extraction succeeds (`generateOutputDocs.js` → `docs-output/`, 0 failures) +- [ ] `ENABLE_SYNC_PROCESS` = `true` +- [ ] End-to-end: push to `main` → cf-docs PR updated + +--- + +## Troubleshooting (source repo) + +| Symptom | Check | +|---------|--------| +| Workflow runs but job skipped | `ENABLE_SYNC_PROCESS` = `true` | +| Extraction step fails | Run `generateOutputDocs.js` locally; fix export config vs source files | +| Dispatch 403 | Writer secrets; `MAIN_REPO_ORG` / `MAIN_REPO_NAME` | +| cf-docs cannot download artifact | Reader app installed on **source repo**; payload `run-id` / `artifact-id` / `repo-org` point at that repo's Actions run | +| Wrong folder in cf-docs PR | `PAYLOAD_repo-name` should match `github.event.repository.name` (e.g. `splice`) | diff --git a/config/snippet-config/splice-snippet-list-remote.json b/config/snippet-config/splice-snippet-list-remote.json index 723606b79..425db1acb 100644 --- a/config/snippet-config/splice-snippet-list-remote.json +++ b/config/snippet-config/splice-snippet-list-remote.json @@ -13,6 +13,18 @@ "https://docs.daml.com/canton/usermanual/kms/kms_gcp_setup.html": "[Canton KMS operations](/global-synchronizer/production-operations/kms-operations#configure-a-google-cloud-provider-gcp-kms)" }, "snippets": [ + { + "snippetName": "splice-literal-full-apps-app-src-pack-examples-recovery-manual-identities-dump", + "sourceRepo": "splice", + "sourceFilepath": "apps/app/src/pack/examples/recovery/manual-identities-dump.sc", + "location": { + "type": "fullFile" + }, + "description": "", + "options": { + "language": "scala" + } + }, { "snippetName": "splice-literal-full-apps-app-src-pack-examples-sv-helm-kms-participant-aws-values", "sourceRepo": "splice", @@ -176,6 +188,2384 @@ "options": { "language": "yaml" } + }, + { + "snippetName": "splice-rst-code-docs-src-app-dev-overview-version-information-bash-42", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/app_dev/overview/version_information.rst", + "location": { + "type": "lines", + "start": 42, + "end": 42 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-app-dev-testing-localnet-bash-162", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/app_dev/testing/localnet.rst", + "location": { + "type": "lines", + "start": 162, + "end": 168 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-app-dev-testing-localnet-bash-175", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/app_dev/testing/localnet.rst", + "location": { + "type": "lines", + "start": 175, + "end": 181 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-app-dev-testing-localnet-bash-190", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/app_dev/testing/localnet.rst", + "location": { + "type": "lines", + "start": 190, + "end": 197 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-app-dev-testing-localnet-bash-206", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/app_dev/testing/localnet.rst", + "location": { + "type": "lines", + "start": 206, + "end": 213 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-app-dev-testing-localnet-bash-228", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/app_dev/testing/localnet.rst", + "location": { + "type": "lines", + "start": 228, + "end": 232 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-app-dev-testing-localnet-none-126", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/app_dev/testing/localnet.rst", + "location": { + "type": "lines", + "start": 126, + "end": 127 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-app-dev-testing-localnet-none-147", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/app_dev/testing/localnet.rst", + "location": { + "type": "lines", + "start": 147, + "end": 147 + }, + "description": "", + "options": { + "language": "none", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-configuration-none-51", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/configuration.rst", + "location": { + "type": "lines", + "start": 51, + "end": 53 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-configuration-yaml-70", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/configuration.rst", + "location": { + "type": "lines", + "start": 70, + "end": 72 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-console-access-bash-166", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/console_access.rst", + "location": { + "type": "lines", + "start": 166, + "end": 166 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-console-access-bash-174", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/console_access.rst", + "location": { + "type": "lines", + "start": 174, + "end": 177 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-console-access-none-104", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/console_access.rst", + "location": { + "type": "lines", + "start": 104, + "end": 120 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-console-access-none-136", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/console_access.rst", + "location": { + "type": "lines", + "start": 136, + "end": 148 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-console-access-none-40", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/console_access.rst", + "location": { + "type": "lines", + "start": 40, + "end": 57 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-console-access-none-71", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/console_access.rst", + "location": { + "type": "lines", + "start": 71, + "end": 88 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-console-access-parsed-literal-126", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/console_access.rst", + "location": { + "type": "lines", + "start": 126, + "end": 126 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-console-access-parsed-literal-154", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/console_access.rst", + "location": { + "type": "lines", + "start": 154, + "end": 154 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-console-access-parsed-literal-63", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/console_access.rst", + "location": { + "type": "lines", + "start": 63, + "end": 63 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-console-access-parsed-literal-94", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/console_access.rst", + "location": { + "type": "lines", + "start": 94, + "end": 94 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-traffic-json-94", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/traffic.rst", + "location": { + "type": "lines", + "start": 94, + "end": 104 + }, + "description": "", + "options": { + "language": "json", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-traffic-parsed-literal-129", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/traffic.rst", + "location": { + "type": "lines", + "start": 129, + "end": 129 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-traffic-parsed-literal-88", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/traffic.rst", + "location": { + "type": "lines", + "start": 88, + "end": 88 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-troubleshooting-text-109", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/troubleshooting.rst", + "location": { + "type": "lines", + "start": 109, + "end": 110 + }, + "description": "", + "options": { + "language": "text", + "normalizeIndent": false + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-troubleshooting-text-123", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/troubleshooting.rst", + "location": { + "type": "lines", + "start": 123, + "end": 124 + }, + "description": "", + "options": { + "language": "text", + "normalizeIndent": false + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-troubleshooting-text-135", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/troubleshooting.rst", + "location": { + "type": "lines", + "start": 135, + "end": 136 + }, + "description": "", + "options": { + "language": "text", + "normalizeIndent": false + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-troubleshooting-text-161", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/troubleshooting.rst", + "location": { + "type": "lines", + "start": 161, + "end": 162 + }, + "description": "", + "options": { + "language": "text", + "normalizeIndent": false + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-troubleshooting-text-174", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/troubleshooting.rst", + "location": { + "type": "lines", + "start": 174, + "end": 177 + }, + "description": "", + "options": { + "language": "text", + "normalizeIndent": false + } + }, + { + "snippetName": "splice-rst-code-docs-src-deployment-troubleshooting-text-89", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/deployment/troubleshooting.rst", + "location": { + "type": "lines", + "start": 89, + "end": 90 + }, + "description": "", + "options": { + "language": "text", + "normalizeIndent": false + } + }, + { + "snippetName": "splice-rst-code-docs-src-scalability-scalability-none-117", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/scalability/scalability.rst", + "location": { + "type": "lines", + "start": 117, + "end": 119 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-backup-bash-23", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_backup.rst", + "location": { + "type": "lines", + "start": 23, + "end": 23 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-1033", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 1029, + "end": 1029 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-302", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 302, + "end": 308 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-314", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 314, + "end": 320 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-326", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 326, + "end": 336 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-381", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 381, + "end": 383 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-39", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 39, + "end": 40 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-507", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 507, + "end": 518 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-55", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 55, + "end": 67 + }, + "description": "SV keygen shell commands (RST verbatim block)", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-627", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 627, + "end": 629 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-725", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 721, + "end": 738 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-835", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 831, + "end": 831 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-844", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 840, + "end": 842 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-861", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 857, + "end": 860 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-873", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 869, + "end": 869 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-914", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 910, + "end": 910 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-93", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 93, + "end": 93 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-bash-990", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 986, + "end": 986 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-none-1135", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 1131, + "end": 1139 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-parsed-literal-1005", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 1001, + "end": 1001 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-parsed-literal-354", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 354, + "end": 360 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-parsed-literal-468", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 468, + "end": 480 + }, + "description": "Canton console sample; unescape RST quotes, haskell fence", + "options": { + "language": "haskell", + "normalizeIndent": "baseline", + "unescapeRstQuotes": true + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-parsed-literal-528", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 528, + "end": 531 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-parsed-literal-691", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 687, + "end": 688 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-parsed-literal-701", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 697, + "end": 697 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-parsed-literal-707", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 703, + "end": 705 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-parsed-literal-715", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 711, + "end": 711 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-text-366", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 366, + "end": 367 + }, + "description": "CometBFT config files to retain (RST verbatim block)", + "options": { + "language": "text", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-text-74", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 74, + "end": 75 + }, + "description": "Sample SV keygen output (RST verbatim block)", + "options": { + "language": "text", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-yaml-440", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 440, + "end": 442 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-yaml-448", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 448, + "end": 450 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-yaml-456", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 456, + "end": 458 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-yaml-882", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 878, + "end": 888 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-yaml-900", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 896, + "end": 902 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-helm-yaml-926", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_helm.rst", + "location": { + "type": "lines", + "start": 922, + "end": 980 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-logical-synchronizer-upgrade-none-118", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_logical_synchronizer_upgrade.rst", + "location": { + "type": "lines", + "start": 118, + "end": 124 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-logical-synchronizer-upgrade-none-142", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_logical_synchronizer_upgrade.rst", + "location": { + "type": "lines", + "start": 142, + "end": 144 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-logical-synchronizer-upgrade-none-87", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_logical_synchronizer_upgrade.rst", + "location": { + "type": "lines", + "start": 87, + "end": 89 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-network-resets-bash-75", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_network_resets.rst", + "location": { + "type": "lines", + "start": 75, + "end": 75 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-network-resets-bash-81", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_network_resets.rst", + "location": { + "type": "lines", + "start": 81, + "end": 83 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-network-resets-bash-90", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_network_resets.rst", + "location": { + "type": "lines", + "start": 90, + "end": 92 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-bash-482", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 482, + "end": 501 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-bash-507", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 507, + "end": 532 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-bash-538", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 538, + "end": 558 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-bash-564", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 564, + "end": 585 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-bash-683", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 683, + "end": 684 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-parsed-literal-171", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 171, + "end": 178 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-parsed-literal-193", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 193, + "end": 193 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-parsed-literal-204", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 204, + "end": 206 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-parsed-literal-222", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 222, + "end": 224 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-sql-344", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 344, + "end": 344 + }, + "description": "", + "options": { + "language": "sql", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-sql-359", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 359, + "end": 365 + }, + "description": "", + "options": { + "language": "sql", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-yaml-296", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 296, + "end": 299 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-yaml-309", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 309, + "end": 314 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-yaml-821", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 821, + "end": 823 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-yaml-829", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 829, + "end": 831 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-yaml-838", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 838, + "end": 840 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-yaml-846", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 846, + "end": 848 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-yaml-865", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 865, + "end": 868 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-operations-yaml-889", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_operations.rst", + "location": { + "type": "lines", + "start": 889, + "end": 893 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-pruning-yaml-62", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_pruning.rst", + "location": { + "type": "lines", + "start": 62, + "end": 65 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-restore-bash-102", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_restore.rst", + "location": { + "type": "lines", + "start": 102, + "end": 102 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-restore-bash-57", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_restore.rst", + "location": { + "type": "lines", + "start": 57, + "end": 64 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-restore-bash-74", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_restore.rst", + "location": { + "type": "lines", + "start": 74, + "end": 81 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-security-bash-110", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_security.rst", + "location": { + "type": "lines", + "start": 110, + "end": 112 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-security-bash-73", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_security.rst", + "location": { + "type": "lines", + "start": 73, + "end": 87 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-sv-operator-sv-security-json-94", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/sv_operator/sv_security.rst", + "location": { + "type": "lines", + "start": 94, + "end": 97 + }, + "description": "", + "options": { + "language": "json", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-backups-bash-36", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_backups.rst", + "location": { + "type": "lines", + "start": 36, + "end": 36 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-backups-bash-67", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_backups.rst", + "location": { + "type": "lines", + "start": 67, + "end": 69 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-compose-bash-167", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_compose.rst", + "location": { + "type": "lines", + "start": 167, + "end": 168 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-compose-bash-175", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_compose.rst", + "location": { + "type": "lines", + "start": 175, + "end": 176 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-compose-bash-281", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_compose.rst", + "location": { + "type": "lines", + "start": 281, + "end": 282 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-compose-bash-306", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_compose.rst", + "location": { + "type": "lines", + "start": 306, + "end": 308 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-compose-bash-58", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_compose.rst", + "location": { + "type": "lines", + "start": 58, + "end": 67 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-compose-yaml-105", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_compose.rst", + "location": { + "type": "lines", + "start": 105, + "end": 111 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": false + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-compose-yaml-152", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_compose.rst", + "location": { + "type": "lines", + "start": 152, + "end": 159 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": false + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-compose-yaml-347", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_compose.rst", + "location": { + "type": "lines", + "start": 347, + "end": 357 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": false + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-compose-yaml-96", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_compose.rst", + "location": { + "type": "lines", + "start": 96, + "end": 102 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": false + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-delegations-bash-201", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_delegations.rst", + "location": { + "type": "lines", + "start": 201, + "end": 209 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-delegations-bash-215", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_delegations.rst", + "location": { + "type": "lines", + "start": 215, + "end": 234 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-delegations-bash-251", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_delegations.rst", + "location": { + "type": "lines", + "start": 251, + "end": 269 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-delegations-bash-276", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_delegations.rst", + "location": { + "type": "lines", + "start": 276, + "end": 294 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-delegations-bash-309", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_delegations.rst", + "location": { + "type": "lines", + "start": 309, + "end": 324 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-bash-140", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 140, + "end": 142 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-none-240", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 240, + "end": 241 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-none-248", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 248, + "end": 249 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-none-260", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 260, + "end": 260 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-none-274", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 274, + "end": 274 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-none-299", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 299, + "end": 300 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-none-314", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 314, + "end": 319 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-none-355", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 355, + "end": 384 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-none-397", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 397, + "end": 413 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-none-419", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 419, + "end": 435 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-none-451", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 451, + "end": 453 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-none-485", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 485, + "end": 491 + }, + "description": "", + "options": { + "language": "", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-parsed-literal-268", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 268, + "end": 268 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-parsed-literal-443", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 443, + "end": 444 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-disaster-recovery-yaml-185", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_disaster_recovery.rst", + "location": { + "type": "lines", + "start": 185, + "end": 187 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-bash-545", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 545, + "end": 548 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-bash-557", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 557, + "end": 557 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-bash-598", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 598, + "end": 598 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-bash-642", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 642, + "end": 642 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-bash-65", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 65, + "end": 65 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-parsed-literal-472", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 472, + "end": 474 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-parsed-literal-657", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 657, + "end": 657 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-yaml-127", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 127, + "end": 130 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-yaml-566", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 566, + "end": 576 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-yaml-584", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 584, + "end": 590 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-yaml-607", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 607, + "end": 635 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-yaml-82", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 82, + "end": 84 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-bash-145", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 145, + "end": 147 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-bash-158", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 158, + "end": 160 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-bash-352", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 352, + "end": 358 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-bash-364", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 364, + "end": 370 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-bash-482", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 482, + "end": 488 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-yaml-787", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 789, + "end": 797 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-helm-yaml-815", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_helm.rst", + "location": { + "type": "lines", + "start": 815, + "end": 821 + }, + "description": "", + "options": { + "language": "yaml", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-onboarding-bash-107", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_onboarding.rst", + "location": { + "type": "lines", + "start": 107, + "end": 116 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-onboarding-bash-136", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_onboarding.rst", + "location": { + "type": "lines", + "start": 136, + "end": 165 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-onboarding-parsed-literal-126", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_onboarding.rst", + "location": { + "type": "lines", + "start": 126, + "end": 130 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-onboarding-parsed-literal-86", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_onboarding.rst", + "location": { + "type": "lines", + "start": 86, + "end": 86 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-onboarding-parsed-literal-95", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_onboarding.rst", + "location": { + "type": "lines", + "start": 95, + "end": 100 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-users-bash-48", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_users.rst", + "location": { + "type": "lines", + "start": 48, + "end": 51 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-code-docs-src-validator-operator-validator-users-bash-66", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/validator_users.rst", + "location": { + "type": "lines", + "start": 66, + "end": 69 + }, + "description": "", + "options": { + "language": "bash", + "normalizeIndent": "baseline" + } + }, + { + "snippetName": "splice-rst-full-docs-src-common-backup-suggestion", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/common/backup_suggestion.rst", + "location": { + "type": "fullFile" + }, + "description": "", + "options": { + "transform": "rstinclude", + "normalizeIndent": false + } + }, + { + "snippetName": "splice-rst-full-docs-src-common-sv-extra-dars-notice", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/common/sv_extra_dars_notice.rst", + "location": { + "type": "fullFile" + }, + "description": "", + "options": { + "transform": "rstinclude", + "normalizeIndent": false + } + }, + { + "snippetName": "splice-rst-full-docs-src-common-traffic-topups", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/common/traffic_topups.rst", + "location": { + "type": "fullFile" + }, + "description": "", + "options": { + "transform": "rstinclude", + "normalizeIndent": false + } + }, + { + "snippetName": "splice-rst-full-docs-src-common-wallet-sweeps", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/common/wallet_sweeps.rst", + "location": { + "type": "fullFile" + }, + "description": "", + "options": { + "transform": "rstinclude", + "normalizeIndent": false + } + }, + { + "snippetName": "splice-rst-partial-docs-src-validator-operator-required-network-parameters-9", + "sourceRepo": "splice", + "sourceFilepath": "docs/src/validator_operator/required_network_parameters.rst", + "location": { + "type": "lines", + "start": 9, + "end": 35 + }, + "description": "", + "options": { + "transform": "rstinclude", + "normalizeIndent": false + } } ] } diff --git a/config/snippet-config/splice-wallet-kernel-snippet-list-remote.json b/config/snippet-config/splice-wallet-kernel-snippet-list-remote.json deleted file mode 100644 index 404857d18..000000000 --- a/config/snippet-config/splice-wallet-kernel-snippet-list-remote.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "snippets": [] -} diff --git a/config/snippet-config/update-docs-snippets.yml b/config/snippet-config/update-docs-snippets.yml deleted file mode 100644 index 57ab5e569..000000000 --- a/config/snippet-config/update-docs-snippets.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Update Docs Snippets - -on: - workflow_dispatch: - - push: - branches: - - main - paths: - - docs/wallet-integration-guide/examples/snippets/** - - docs/wallet-integration-guide/examples/scripts/** - -jobs: - update-snippets: - if: vars.ENABLE_SYNC_PROCESS == 'true' - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Extract Snippet data - run: node docs/scripts/generateOutputDocs.js - - - name: Store Artifact output - id: store-artifact - uses: actions/upload-artifact@v7 - with: - name: splice-wallet-kernel-snippets - path: docs-output/ - env: - main_repo_token: ${{ secrets.SOURCE_REPO_TOKEN }} - - - name: Prepare additional params - id: additional-params - run: echo "short_sha=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" - - - name: Update Main Docs Repo - uses: passeidireto/trigger-external-workflow-action@main - env: - PAYLOAD_run-id: ${{ github.run_id }} - PAYLOAD_artifact-id: ${{ steps.store-artifact.outputs.artifact-id }} - PAYLOAD_repo-name: ${{ vars.SOURCE_REPO_NAME }} - PAYLOAD_repo-org: ${{ vars.SOURCE_REPO_ORG }} - PAYLOAD_repo-version: ${{ vars.SOURCE_REPO_VERSION }} - PAYLOAD_trigger_sha_short: ${{ steps.additional-params.outputs.short_sha }} - with: - repository: ${{ vars.MAIN_REPO_ORG }}/${{ vars.MAIN_REPO_NAME }} - event: update_snippets - github_pat: ${{ secrets.MAIN_DOCS_REPO_TOKEN }} diff --git a/config/snippet-config/update-workflow-rev2.md b/config/snippet-config/update-workflow-rev2.md new file mode 100644 index 000000000..47dd68581 --- /dev/null +++ b/config/snippet-config/update-workflow-rev2.md @@ -0,0 +1,401 @@ +# CF Docs snippet sync — rev 2 + +Target architecture for syncing external code snippets into [digital-asset/docs](https://github.com/digital-asset/docs) (cf-docs) using **GitHub Apps**. + +Snippet changes are extracted in a source repository, uploaded as a GHA artifact, and pulled into cf-docs via `repository_dispatch`. cf-docs writes files to `docs-main/snippets/external/{repo}/{version}/` and opens or updates a PR on `main`. + +**Exception:** [DACH-NY/canton](https://github.com/DACH-NY/canton) uses a **CircleCI → GHA bridge** because snippet extraction runs on CircleCI there. Apart from that bridge, every source repo follows the same GHA flow (extract → upload artifact → dispatch cf-docs). + +**Setup:** [app-install-checklist.md](./app-install-checklist.md) +**Source repo guide:** [source-repo-workflow-readme.md](./source-repo-workflow-readme.md) +**Legacy flow / local extraction:** [update-workflows.md](./update-workflows.md) + +Within this document: + +* **cf-docs** — [digital-asset/docs](https://github.com/digital-asset/docs) (consumer) +* **Source repositories** (publishers): + * [DACH-NY/canton](https://github.com/DACH-NY/canton) — CircleCI bridge + * [canton-network/splice](https://github.com/canton-network/splice) + * [digital-asset/daml](https://github.com/digital-asset/daml) + * [digital-asset/cn-quickstart](https://github.com/digital-asset/cn-quickstart) + * [DACH-NY/daml-shell](https://github.com/DACH-NY/daml-shell) + * [digital-asset/dpm](https://github.com/digital-asset/dpm) + * [DACH-NY/scribe](https://github.com/DACH-NY/scribe) + +Publishing runs on **`main` only** (Canton: additionally gated on `CIRCLE_BRANCH == main`). + +--- + +## Overview + +| Path | Source repos | Extract | Artifact | Dispatch to cf-docs | +|------|--------------|---------|----------|-------------------| +| **GHA** | splice, daml, cn-quickstart, daml-shell, dpm, scribe | GHA publish workflow | GHA `upload-artifact` | Writer app → cf-docs | +| **CircleCI bridge** | [DACH-NY/canton](https://github.com/DACH-NY/canton) only | CircleCI `export_mintlify_snippets` | CCI → GHA re-upload | Writer app → cf-docs | + +All GHA source repos share the same pattern: run `generateOutputDocs.js`, upload `docs-output/` as an artifact, mint a writer app token, dispatch `update_snippets` on cf-docs. Copy [scripts/templates/publish-cfdocs-snippets.yml](/scripts/templates/publish-cfdocs-snippets.yml) to `.github/workflows/publish-cfdocs-snippets.yml` on each source repo (adjust paths and script location per repo). + +--- + +## Authentication + +Cross-repo snippet sync uses **two GitHub Apps** (reader + writer). The separate **`GENERATED_DOCS_MERGER`** app is unrelated — it only merges generated reference docs on cf-docs. + +| App | Installed on | Permissions | Used for | +|-----|--------------|-------------|----------| +| **cf-docs-snippet-reader** | Source repos | Actions: Read | cf-docs `download-artifact` from source | +| **cf-docs-snippet-writer** | cf-docs only | Contents + PRs: R/W | Source → cf-docs dispatch; cf-docs PR creation | + +**Not app-authenticated (Canton bridge only):** + +These credentials are **only** used on [DACH-NY/canton](https://github.com/DACH-NY/canton) for the CircleCI → GHA bridge. No other source repo needs them. + +| Credential | Location | Purpose | +|------------|----------|---------| +| `GITHUB_TOKEN` (canton-machine PAT) | CircleCI context on Canton | CircleCI → Canton GHA `publish_cfdocs_snippets` dispatch | +| `CIRCLECI_API_TOKEN` | Canton GHA | Bridge downloads CircleCI snippet artifacts | + +See [GitHub Apps](#github-apps) and [app-install-checklist.md](./app-install-checklist.md). + +--- + +## cf-docs: pulling snippets + +**Workflow:** [pull-external-snippets.yml](/.github/workflows/pull-external-snippets.yml) +**Event:** `update_snippets` + +**Dispatch payload:** + +| Field | Description | +|-------|-------------| +| `artifact-id` | GHA artifact ID on the source repository | +| `run-id` | GHA workflow run ID on the source repository | +| `repo-name` | Source repository name | +| `repo-org` | Source repository org | +| `repo-version` | Version folder (branch name; `main` for Canton) | + +**Steps:** + +1. Mint **reader** app token scoped to `${repo_org}/${repo_name}` +2. `download-artifact` from source GHA run +3. Write to `docs-main/snippets/external/{repo_name}/{repo_version}/` +4. Mint **writer** app token → `create-pull-request` → `external-snippet-update-{repo}-{version}` + +**cf-docs secrets:** + +| Secret | +|--------| +| `CF_DOCS_SNIPPET_READER_APP_ID` | +| `CF_DOCS_SNIPPET_READER_PRIVATE_KEY` | +| `CF_DOCS_SNIPPET_WRITER_APP_ID` | +| `CF_DOCS_SNIPPET_WRITER_PRIVATE_KEY` | + +--- + +## Canton: CircleCI + GHA bridge + +Repository: [DACH-NY/canton](https://github.com/DACH-NY/canton) + +### CircleCI (`export_mintlify_snippets`) + +1. Restore `docs-open/target/snippet_json_data` from workspace +2. Run `node scripts/docs/generateOutputDocs.js` → `docs-output/` +3. Store CircleCI artifact `cfdocs-snippets-{CIRCLE_SHA1}` +4. On **`main` only**: `repository_dispatch` → `publish_cfdocs_snippets` + +**Soft failure:** unless `FAIL_ON_CF_DOCS_ERROR=true` is set in the CircleCI context, export or dispatch failures **do not fail the CI job** (allows testing without blocking `main`). When set to `true`, failures fail the job. + +### Canton GHA ([scripts/templates/publish-cfdocs-snippets-canton-bridge.yml](/scripts/templates/publish-cfdocs-snippets-canton-bridge.yml)) + +1. Download CircleCI artifact `cfdocs-snippets-{sha}` +2. Re-upload as GHA artifact `cfdocs-snippets-{sha}` +3. Mint **writer** app token → dispatch `update_snippets` on cf-docs + +Gated by `ENABLE_CFDOCS_SNIPPET_SYNC == 'true'`. + +**Canton GHA secrets / vars:** + +| Name | Type | Purpose | +|------|------|---------| +| `CF_DOCS_SNIPPET_WRITER_APP_ID` | Secret | Dispatch to cf-docs | +| `CF_DOCS_SNIPPET_WRITER_PRIVATE_KEY` | Secret | Dispatch to cf-docs | +| `CIRCLECI_API_TOKEN` | Secret | Download CCI artifacts *(bridge only)* | +| `MAIN_REPO_ORG` / `MAIN_REPO_NAME` | Variable | cf-docs target | +| `ENABLE_CFDOCS_SNIPPET_SYNC` | Variable | Enable bridge | + +**CircleCI *(bridge only)*:** + +| Name | Purpose | +|------|---------| +| `GITHUB_TOKEN` (context) | CCI → Canton GHA dispatch | +| `FAIL_ON_CF_DOCS_ERROR` | Set `true` to fail job on export/dispatch errors *(optional)* | + +--- + +## GHA source repos + +All repositories below use the same GHA flow. **Template:** [scripts/templates/publish-cfdocs-snippets.yml](/scripts/templates/publish-cfdocs-snippets.yml) → copy to `.github/workflows/publish-cfdocs-snippets.yml`. **Setup details:** [source-repo-workflow-readme.md](./source-repo-workflow-readme.md). + +1. Extract snippets → `docs-output/` +2. `upload-artifact` (name: `{repository.name}-snippets`, from `${{ github.event.repository.name }}`) +3. Mint writer app token → dispatch `update_snippets` on cf-docs + +### Enable switch: `ENABLE_SYNC_PROCESS` + +The publish job runs only when the repository variable **`ENABLE_SYNC_PROCESS`** is exactly `true`: + +```yaml +if: vars.ENABLE_SYNC_PROCESS == 'true' +``` + +Leave unset (or set to any other value) while rolling out the workflow and extraction scripts — triggers may fire, but the publish job is skipped until you are ready for live sync. Set to `true` after reader app install, writer secrets, and a successful local extraction test. + +*(Canton bridge uses `ENABLE_CFDOCS_SNIPPET_SYNC` instead.)* + +**Secrets (each source repo):** `CF_DOCS_SNIPPET_WRITER_*` +**Variables:** + +| Variable | Value | Purpose | +|----------|-------|---------| +| `MAIN_REPO_ORG` | `digital-asset` | cf-docs org (dispatch target) | +| `MAIN_REPO_NAME` | `docs` | cf-docs repo name | +| `ENABLE_SYNC_PROCESS` | `true` when live | Enables publish job | + +**Reader app:** installed on the source repo (not on cf-docs) + +--- + +## Splice (GHA source) + +Repository: [canton-network/splice](https://github.com/canton-network/splice) + +### Layout + +| Path | Role | +|------|------| +| `gha-scripts/cf-docs/generateOutputDocs.js` | Snippet extraction script | +| `gha-scripts/cf-docs/exportConfig.json` | Snippet definitions (synced from cf-docs `splice-snippet-list-remote.json`) | +| `.github/workflows/publish-cfdocs-snippets.yml` | Publish workflow | +| `docs-output/` | Generated snippets *(CI artifact, not committed)* | + +### Workflow + +**File:** `.github/workflows/publish-cfdocs-snippets.yml` + +**Triggers:** push to `main` on snippet source paths, or `workflow_dispatch`: + +```yaml +paths: + - docs/src/** + - apps/app/src/pack/examples/** + - cluster/helm/** + - gha-scripts/cf-docs/** +``` + +**Steps:** checkout → `node gha-scripts/cf-docs/generateOutputDocs.js` → upload artifact `${{ github.event.repository.name }}-snippets` → dispatch cf-docs with `repo-name` / `repo-org` from `${{ github.event.repository.name }}` and `${{ github.repository_owner }}`, `repo-version: main`. + +Job gated by **`ENABLE_SYNC_PROCESS`** = `true` — see [source-repo-workflow-readme.md](./source-repo-workflow-readme.md#enable_sync_process). + +### Installation checklist + +1. Install **reader** app on [canton-network/splice](https://github.com/canton-network/splice) +2. Add writer app secrets (`CF_DOCS_SNIPPET_WRITER_*`) on splice (or `canton-network` org secret) +3. Set repository variables: `MAIN_REPO_ORG` = `digital-asset`, `MAIN_REPO_NAME` = `docs` +4. Set `ENABLE_SYNC_PROCESS` = `true` when ready to publish +5. Merge `.github/workflows/publish-cfdocs-snippets.yml` and `gha-scripts/cf-docs/` on `main` +6. Verify: push to `main` → splice workflow → cf-docs PR under `docs-main/snippets/external/splice/main/` + +Snippet config in cf-docs: [splice-snippet-list-remote.json](./splice-snippet-list-remote.json) (~172 snippets). + +--- + +## GitHub Apps + +### How token minting works + +Workflows call [`actions/create-github-app-token@v2`](https://github.com/actions/create-github-app-token) with `APP_ID` + `PRIVATE_KEY` from secrets. Tokens are short-lived and scoped per step. + +**Reader (cf-docs pulls from source):** + +```yaml +- uses: actions/create-github-app-token@v2 + id: reader-token + with: + app-id: ${{ secrets.CF_DOCS_SNIPPET_READER_APP_ID }} + private-key: ${{ secrets.CF_DOCS_SNIPPET_READER_PRIVATE_KEY }} + owner: ${{ env.repo_org }} + repositories: ${{ env.repo_name }} +``` + +**Writer (dispatch or PR on cf-docs):** + +```yaml +- uses: actions/create-github-app-token@v2 + id: writer-token + with: + app-id: ${{ secrets.CF_DOCS_SNIPPET_WRITER_APP_ID }} + private-key: ${{ secrets.CF_DOCS_SNIPPET_WRITER_PRIVATE_KEY }} + owner: ${{ vars.MAIN_REPO_ORG }} # source-repo dispatch only + repositories: ${{ vars.MAIN_REPO_NAME }} +``` + +Writer app is **installed on cf-docs only**. Source repos hold the private key but do not install the app. + +### Why two apps? + +App permissions are global per app. A single app with Contents write must be installed on source repos to read their artifacts — granting write access on Canton, splice, etc. Two apps keep sources read-only from cf-docs' perspective. + +### Credential topology + +```text +READER (Actions: Read) WRITER (Contents + PRs R/W) +installed on source repos installed on cf-docs only +private key on cf-docs private key on cf-docs + sources +``` + +--- + +## Full flow + +```mermaid +flowchart TB + dev(["Developer merges to main"]) + + subgraph sources ["Source repositories"] + subgraph cantonPath ["Canton — CircleCI + GHA bridge"] + cci["CircleCI export_mintlify_snippets"] + cciOut[("CCI artifact cfdocs-snippets-{sha}")] + cciPat["GITHUB_TOKEN → publish_cfdocs_snippets"] + bridge["Canton GHA bridge"] + bridgeOut[("GHA artifact")] + bridgeWriter["Writer app token"] + end + subgraph ghaPath ["GHA sources (splice, daml, …)"] + extWF["publish-cfdocs-snippets"] + extOut[("GHA artifact docs-output")] + extWriter["Writer app token"] + end + end + + subgraph apps ["GitHub Apps"] + readerApp["cf-docs-snippet-reader"] + writerApp["cf-docs-snippet-writer"] + end + + subgraph cfdocs ["cf-docs (digital-asset/docs)"] + pullWF["pull-external-snippets"] + readerMint["Reader app token"] + download["download-artifact"] + targetDir["docs-main/snippets/external/"] + writerMint["Writer app token"] + pr["create-pull-request"] + end + + dev --> cci + dev --> extWF + cci --> cciOut --> cciPat --> bridge + bridge --> bridgeOut --> bridgeWriter + writerApp -.-> bridgeWriter + bridgeWriter --> pullWF + extWF --> extOut --> extWriter + writerApp -.-> extWriter + extWriter --> pullWF + pullWF --> readerMint + readerApp -.-> readerMint + readerMint --> download + bridgeOut --> download + extOut --> download + download --> targetDir + pullWF --> writerMint + writerApp -.-> writerMint + writerMint --> pr + targetDir --> pr +``` + +### Sequence (auth-focused) + +```mermaid +sequenceDiagram + autonumber + participant Src as Source automation + participant WApp as cf-docs-snippet-writer + participant GHA as GHA artifacts (source) + participant CfDocs as pull-external-snippets + participant RApp as cf-docs-snippet-reader + participant PR as cf-docs PR + + Src->>GHA: upload-artifact + Src->>WApp: create-github-app-token (cf-docs) + WApp-->>Src: writer token + Src->>CfDocs: repository_dispatch update_snippets + + CfDocs->>RApp: create-github-app-token (source) + RApp-->>CfDocs: reader token + CfDocs->>GHA: download-artifact + CfDocs->>CfDocs: docs-main/snippets/external/... + + CfDocs->>WApp: create-github-app-token (cf-docs) + WApp-->>CfDocs: writer token + CfDocs->>PR: create-pull-request +``` + +--- + +## Source repo installation + +Track rollout per repository. Update as apps are installed and workflows merged. + +**Sync path:** `GHA` = standard GitHub Actions flow · `CCI bridge` = Canton CircleCI path + +**Status:** `—` not started · `WIP` in progress · `Live` app auth verified + +| Snippet key | GitHub repository | Path | Snippet config | Workflow | Status | Notes | +|-------------|-------------------|------|----------------|----------|--------|-------| +| `canton` | [DACH-NY/canton](https://github.com/DACH-NY/canton) | CCI bridge | [canton-snippet-list-remote.json](./canton-snippet-list-remote.json) | `publish-cfdocs-snippets.yml` + CCI | WIP | ~335 snippets. `FAIL_ON_CF_DOCS_ERROR` unset during rollout. Cross-org reader install. | +| `splice` | [canton-network/splice](https://github.com/canton-network/splice) | GHA | [splice-snippet-list-remote.json](./splice-snippet-list-remote.json) | `publish-cfdocs-snippets.yml` | WIP | Scripts in `gha-scripts/cf-docs/`. ~12 snippets. | +| `daml` | [digital-asset/daml](https://github.com/digital-asset/daml) | GHA | [daml-snippet-list-remote.json](./daml-snippet-list-remote.json) | TBC | — | | +| `cn-quickstart` | [digital-asset/cn-quickstart](https://github.com/digital-asset/cn-quickstart) | GHA | [cn-quickstart-snippet-list-remote.json](./cn-quickstart-snippet-list-remote.json) | TBC | — | | +| `daml-shell` | [DACH-NY/daml-shell](https://github.com/DACH-NY/daml-shell) | GHA | [daml-shell-snippet-list-remote.json](./daml-shell-snippet-list-remote.json) | TBC | — | | +| `dpm` | [digital-asset/dpm](https://github.com/digital-asset/dpm) | GHA | [dpm-snippet-list-remote.json](./dpm-snippet-list-remote.json) | TBC | — | | +| `scribe` | [DACH-NY/scribe](https://github.com/DACH-NY/scribe) | GHA | [scribe-snippet-list-remote.json](./scribe-snippet-list-remote.json) | TBC | — | | + +### Per-repo onboarding checklist + +```markdown +- [ ] Reader app installed on source repo +- [ ] Writer app secrets on source repo +- [ ] MAIN_REPO_ORG / MAIN_REPO_NAME variables set +- [ ] ENABLE_SYNC_PROCESS=true when ready for live sync +- [ ] Extraction workflow merged +- [ ] End-to-end test on main → cf-docs PR +- [ ] Tracker row → Live +``` + +### cf-docs (consumer) + +| Item | Value | +|------|-------| +| Repository | [digital-asset/docs](https://github.com/digital-asset/docs) | +| Pull workflow | [pull-external-snippets.yml](/.github/workflows/pull-external-snippets.yml) | +| Reader + writer secrets | `CF_DOCS_SNIPPET_READER_*`, `CF_DOCS_SNIPPET_WRITER_*` | +| Writer app installation | cf-docs repo only | +| Merger app | `GENERATED_DOCS_MERGER_*` — separate, generated docs only | + +--- + +## Reference files + +| File | Role | +|------|------| +| [app-install-checklist.md](./app-install-checklist.md) | Step-by-step app + secret setup | +| [source-repo-workflow-readme.md](./source-repo-workflow-readme.md) | Source repo publish workflow guide | +| [scripts/templates/publish-cfdocs-snippets.yml](/scripts/templates/publish-cfdocs-snippets.yml) | GHA source repo template | +| [scripts/templates/publish-cfdocs-snippets-canton-bridge.yml](/scripts/templates/publish-cfdocs-snippets-canton-bridge.yml) | Canton CircleCI → GHA bridge template | +| [pull-external-snippets.yml](/.github/workflows/pull-external-snippets.yml) | cf-docs consumer | +| `*-snippet-list-remote.json` | Snippet definitions | + +--- + +## Cross-org note + +Source repos span multiple orgs (`DACH-NY`, `canton-network`, `digital-asset`). Reader app installs need approval from each org. Writer private keys on cross-org repos (e.g. Canton, daml-shell, scribe) may require org secret policy allowance. diff --git a/config/snippet-config/update-workflows.md b/config/snippet-config/update-workflows.md index b23efb955..721ffbe99 100644 --- a/config/snippet-config/update-workflows.md +++ b/config/snippet-config/update-workflows.md @@ -6,6 +6,8 @@ This document describes the external snippet update workflow for this docs repos The automation to pull the snippet updates into this repository is implemented using GitHub Action workflows +> **Rev 2 (GitHub Apps, Canton bridge):** see [update-workflow-rev2.md](./update-workflow-rev2.md) and [app-install-checklist.md](./app-install-checklist.md). + ## Local one-command extraction From this repository, use `generate:external-snippets` to copy the matching helper/config into a local source repository and run extraction there: @@ -36,13 +38,13 @@ Changes in the external repository snippet source files are being extracted on t ## Extract snippet files In the external repository, three files control the extraction of snippets: -* [config/snippet-config/update-docs-snippets.yml](/config/snippet-config/update-docs-snippets.yml) - GitHub workflow file -* [config/snippet-config/splice-wallet-kernel-snippet-list-remote.json](/config/snippet-config/splice-wallet-kernel-snippet-list-remote.json) - The list defining the snippets to be extracted +* [scripts/templates/publish-cfdocs-snippets.yml](/scripts/templates/publish-cfdocs-snippets.yml) - GitHub workflow template (copy to source repo) +* The matching `*-snippet-list-remote.json` from this folder - The list defining the snippets to be extracted * [scripts/helpers/generateOutputDocs.js](/scripts/helpers/generateOutputDocs.js) - Script that extracts the snippets defined in the snippet list. -The location of the script and config file might vary depending on the source repo file structure. In the splice-wallet-kernel repository, these are placed inside the `/docs/` folder: -* The snippet list json file is located at `/docs/config/exportConfig.json` -* The helper script is located at `/docs/scripts/generateOutputDocs.js` +The location of the script and config file might vary depending on the source repo file structure. For example, in `daml-shell` they live under `scripts/docs/`: +* The snippet list json file is copied to `scripts/docs/exportConfig.json` +* The helper script is copied to `scripts/docs/generateOutputDocs.js` ### Manual extraction @@ -52,15 +54,15 @@ The GitHub action file needs to be adjusted accordingly: ``` paths: - - docs/wallet-integration-guide/examples/snippets/** - - docs/wallet-integration-guide/examples/scripts/** + - docs/** # adjust to snippet source paths in the source repo + - scripts/docs/** ``` Line 9-11 with the paths to trigger the update workflow ``` -run: node docs/scripts/generateOutputDocs.js +run: node scripts/docs/generateOutputDocs.js ``` -Line 21 with the path to the `generateOutputDocs.js` script +Line 21 with the path to the `generateOutputDocs.js` script (adjust per repo layout) The snippet extraction script is then called from the GitHub action and extracts snippet files into a temp folder `docs-output`. During the extraction, the files are also transformed: Content is wrapped into a markdown codeblock. The content of this folder (full extract) is then stored into the [GitHub artifact storage](https://docs.github.com/en/actions/concepts/workflows-and-actions/workflow-artifacts). Afterwards, the `update_snippets` workflow is called on the main repository (this repo), which will pull the snippet files. @@ -74,7 +76,7 @@ In this repository, the [pull-external-snippets](/.github/workflows/pull-externa * repo-org: External repo org * repo-version: External repo version -It pulls the external artifact and places the files into `snippets/external/{repo_name}/{repo_version}`. Then, a PR is created (if there are any changed files) towards main on this repository. The PR title contains the repo name, version and the last commit hash (short) of the external repo. If another update is pushed on the external repository, the existing PR is being updated automatically. +It pulls the external artifact and places the files into `docs-main/snippets/external/{repo_name}/{repo_version}`. Then, a PR is created (if there are any changed files) towards main on this repository. The PR title contains the repo name, version and the last commit hash (short) of the external repo. If another update is pushed on the external repository, the existing PR is being updated automatically. ## Full workflow sequence @@ -83,7 +85,7 @@ sequenceDiagram autonumber participant Dev as Developer participant ExtRepo as External Repository - participant ExtWF as External GH Workflow
update-docs-snippets.yml + participant ExtWF as External GH Workflow
publish-cfdocs-snippets.yml participant ExtScript as docs/scripts/generateOutputDocs.js participant Artifact as GitHub Artifact Storage participant MainWF as Main Repo Workflow
pull-external-snippets (update_snippets) @@ -92,13 +94,13 @@ sequenceDiagram Dev->>ExtRepo: Push changes to snippet source files ExtRepo->>ExtWF: Trigger on configured path filters ExtWF->>ExtScript: Run extraction command - Note over ExtScript: Reads docs/config/exportConfig.json
Extracts configured snippets + Note over ExtScript: Reads scripts/docs/exportConfig.json
Extracts configured snippets ExtScript->>ExtRepo: Write extracted files to docs-output/ ExtWF->>Artifact: Upload docs-output as artifact ExtWF->>MainWF: Trigger update_snippets
(artifact-id, run-id, repo-name, repo-org, repo-version) MainWF->>Artifact: Download external artifact - MainWF->>MainRepo: Copy files to snippets/external/REPO_NAME/REPO_VERSION + MainWF->>MainRepo: Copy files to docs-main/snippets/external/REPO_NAME/REPO_VERSION MainWF->>MainRepo: Detect file changes MainWF->>MainRepo: Create/update PR to main
title includes repo/version/short commit hash @@ -108,60 +110,23 @@ sequenceDiagram # Tokens and variables/secrets configuration -## Target repository (this repo) configuration - -On the target repository, the following repository environment **secrets** must be configured: -* `EXTERNAL_REPO_TOKEN` - token used to access the artifact of the external repository -* `DOCS_PR_TOKEN` - token used to create the Pull Request on this repository - - -## Source repository configuration - -On the source repository, the following secret must be configured: -* `MAIN_DOCS_REPO_TOKEN` - -additionally, the following environment variables must be set: -* `MAIN_REPO_ORG` - `digital-asset` -* `MAIN_REPO_NAME` - `docs` -* `SOURCE_REPO_NAME` - `{SOURCE_REPOSITORY_NAME}` -* `SOURCE_REPO_ORG` - `{SOURCE_REPOSITORY_ORG}` -* `SOURCE_REPO_VERSION` - `main` -* `ENABLE_SYNC_PROCESS` - `true` - -## Token permissions - -The following token permission must be configured on these tokens: - -**EXTERNAL_REPO_TOKEN** - -* repository scope: External repositories - * `hyperledger-labs/splice-wallet-kernel/` - * `DACH-NY/canton` - * `digital-asset/daml` - * `hyperledger-labs/splice` - * TODO: finalize list - -* permission scope: - * Actions: Read - -**DOCS_PR_TOKEN** - -* repository scope: This repository - * `digital-asset/docs` +Snippet sync uses **GitHub Apps** (reader + writer). See [update-workflow-rev2.md](./update-workflow-rev2.md) and [app-install-checklist.md](./app-install-checklist.md). -* permission scope: - * Contents: Read and write - * Pull requests: Read and write +Legacy PAT names (`EXTERNAL_REPO_TOKEN`, `DOCS_PR_TOKEN`, `MAIN_DOCS_REPO_TOKEN`) are **not used** in rev 2 workflows. -**MAIN_DOCS_REPO_TOKEN** +## Source repository configuration (GHA-only template) -* repository scope: This repository - * `digital-asset/docs` +On GHA-only source repositories. Full setup: [source-repo-workflow-readme.md](./source-repo-workflow-readme.md). -* permission scope: - * Contents: Read and write +| Name | Type | Purpose | +|------|------|---------| +| `CF_DOCS_SNIPPET_WRITER_APP_ID` | Secret | Writer app — dispatch to cf-docs | +| `CF_DOCS_SNIPPET_WRITER_PRIVATE_KEY` | Secret | Writer app private key | +| `MAIN_REPO_ORG` | Variable | cf-docs org | +| `MAIN_REPO_NAME` | Variable | cf-docs repo | +| `ENABLE_SYNC_PROCESS` | Variable | Must be `true` to run the publish job (master switch) | -Note: The `DOCS_PR_TOKEN` can also be used as `MAIN_DOCS_REPO_TOKEN` +The workflow derives `repo-name`, `repo-org`, and artifact name from `${{ github.event.repository.name }}` and `${{ github.repository_owner }}` — no separate `SOURCE_REPO_*` variables are required. # Integration in the documentation @@ -178,7 +143,7 @@ import MySnippet from "/shared/my-snippet.mdx"; The above mentioned files: * `config/snippet-config/*-snippet-list-remote.json` -* `config/snippet-config/update-docs-snippets.yml` +* `scripts/templates/publish-cfdocs-snippets.yml` * `scripts/generateOutputDocs.js` are only added to this repository for reference. They are only used in the external repositories. @@ -189,4 +154,4 @@ Currently, snippets are only being added and updated, but not deleted. ## Complex build extraction -This readme currently shows the process for simple repositories, where the snippets can be extracted directly (like the splice-wallet-kernel repository) and needs to be updated to reflect the build steps on more complex repositories (like the canton repository), which run before the snippet extraction. +Repositories with a complex build before extraction (for example Canton) use the rev 2 flow documented in [update-workflow-rev2.md](./update-workflow-rev2.md). diff --git a/scripts/generate_external_snippets.py b/scripts/generate_external_snippets.py index 77f4e27bc..b9911169b 100644 --- a/scripts/generate_external_snippets.py +++ b/scripts/generate_external_snippets.py @@ -3,7 +3,7 @@ Examples: python3 scripts/generate_external_snippets.py canton --source-dir ../canton - python3 scripts/generate_external_snippets.py wallet-gateway --source-dir ../wallet-gateway + python3 scripts/generate_external_snippets.py daml-shell --source-dir ../daml-shell python3 scripts/generate_external_snippets.py canton --copy-output --version main """ @@ -29,6 +29,7 @@ class SnippetRepo: aliases: tuple[str, ...] output_repo_name: str | None = None helper_name: str = "generateOutputDocs.js" + scripts_subdir: str = "scripts/docs" prepare: tuple[str, ...] = () needs_docker: bool = False @@ -77,19 +78,7 @@ class SnippetRepo: name="splice", config_name="splice-snippet-list-remote.json", aliases=("splice",), - ), - "wallet-gateway": SnippetRepo( - name="wallet-gateway", - config_name="splice-wallet-kernel-snippet-list-remote.json", - aliases=("wallet-gateway", "splice-wallet-kernel"), - helper_name="generateOutputDocs.cjs", - ), - "splice-wallet-kernel": SnippetRepo( - name="splice-wallet-kernel", - config_name="splice-wallet-kernel-snippet-list-remote.json", - aliases=("splice-wallet-kernel", "wallet-gateway"), - output_repo_name="wallet-gateway", - helper_name="generateOutputDocs.cjs", + scripts_subdir="gha-scripts/cf-docs", ), } @@ -322,7 +311,7 @@ def checkout_ref(source_dir: Path, ref: str | None, fetch: bool, dry_run: bool) def copy_helper_and_config(repo: SnippetRepo, source_dir: Path, dry_run: bool) -> Path: - target_scripts = source_dir / "scripts" / "docs" + target_scripts = source_dir / repo.scripts_subdir target_helper = target_scripts / repo.helper_name target_export = target_scripts / "exportConfig.json" diff --git a/scripts/templates/publish-cfdocs-snippets-canton-bridge.yml b/scripts/templates/publish-cfdocs-snippets-canton-bridge.yml new file mode 100644 index 000000000..5de5ffb8d --- /dev/null +++ b/scripts/templates/publish-cfdocs-snippets-canton-bridge.yml @@ -0,0 +1,128 @@ +name: Publish CF Docs Snippets + +# Template for Canton (CircleCI + GHA bridge). Copy to: +# .github/workflows/publish-cfdocs-snippets.yml +# on DACH-NY/canton. + +on: + repository_dispatch: + types: [publish_cfdocs_snippets] + workflow_dispatch: + inputs: + job_number: + description: CircleCI job number for export_mintlify_snippets + required: true + type: string + sha: + description: Full commit SHA (CIRCLE_SHA1) + required: true + type: string + branch: + description: Branch name (expected main) + required: true + type: string + default: main + project_slug: + description: CircleCI project slug (e.g. gh/DACH-NY/canton) + required: false + type: string + +permissions: + actions: write + contents: read + +jobs: + publish_cfdocs_snippets: + if: vars.ENABLE_CFDOCS_SNIPPET_SYNC == 'true' + runs-on: ubuntu-latest + env: + job_number: ${{ github.event.client_payload.job_number || inputs.job_number }} + sha: ${{ github.event.client_payload.sha || inputs.sha }} + branch: ${{ github.event.client_payload.branch || inputs.branch }} + project_slug: ${{ github.event.client_payload.project_slug || inputs.project_slug || format('gh/{0}/{1}', github.repository_owner, github.event.repository.name) }} + artifact_prefix: cfdocs-snippets-${{ github.event.client_payload.sha || inputs.sha }} + steps: + - name: Validate inputs + run: | + set -euo pipefail + test -n "${job_number}" + test -n "${sha}" + test -n "${branch}" + test -n "${project_slug}" + if [ "${branch}" != "main" ]; then + echo "Snippet sync only runs for main builds (branch=${branch})" + exit 1 + fi + + - name: Download CircleCI snippet artifacts + env: + CIRCLECI_API_TOKEN: ${{ secrets.CIRCLECI_API_TOKEN }} + run: | + set -euo pipefail + artifacts_json="$(mktemp)" + curl -sS --fail-with-body \ + -H "Circle-Token: ${CIRCLECI_API_TOKEN}" \ + "https://circleci.com/api/v2/project/${project_slug}/job/${job_number}/artifacts" \ + > "${artifacts_json}" + + mkdir -p docs-output + matched=0 + while IFS=$'\t' read -r artifact_path artifact_url; do + [ -z "${artifact_path}" ] && continue + rel_path="${artifact_path#${artifact_prefix}/}" + if [ "${rel_path}" = "${artifact_path}" ]; then + continue + fi + matched=$((matched + 1)) + target="docs-output/${rel_path}" + mkdir -p "$(dirname "${target}")" + curl -sS --fail-with-body -o "${target}" "${artifact_url}" + done < <(jq -r --arg prefix "${artifact_prefix}/" \ + '.items[] | select(.path | startswith($prefix)) | [.path, .url] | @tsv' \ + "${artifacts_json}") + + if [ "${matched}" -eq 0 ]; then + echo "No CircleCI artifacts found with prefix ${artifact_prefix}/" + jq -r '.items[].path' "${artifacts_json}" | head -20 || true + exit 1 + fi + + snippet_count="$(find docs-output -name '*.mdx' | wc -l | tr -d ' ')" + echo "Downloaded ${snippet_count} snippet files from CircleCI" + test "${snippet_count}" -gt 0 + + - name: Store artifact output + id: store-artifact + uses: actions/upload-artifact@v7 + with: + name: cfdocs-snippets-${{ env.sha }} + path: docs-output/ + + - name: Prepare additional params + id: additional-params + run: echo "short_sha=${sha:0:7}" >> "$GITHUB_OUTPUT" + env: + sha: ${{ env.sha }} + + - name: Generate snippet writer app token + id: writer-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.CF_DOCS_SNIPPET_WRITER_APP_ID }} + private-key: ${{ secrets.CF_DOCS_SNIPPET_WRITER_PRIVATE_KEY }} + owner: ${{ vars.MAIN_REPO_ORG }} + repositories: ${{ vars.MAIN_REPO_NAME }} + + - name: Update main docs repo + uses: passeidireto/trigger-external-workflow-action@main + env: + PAYLOAD_run-id: ${{ github.run_id }} + PAYLOAD_artifact-id: ${{ steps.store-artifact.outputs.artifact-id }} + PAYLOAD_repo-name: ${{ github.event.repository.name }} + PAYLOAD_repo-org: ${{ github.repository_owner }} + PAYLOAD_repo-version: ${{ env.branch }} + PAYLOAD_trigger_sha_short: ${{ steps.additional-params.outputs.short_sha }} + with: + repository: ${{ vars.MAIN_REPO_ORG }}/${{ vars.MAIN_REPO_NAME }} + event: update_snippets + github_pat: ${{ steps.writer-token.outputs.token }} diff --git a/scripts/templates/publish-cfdocs-snippets.yml b/scripts/templates/publish-cfdocs-snippets.yml new file mode 100644 index 000000000..1905e1bdf --- /dev/null +++ b/scripts/templates/publish-cfdocs-snippets.yml @@ -0,0 +1,76 @@ +name: Publish CF Docs Snippets + +# Template for GHA source repositories (splice, daml, cn-quickstart, …). +# Copy to .github/workflows/publish-cfdocs-snippets.yml on the source repo. +# +# Before copying, adjust for THIS source repo (required): +# - on.push.paths: every path that affects snippet content or extraction +# - run: path to generateOutputDocs.js in the source repo +# +# Artifact upload stores files in this repo's GHA artifact storage (not cf-docs). +# cf-docs downloads via dispatch payload and merges into docs-main/snippets/external/… +# +# See config/snippet-config/source-repo-workflow-readme.md for setup details. + +on: + workflow_dispatch: + + push: + branches: + - main + paths: + # REQUIRED: replace with paths for this source repo (see source-repo-workflow-readme.md). + - docs/** + - scripts/docs/** + +permissions: + actions: write + contents: read + +jobs: + publish_cfdocs_snippets: + # Set repository variable ENABLE_SYNC_PROCESS=true to activate (see source-repo-workflow-readme.md). + if: vars.ENABLE_SYNC_PROCESS == 'true' + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Extract snippet data + # Adjust script path per repo layout (e.g. gha-scripts/cf-docs/generateOutputDocs.js). + run: node scripts/docs/generateOutputDocs.js + + - name: Store artifact output + id: store-artifact + # Artifact is stored on this workflow run (source repo Actions storage), not in cf-docs. + uses: actions/upload-artifact@v7 + with: + name: ${{ github.event.repository.name }}-snippets + path: docs-output/ + + - name: Prepare additional params + id: additional-params + run: echo "short_sha=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" + + - name: Generate snippet writer app token + id: writer-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.CF_DOCS_SNIPPET_WRITER_APP_ID }} + private-key: ${{ secrets.CF_DOCS_SNIPPET_WRITER_PRIVATE_KEY }} + owner: ${{ vars.MAIN_REPO_ORG }} + repositories: ${{ vars.MAIN_REPO_NAME }} + + - name: Update main docs repo + uses: passeidireto/trigger-external-workflow-action@main + env: + PAYLOAD_run-id: ${{ github.run_id }} + PAYLOAD_artifact-id: ${{ steps.store-artifact.outputs.artifact-id }} + PAYLOAD_repo-name: ${{ github.event.repository.name }} + PAYLOAD_repo-org: ${{ github.repository_owner }} + PAYLOAD_repo-version: main + PAYLOAD_trigger_sha_short: ${{ steps.additional-params.outputs.short_sha }} + with: + repository: ${{ vars.MAIN_REPO_ORG }}/${{ vars.MAIN_REPO_NAME }} + event: update_snippets + github_pat: ${{ steps.writer-token.outputs.token }} diff --git a/tests/test_generate_external_snippets.py b/tests/test_generate_external_snippets.py index 550e5b15c..2a9f7a05a 100644 --- a/tests/test_generate_external_snippets.py +++ b/tests/test_generate_external_snippets.py @@ -22,19 +22,6 @@ def test_copy_helper_and_config_copies_helper(tmp_path: Path) -> None: assert (target_scripts / "exportConfig.json").is_file() -def test_copy_helper_and_config_preserves_repo_specific_helper_name(tmp_path: Path) -> None: - source_dir = tmp_path / "splice-wallet-kernel" - helper = generator.copy_helper_and_config( - generator.REPOS["splice-wallet-kernel"], - source_dir, - dry_run=False, - ) - - target_scripts = source_dir / "scripts" / "docs" - assert helper == target_scripts / "generateOutputDocs.cjs" - assert helper.is_file() - - def test_validate_inputs_reports_missing_helper( tmp_path: Path, monkeypatch: pytest.MonkeyPatch ) -> None: