Skip to content

feat: extract --check and the check-sync GitHub Action (#28, 1/2) - #57

Open
adrianbrowning wants to merge 4 commits into
mainfrom
feat/28-github-actions
Open

adrianbrowning wants to merge 4 commits into
mainfrom
feat/28-github-actions

Conversation

@adrianbrowning

@adrianbrowning adrianbrowning commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Part of #28 (PR 1 of 2: check-sync). The update-readme action follows in a stacked PR, which closes #28.

Summary

A read-only CI gate that verifies both directions of sync, plus the CLI support it needs.

 packages/mdcode/src/
   commands/extract.ts   extract()
+                          check: plan each target exactly as extract would, compare instead of write
+                          → "unchanged", or out_of_sync per block (region differs / missing / file missing / whole file differs)
   cli.ts                extract
+                          --check (exit 1 on drift, 2 if a target would be skipped; never writes)
   region.ts             spliceRegions
~                          don't re-indent a body whose first line already has the marker's indent
+.github/actions/check-sync/
+  action.yml            composite: setup-node (pinned SHA) → node check-sync.mjs
+  check-sync.mjs        update --check  +  extract --check --force  → annotations, job summary, `problems` output
 .github/workflows/ci_test.yml
+                          dogfoods ./.github/actions/check-sync on this repo's docs with the workspace build

Decisions (agreed before starting):

  • Extract direction uses native extract --check, not a temp copy of the checkout. It builds each target exactly as extract would: whole file, region splice or appended region. The action passes --force so existing whole files are compared rather than reported skipped.
  • CLI version: the action runs npx --yes mdcode-ts@<version>, where the version comes from packages/mdcode/package.json at the action's own ref. Pinning the action SHA pins the CLI. mdcode-command overrides it, and this repo's dogfood step sets it to the branch build.
  • Pinning: SHA only. No moving v1 tag. The docs show how to find the commit behind a mdcode-ts@x.y.z release tag, which bumpy's publish step creates.

Bugs found by dogfooding, all fixed here, because a passing check has to mean extract would change nothing:

  • Indented regions were indented twice. extract on tests/examples/fibonacci rewrote fibonacci.js with every region body pushed right by the marker's indent. update copies a region verbatim, indentation included, and the splice then added the indent again. Per your call, the splice now leaves a body as it stands when its first non-empty line already starts with the marker's indent. A dedented body is still indented to the marker.
  • extract --force dropped the final newline of an overwritten file. It now keeps the file's LF or CRLF; new files are written as before.
  • extract --force on a symlinked target replaced the link with a regular file (writeAtomic renames over it), and on a target that isn't valid UTF-8 it re-encoded the bytes. It now refuses both, as splices already did, so a passing extract --check --force always means extract --force would change nothing.

The action:

  • Paths: documents takes one path or glob per line, so paths may contain spaces.
  • Bases: by default, extract resolves each document's files against that document's directory, the same as update. base sets the root for both directions. With project or config, the configuration's roots apply.
  • Reporting: drift that both directions see is reported once, marked both. Annotations name the direction, document, line, block, file and region.
  • Exit codes: 1 for drift, 2 for bad inputs.
  • Safety: needs only contents: read and runs no code from the Markdown. The docs say to use pull_request, never pull_request_target.

Evidence

  • Before: mdcode extract on a copy of tests/examples/fibonacci changed fibonacci.js (diff: if (n < 1) { → if (n < 1) {).
    After: byte-identical, and the dogfood run passes: ✓ 6 document(s) in sync: files → Markdown (update) and Markdown → files (extract).
  • extract.test.ts "extract: check":
    • in sync (whole, CRLF, regions): unchanged, nothing written;
    • per-region drift, with an unchanged region not reported;
    • a missing region would be appended, a missing file would be created;
    • a trailing-newline-only difference is named;
    • without --force, an existing file is skipped;
    • an LF/CRLF overwrite keeps its newline and the check passes after extract;
    • symlinked and non-UTF-8 targets are refused by both the check and the real write, and their bytes are left as they were.
  • region.test.ts: read-then-splice round trip for indented markers, including a body whose last line closes a scope left of the marker.
  • check-sync-action.test.ts (8 tests), run the way action.yml runs the script:
    • a synced checkout of two documents, one under my docs/ with file="hello world.ts", passes and every file is unchanged;
    • a changed source is reported as both, with document, line, block and file;
    • update-only drift (a stale outline) and extract-only drift (extra trailing newlines);
    • a lost region reads as missing_region for update and "would append" for extract;
    • directions selection and base;
    • bad inputs exit 2;
    • with no mdcode-command, it runs npx --yes mdcode-ts@<package.json version> (checked with a stub npx).
  • pnpm check passes (pre-push). intent maintainer check: 0 pending.

Merge Danger

Door: two-way

Blast Radius: extract output

  • extract --force now keeps final newlines and refuses symlinked targets.
  • Splicing into indented regions no longer double-indents. Any repo that relied on that, by writing dedented bodies whose first line happens to start with the marker's indent, would see a difference.
  • The action is new, so no consumers yet.
  • Until the next release (🐸 Versioned release #27), the action's default CLI is 0.0.4, which has no extract --check. The script reports that clearly, and the docs say to pin a release commit.

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

bumpy-frog

The changes in this PR will be included in the next version bump.

minor Minor releases

  • mdcode-ts 0.0.4 → 0.1.0

Bump files in this PR

Click here if you want to add another bump file to this PR


This comment is maintained by bumpy.

@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown

⚠️ ESLint Check Warnings

Click to see details

Style


&gt; mdcode@0.0.1 lint:s /home/runner/work/mdcode-ts/mdcode-ts
&gt; pnpm -r lint:s

Scope: 2 of 3 workspace projects
packages/mdcode lint:s$ eslint --config .eslintrc.style.json "src/**/*.{j,t}s{,x}" --cache --max-warnings=0
packages/mdcode lint:s: [baseline-browser-mapping] The data in this module is over two months old.  To ensure accurate Baseline data, please update: 'npm i baseline-browser-mapping@latest -D'
packages/mdcode lint:s: Done
packages/usage lint:s$ eslint --config .eslintrc.style.json "{tests,fixtures,examples}/**/*.{j,t}s{,x}" --cache --max-warnings=0
packages/usage lint:s: [baseline-browser-mapping] The data in this module is over two months old.  To ensure accurate Baseline data, please update: 'npm i baseline-browser-mapping@latest -D'
packages/usage lint:s: Done

Correctness


&gt; mdcode@0.0.1 lint:esl /home/runner/work/mdcode-ts/mdcode-ts
&gt; pnpm -r lint:esl

Scope: 2 of 3 workspace projects
packages/mdcode lint:esl$ eslint "src/**/*.{j,t}s{,x}" --cache --max-warnings=0
packages/mdcode lint:esl: [baseline-browser-mapping] The data in this module is over two months old.  To ensure accurate Baseline data, please update: 'npm i baseline-browser-mapping@latest -D'
packages/mdcode lint:esl: Done
packages/usage lint:esl$ eslint "{tests,fixtures,examples}/**/*.{j,t}s{,x}" --cache --max-warnings=0
packages/usage lint:esl: [baseline-browser-mapping] The data in this module is over two months old.  To ensure accurate Baseline data, please update: 'npm i baseline-browser-mapping@latest -D'
packages/usage lint:esl: Done

View workflow run

@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown

⚠️ ESLint Check Warnings

Click to see details

Style


&gt; mdcode@0.0.1 lint:s /home/runner/work/mdcode-ts/mdcode-ts
&gt; pnpm -r lint:s

Scope: 2 of 3 workspace projects
packages/mdcode lint:s$ eslint --config .eslintrc.style.json "src/**/*.{j,t}s{,x}" --cache --max-warnings=0
packages/mdcode lint:s: [baseline-browser-mapping] The data in this module is over two months old.  To ensure accurate Baseline data, please update: 'npm i baseline-browser-mapping@latest -D'
packages/mdcode lint:s: Done
packages/usage lint:s$ eslint --config .eslintrc.style.json "{tests,fixtures,examples}/**/*.{j,t}s{,x}" --cache --max-warnings=0
packages/usage lint:s: [baseline-browser-mapping] The data in this module is over two months old.  To ensure accurate Baseline data, please update: 'npm i baseline-browser-mapping@latest -D'
packages/usage lint:s: Done

Correctness


&gt; mdcode@0.0.1 lint:esl /home/runner/work/mdcode-ts/mdcode-ts
&gt; pnpm -r lint:esl

Scope: 2 of 3 workspace projects
packages/mdcode lint:esl$ eslint "src/**/*.{j,t}s{,x}" --cache --max-warnings=0
packages/mdcode lint:esl: [baseline-browser-mapping] The data in this module is over two months old.  To ensure accurate Baseline data, please update: 'npm i baseline-browser-mapping@latest -D'
packages/mdcode lint:esl: Done
packages/usage lint:esl$ eslint "{tests,fixtures,examples}/**/*.{j,t}s{,x}" --cache --max-warnings=0
packages/usage lint:esl: [baseline-browser-mapping] The data in this module is over two months old.  To ensure accurate Baseline data, please update: 'npm i baseline-browser-mapping@latest -D'
packages/usage lint:esl: Done

View workflow run

@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown

⚠️ ESLint Check Warnings

Click to see details

Style


&gt; mdcode@0.0.1 lint:s /home/runner/work/mdcode-ts/mdcode-ts
&gt; pnpm -r lint:s

Scope: 2 of 3 workspace projects
packages/mdcode lint:s$ eslint --config .eslintrc.style.json "src/**/*.{j,t}s{,x}" --cache --max-warnings=0
packages/mdcode lint:s: [baseline-browser-mapping] The data in this module is over two months old.  To ensure accurate Baseline data, please update: 'npm i baseline-browser-mapping@latest -D'
packages/mdcode lint:s: Done
packages/usage lint:s$ eslint --config .eslintrc.style.json "{tests,fixtures,examples}/**/*.{j,t}s{,x}" --cache --max-warnings=0
packages/usage lint:s: [baseline-browser-mapping] The data in this module is over two months old.  To ensure accurate Baseline data, please update: 'npm i baseline-browser-mapping@latest -D'
packages/usage lint:s: Done

Correctness


&gt; mdcode@0.0.1 lint:esl /home/runner/work/mdcode-ts/mdcode-ts
&gt; pnpm -r lint:esl

Scope: 2 of 3 workspace projects
packages/mdcode lint:esl$ eslint "src/**/*.{j,t}s{,x}" --cache --max-warnings=0
packages/mdcode lint:esl: [baseline-browser-mapping] The data in this module is over two months old.  To ensure accurate Baseline data, please update: 'npm i baseline-browser-mapping@latest -D'
packages/mdcode lint:esl: Done
packages/usage lint:esl$ eslint "{tests,fixtures,examples}/**/*.{j,t}s{,x}" --cache --max-warnings=0
packages/usage lint:esl: [baseline-browser-mapping] The data in this module is over two months old.  To ensure accurate Baseline data, please update: 'npm i baseline-browser-mapping@latest -D'
packages/usage lint:esl: Done

View workflow run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add reusable GitHub Actions for bidirectional sync checks and README updates

1 participant