Skip to content

ci(api-docs/ts): bring npm's cache-poisoning fix upstream, reconcile the rest - #134

Merged
WomB0ComB0 merged 3 commits into
mainfrom
ci/api-docs-ts-reconcile-npm
Sep 22, 2026
Merged

WomB0ComB0 merged 3 commits into
mainfrom
ci/api-docs-ts-reconcile-npm

Conversation

@WomB0ComB0

@WomB0ComB0 WomB0ComB0 commented Sep 22, 2026

Copy link
Copy Markdown
Member

What

Reconciles resq-software/npm's copy of .github/workflows/api-docs.yml
against automation/source-repo-templates/api-docs.typescript.yml, the
follow-up #132 deferred.

The two files differed by 92 changed lines across 12 hunks. Each hunk was
traced to the commit that created it — git log --follow -p on the npm copy,
git log -S on this template — and classified. Three hunks carry changes
that belong upstream. Seven are the template already being ahead, or values
that should differ. Two are noise.

This is not a wholesale re-sync. Nothing npm-specific is hoisted, and nothing
merged today is reverted.

Per-hunk classification

# Where What differs Bucket Action
1 L1 copyright holder needs an org decision none, flagged below
2 L15–24 tags: matches one scope vs both template-ahead none
3 L79 DOCS_REF_SLUG example uses a dead scope downstream fix brought upstream
4 L101 actions/checkout pin upstream rot bumped
5 L107 setup-bun pin + missing no-cache downstream fix + rot brought upstream
6 L117 doc-generation comment template-ahead none
7 L165–200 warn-and-continue vs abort template-ahead none
8 L429 one blank line noise none
9 L452–470 read_version vs read_manifest template-ahead (#132) none — see below
10 L487 index line rebuilds vs reads the name template-ahead (#132) none — see below
11 L506 actions/checkout pin upstream rot bumped
12 L620 create-pull-request pin upstream rot bumped

Brought upstream

Hunk 5 — no-cache: true on setup-bun. npm added this on 2026-05-31 to
close a zizmor cache-poisoning finding at error severity: the job runs on
release tags and opens a cross-repo PR with DOCS_REPO_PR_TOKEN, so a cache
populated by a less-trusted run must not be restorable into it. That commit
ended with a note saying the upstream template needed the same change or the
next sync would regress it. Four months later it still did not have it, and
because sync-templates.sh overwrites the consumer file wholesale, running
the sync today would have deleted the mitigation. This is the item #132
named as outstanding.

Generalised on the way up: npm's comment cites that repo's own code-scanning
alert number, which means nothing in a shared template. The rationale is
stated instead, and it holds for any TypeScript consumer. no-cache is an
input in setup-bun v2.0.2 as well as v2.2.0, so the fix does not depend on
the version bump in hunk 5's other half.

Hunk 3 — stale scope in a comment. The DOCS_REF_SLUG worked example
still demonstrated @resq-sw/ui@v0.35.6. That scope stopped publishing in
July 2026. npm corrected the comment in its copy at the time. Comment only,
no behaviour change; it is the last @resq-sw literal in this file that
refers to the npm scope rather than to the resq-sw machine account, which
is correct and is left alone.

Hunks 4, 11, 12 (and half of 5) — the pins. Not a downstream fix, a
different problem: Dependabot's github-actions ecosystem only scans
.github/workflows/, so automation/source-repo-templates/ is invisible to
it. This repo's own changelog-sync.yml runs checkout v7.0.0 and
create-pull-request v8.1.1 while every template still names v6.0.2 and
v7.0.8 — same repo, same config, opposite freshness.

The consumers diverged the other way because they do get Dependabot:

repo checkout create-pull-request
crates v7.0.1 v8.1.1
npm v7.0.1 v8.1.1
pypi v7.0.1 v8.1.1
vcpkg v7.0.1 v8.1.1
dotnet-sdk v6.0.2 v7.0.8

Four consumers converged on identical SHAs independently, so these are the
org's versions and the templates are the outlier — this is not npm's
preference being hoisted. Syncing the template as it stands would walk npm
back a major on both, plus setup-bun v2.2.0 → v2.0.2.

Deliberately not brought upstream

Hunks 9 and 10 — this is the one that conflicts with #132. npm's copy
hardcodes @resq-systems/ when building index entries. That is correct
today
and was a real fix when #167 made it in July. #132, merged this
morning, solves the same problem differently: read_manifest() reads .name
out of the manifest it already opens for .version. The upstream version
wins and is not touched.
npm's fix restates the scope in a second place, so
it needs another edit at the next rename — which is exactly how the @resq-sw
literal survived two months. #132 derives from the source of truth and needs
no edit. Taking npm's version here would silently revert this morning's fix
for a strictly worse one. The next sync replaces npm's hardcode with the
derived form.

Hunk 2 — the tags: list. npm matches only @resq-systems/*@v*; the
template matches that and @resq-sw/*@v*. This looks like npm cleaning up
after the rename, but the history runs the other way: npm replaced the
pattern on 2026-07-12 and #101 added dual matching on 2026-07-24, twelve days
later, with the rationale in the comment. The template's superset is the
deliberate, newer decision. No action, and the legacy pattern is left in
place.

Hunks 6 and 7 — the generation loop. npm warns and continues when a
package fails; the template aborts the run (#113). Template-ahead, and the
stricter behaviour is the right one given that "Sync generated MDX" clears
the target directory before copying. Left alone, and deliberately not
softened toward the consumer's older shape.

Hunk 1 — the copyright holder. npm's copy says ResQ Systems, Inc.;
this template says ResQ Software. npm#167 standardised the org on
ResQ Systems, Inc. as the copyright holder while explicitly keeping the
resq-software GitHub org and the resq.software domains. So the template
line is plausibly wrong — but it is wrong in the dotnet and python templates
too, the rust and cpp templates carry no copyright header at all, and which
legal entity holds copyright is not an engineering call. Changing one of
three templates would make the set less consistent, not more. Flagged, not
touched.

Hunk 8 is a single blank line.

Checked and found already in sync

Worth recording, because the drift was smaller than expected:

Verification

  • Every action SHA resolved against the upstream tag via the GitHub API
    before use, in both directions. All six pins on both sides already agreed
    with their version comments — no repeat of the mismatch class fixed in fix(dotnet-docs): scan all .csproj candidates for a real version #56.
    • actions/checkout v7.0.1 → 3d3c42e5aac5ba805825da76410c181273ba90b1
    • oven-sh/setup-bun v2.2.0 → 0c5077e51419868618aeaa5fe8019c62421857d6
    • peter-evans/create-pull-request v8.1.1 → 5f6978faf089d4d20b00c7766989d076bb2fc7f1
  • create-pull-request v8 is a major bump, so its input surface was diffed
    against this step: all 12 inputs used here (add-paths, author, base,
    body, branch, commit-message, committer, delete-branch, labels,
    path, title, token) are still accepted by v8.1.1.
  • no-cache confirmed present in setup-bun's action.yml at both the old
    and new pinned SHAs.
  • npm's copy has run this workflow green on setup-bun v2.2.0,
    create-pull-request v8.1.1 and no-cache: true — three times on
    2026-07-27, at checkout v7.0.0. The v7.0.1 patch bump landed the next day
    and has not had a release-tag run yet; it is the SHA four consumers carry
    today, and lychee.yml in this repo already runs it.
  • actionlint clean on all five templates.
  • Residual diff against npm's copy is down to 8 hunks, every one of them
    either template-ahead, the reworded comment from hunk 5, or the two items
    flagged above.

Follow-ups, deliberately not in this PR

  1. The template directory gets no automated dependency updates. Hand-
    bumping one template is a stopgap and it will rot again. The other four
    have the same problem — the python template pins setup-uv v6.0.0 while
    pypi runs v10.1.0, four majors back. Worth either bringing the directory
    under automated updates or dropping literal pins from the templates.
  2. pypi carries a setup-uv cache-poisoning mitigation that its
    template lacks, the same shape as hunk 5. Not audited here.
  3. The copyright header needs one decision applied to all five templates.
  4. Nothing carries drift back automatically. All three items in this PR
    were found by hand, months late, and one of them was flagged in its own
    commit message at the time and still missed. A periodic template-vs-
    consumer diff check would have surfaced all three the week they landed.

Test plan

  • Every hunk traced to the commit that created it, both directions
  • Action SHAs re-resolved against upstream tags
  • create-pull-request v8 input compatibility diffed against this step
  • no-cache confirmed as a valid input at both setup-bun pins
  • actionlint clean on all five templates
  • Sync to resq-software/npm and confirm the next release-tag run is green

The TypeScript api-docs job runs on release tags and opens a cross-repo
PR with DOCS_REPO_PR_TOKEN, so it is a privileged context. setup-bun
enables dependency caching by default, which zizmor flags at error
severity: a less-trusted run can populate the shared cache and have it
restored here.

resq-software/npm has carried this mitigation in its copy of the
workflow since 2026-05-31, and that commit said in as many words that
the upstream template needed the same change or the next sync would
regress it. It never got it. Because the sync is a wholesale file
copy, running automation/sync-templates.sh typescript today would
delete the mitigation from the consumer.

The npm copy cites that repo's own code-scanning alert number; the
rationale is generalised here since it holds for any TypeScript
consumer. The install step is already --frozen-lockfile, so a cold
install is functionally identical.

no-cache exists in setup-bun v2.0.2 (the pin in this file) as well as
in the newer v2.2.0, so this change stands on its own.
Last surviving @resq-sw literal in this template that refers to the npm
scope rather than to the machine account. The packages moved to
@ResQ-Systems in July 2026; npm corrected this comment in its own copy
at the time and the correction was never brought back.

Comment only, no behaviour change. The tags: list keeps matching both
scopes, which is deliberate (#101) and is left alone; this only stops
the worked example from demonstrating a scope nothing publishes under
any more.
@coderabbitai

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 23 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 3591e37e-88c2-443a-a5f9-19fc0111f3a9

📥 Commits

Reviewing files that changed from the base of the PR and between 66977df and df63a17.

📒 Files selected for processing (1)
  • automation/source-repo-templates/api-docs.typescript.yml

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the area:content MDX/MD documentation content label Sep 22, 2026
Dependabot's github-actions ecosystem only scans .github/workflows/, so
automation/source-repo-templates/ is invisible to it. This repo's own
dependabot.yml covers the workflows and nothing else, and the result
shows: changelog-sync.yml here runs checkout v7.0.0 and
create-pull-request v8.1.1 while every template still names v6.0.2 and
v7.0.8.

The consumers diverged the other way, because they do get Dependabot:

  repo         checkout   create-pull-request
  crates       v7.0.1     v8.1.1
  npm          v7.0.1     v8.1.1
  pypi         v7.0.1     v8.1.1
  vcpkg        v7.0.1     v8.1.1
  dotnet-sdk   v6.0.2     v7.0.8

Four consumers converged on the same SHAs independently, so these are
the org's versions and the templates are the outlier. Since
sync-templates.sh overwrites the consumer file wholesale, syncing this
template today would walk npm back a major on both, plus setup-bun
v2.2.0 -> v2.0.2.

Every SHA below was resolved against the upstream tag before use:

  actions/checkout            v7.0.1  3d3c42e5aac5ba805825da76410c181273ba90b1
  oven-sh/setup-bun           v2.2.0  0c5077e51419868618aeaa5fe8019c62421857d6
  peter-evans/create-pull-request
                              v8.1.1  5f6978faf089d4d20b00c7766989d076bb2fc7f1

create-pull-request v8 is a major bump, so its input surface was
diffed against this step: all 12 inputs used here (add-paths, author,
base, body, branch, commit-message, committer, delete-branch, labels,
path, title, token) are still accepted by v8.1.1.

npm's copy has run this workflow green on setup-bun v2.2.0 and
create-pull-request v8.1.1, three times on 2026-07-27, at checkout
v7.0.0. The v7.0.1 patch bump landed the day after and has not had a
release-tag run yet; it is the SHA the other consumers carry and the
one lychee.yml in this repo already runs.

Hand-bumping is a stopgap. The durable fix is to get the template
directory under automated updates, or to stop carrying literal pins in
the templates at all; that is bigger than this PR and the other four
templates have the same rot (the python template pins setup-uv v6.0.0
while pypi runs v10.1.0). This commit is separable if you would rather
fix it centrally.
@WomB0ComB0
WomB0ComB0 force-pushed the ci/api-docs-ts-reconcile-npm branch from 3bae3a0 to df63a17 Compare September 22, 2026 09:28
@WomB0ComB0
WomB0ComB0 merged commit 09b16f5 into main Sep 22, 2026
22 checks passed
@WomB0ComB0
WomB0ComB0 deleted the ci/api-docs-ts-reconcile-npm branch September 22, 2026 09:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:content MDX/MD documentation content

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant