Skip to content

chore: bump js-yaml to ^5.3.0 - #271

Open
wrn14897 wants to merge 2 commits into
mainfrom
warren/bump-js-yaml
Open

chore: bump js-yaml to ^5.3.0#271
wrn14897 wants to merge 2 commits into
mainfrom
warren/bump-js-yaml

Conversation

@wrn14897

Copy link
Copy Markdown
Collaborator

Bumps js-yaml from ^4.2.0 to ^5.3.0 (latest). v5 keeps the CJS load/dump API used by scripts/update-chart-versions.js; verified the script still produces byte-identical Chart.yaml output after the upgrade.


Compound Engineering
OpenCode

@wrn14897
wrn14897 requested a review from a team as a code owner August 24, 2026 17:33
@changeset-bot

changeset-bot Bot commented Aug 24, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 0b6e1b9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

<!-- deep-review -->

Deep Review

🔴 P0/P1 — must fix

  • scripts/update-chart-versions.js:2 — The release script loads the bumped dependency with CommonJS require("js-yaml") from a package with no "type": "module", while the lockfile entry in this diff renames the package bin from bin/js-yaml.js to bin/js-yaml.mjs and the v5.0.0 changelog embedded in base commit d370fb5 records a TypeScript rewrite that "reorganized the public API around flat named exports" with a dedicated migrate_v4_to_v5.md guide, so require() may throw ERR_REQUIRE_ESM or yield a namespace object whose .load is undefined. Because .github/workflows/release.yml:42 (version: yarn run version) is the only place this script ever runs and no PR-time workflow installs root dependencies, the first real execution against v5 happens post-merge inside changesets/action on main, where the failure blocks all chart releases rather than failing this PR.
    • Fix: Run yarn install && node scripts/update-chart-versions.js on Node 20 and confirm a zero exit before merging, and if require() fails, move to ^4.3.0 instead — it carries the maxTotalMergeKeys security backport that this repo's current 4.2.0 lacks, without the v5 API rewrite.
    • correctness, testing, maintainability, project-standards, reliability, security

🟡 P2 — recommended

  • scripts/update-chart-versions.js:12yaml.dump(chart) is called with no options, so the entire published charts/clickstack/Chart.yaml is re-serialized from whatever emitter defaults the installed major ships, and v5.1.0's changelog marks quoteStyle as [breaking] while v5.0.0 reworked scalar resolution and added seven new dump options. Release commit b42bbac confirms the v4 round-trip currently rewrites the file with only the version: line changing, meaning the folded description: >- at charts/clickstack/Chart.yaml:3-5 and the literal artifacthub.io/links: | block at lines 12-16 are v4-emitter-normalized and would silently reformat in the release commit under any v5 emitter delta.
    • Fix: Pin the emitter by passing explicit options such as yaml.dump(chart, { lineWidth: 80, noRefs: true }), or follow the precedent already set in .github/workflows/update-app-version.yml:26 and replace the version: line with a targeted edit instead of a full parse-and-re-serialize.
    • correctness, maintainability, reliability
  • .github/workflows/release.yml:42 — Neither chart-test.yml nor helm-test.yaml installs root Node dependencies or invokes update-chart-versions, so this dependency bump merges with zero automated evidence that its single consumer still runs, which is precisely why both findings above can only surface during a live release.
    • Fix: Add a PR-time job that runs the script against a scratch copy of Chart.yaml and asserts both a zero exit and that git diff reports no change beyond the version: field.
    • testing, correctness, maintainability, project-standards, reliability, security
🔵 P3 nitpicks (1)
  • package.json:11"version": "changeset version && npm run update-chart-versions" sequences two mutations non-atomically, so a throw in the second step leaves package.json bumped and charts/clickstack/Chart.yaml:18 stale — the exact skew the script exists to prevent; CI fails safe here because changesets/action aborts without opening a PR, but a maintainer running yarn version locally can commit the half-applied state.
    • Fix: Add a post-version assertion that package.json version equals the chart's version.

Reviewers (7): correctness, testing, maintainability, project-standards, reliability, security, learnings-researcher

Testing gaps:

  • No CI job executes scripts/update-chart-versions.js before merge; the only invocation path is changesets/action on main after merge.
  • No golden-file or idempotency assertion that a yaml.load + yaml.dump round-trip leaves charts/clickstack/Chart.yaml unchanged apart from the version: field.
  • No smoke check that require("js-yaml").load and .dump are callable functions under the release runtime.
  • docs/solutions/ does not exist, and scripts/update-chart-versions.js has never been modified since creation, so there is no prior incident record for this upgrade path.

Cleared during review: No secrets in the diff; the lockfile entry is self-consistent with a plain npm: resolution, an unchanged transitive set (argparse ^2.0.1), and a well-formed checksum. yaml.load uses DEFAULT_SCHEMA on repo-owned input only, so there is no parsing-safety regression. The caret range is inert because Yarn 4 enforces immutable installs in CI and the lockfile pins 5.3.0, and omitting a changeset matches this repo's precedent for dependency bumps.

@wrn14897

Copy link
Copy Markdown
Collaborator Author

Re: P0 — require("js-yaml") under v5

Verified the concern doesn't materialize, and closed the coverage gap:

  • js-yaml v5 is a dual CJS/ESM build: exports.requiredist/js-yaml.cjs.js. Only the bin entrypoint moved to .mjs, which this repo never invokes. CJS require() returns an object with load/dump functions.
  • Ran on Node 20.19.3 (matching release.yml): yarn install && node scripts/update-chart-versions.js → exit 0, and the Chart.yaml round-trip output is byte-identical to the committed file.
  • The real gap was that this script only ever executed post-merge in release.yml. Added a version-script-smoke job to the PR-time helm-test.yaml workflow (373f7ce) that installs root deps on Node 20, runs the script, and asserts the round-tripped Chart.yaml parses with the version from package.json — so future dependency bumps fail on the PR instead of blocking releases on main.

No downgrade to ^4.3.0 needed; v5.3.0 includes the same maxTotalMergeKeys hardening.

@wrn14897
wrn14897 force-pushed the warren/bump-js-yaml branch from 373f7ce to 0b6e1b9 Compare August 24, 2026 19:00
@github-actions

Copy link
Copy Markdown
Contributor

Deep Review

🔴 P0/P1 -- must fix

  • package.json:16 -- The bump crosses a major boundary where js-yaml was rewritten around flat named exports and now ships an ESM bin/js-yaml.mjs, while scripts/update-chart-versions.js:2 and scripts/extract-release-notes.js:7 both consume it through CommonJS require() and call yaml.load / yaml.dump.
    • Fix: Confirm js-yaml@5.3.0 still resolves under a require condition and exposes load/dump as named exports, otherwise convert both scripts to ESM or hold on the 4.x line.
    • correctness, security, adversarial, project-standards

🟡 P2 -- recommended

  • .github/workflows/helm-test.yaml:42 -- The assertion compares chart.version against the same package.json value the script just wrote, re-parsed by the same library that produced the file, so it can only fail if the script throws.
    • Fix: Assert git diff --exit-code -- charts/clickstack/Chart.yaml (a genuine no-op today, since both sides are 3.3.0), run the script against an injected differing version, and check typeof chart.appVersion === 'string'.
    • adversarial, correctness, testing, reliability, security
  • .github/workflows/helm-test.yaml:34 -- scripts/extract-release-notes.js is the other js-yaml consumer on the release path (release.yml:53) and calls version.replace() on the loaded value, but the new job never executes it.
    • Fix: Add node scripts/extract-release-notes.js to the same step and include the file it writes in the cleanup.
    • correctness, security
  • .github/workflows/helm-test.yaml:6 -- The push trigger is filtered to charts/**, so a merge touching only package.json, yarn.lock, or scripts/** never runs this job on main, leaving release.yml:35 as the first execution of the new library against the merged tree.
    • Fix: Add package.json, yarn.lock, scripts/**, and .github/workflows/helm-test.yaml to the push paths list, and mark version-script-smoke a required status check.
    • adversarial, correctness, reliability, testing
  • .github/workflows/helm-test.yaml:12 -- This is the first job in Helm Chart Tests to depend on the npm registry, and that workflow's aggregate conclusion is one of the two workflow_run triggers for release.yml:3, so a transient install failure now flips that trigger to failure.
    • Fix: Move the job into its own workflow outside release.yml's workflows: list, or accept the coupling deliberately and harden the install step.
  • .github/workflows/helm-test.yaml:1 -- The workflow declares no permissions: block while its new job runs yarn over PR-controlled package.json and yarn.lock, which executes dependency build scripts under nodeLinker: node-modules.
    • Fix: Add permissions: contents: read at the workflow level and install with yarn install --immutable --mode=skip-build, matching the explicit blocks already in release.yml and update-app-version.yml.
  • yarn.lock:541 -- The helm-charts@workspace:. block has been missing its js-yaml descriptor since d370fb5 deleted the ^4.2.0 entry without touching package.json, so yarn (immutable under CI=true) has been failing at release.yml:35; this PR incidentally repairs that drift.
    • Fix: Audit release runs since d370fb5 for silent install failures, and keep an immutable-install check in PR CI so manifest/lock divergence cannot merge again.
    • reliability, security, correctness, adversarial
🔵 P3 nitpicks (8)
  • .github/workflows/helm-test.yaml:37 -- The verification logic lives as an inline node -e string in YAML, so it cannot be run locally or linted, unlike update-chart-versions which is a first-class npm script.
    • Fix: Move it to scripts/verify-chart-versions.js, expose it as a package.json script, and have the workflow call that.
    • maintainability, agent-native, testing
  • .github/workflows/helm-test.yaml:19 -- The new job pins actions/checkout@v3 and actions/setup-node@v3 while chart-test.yml uses @v4 and deep-review.yml uses @v6.
    • Fix: Bump both to @v4 to match the newer workflows in this repo.
    • reliability, security, project-standards
  • .github/workflows/helm-test.yaml:33 -- The run: block relies on the implicit bash -e default and omits pipefail, which AGENTS.md:144 requires for shell in this repo.
    • Fix: Start the block with set -eo pipefail.
  • .github/workflows/helm-test.yaml:48 -- git checkout -- charts/*/Chart.yaml discards the regenerated file, throwing away the one artifact that would show what the dump actually changed.
    • Fix: Print git diff -- charts/*/Chart.yaml before reverting.
    • security, adversarial
  • .github/workflows/helm-test.yaml:12 -- The job sets no timeout-minutes, so a stalled Corepack or registry fetch holds a runner until the default job limit.
    • Fix: Add timeout-minutes: 10.
  • scripts/update-chart-versions.js:6 -- The script writes only ./charts/clickstack while the cleanup glob restores charts/*/Chart.yaml, making clickstack-operators look covered when it is never version-synced.
    • Fix: Narrow the restore to charts/clickstack/Chart.yaml, or add the second chart and assert both.
    • adversarial, maintainability, testing
  • .github/workflows/update-app-version.yml:26 -- The sed writes appVersion: unquoted, so a two-component tag such as 2.0 would load as a number and dump back as one, which Helm rejects.
    • Fix: Quote the substituted value in the replacement pattern.
  • AGENTS.md:153 -- The CI Workflows table still describes helm-test.yaml as unit tests plus example validation only.
    • Fix: Mention the version-script smoke job in that row.

Reviewers (9): correctness, security, adversarial, testing, reliability, maintainability, project-standards, agent-native, learnings

Testing gaps:

  • The version-change path is never exercised: package.json and charts/clickstack/Chart.yaml are both 3.3.0, so the assignment at scripts/update-chart-versions.js:11 is a no-op under CI.
  • No Helm-side validation (helm lint or helm show chart) runs against the regenerated Chart.yaml before it is reverted, so corruption that js-yaml accepts but Helm rejects stays invisible.
  • charts/clickstack-operators/Chart.yaml is never loaded, dumped, or asserted anywhere in the new job.
  • This review had no network access, so js-yaml@5.3.0's published module format and the recorded lockfile checksum could not be confirmed against the registry — the P1 above needs a real install to settle.

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.

1 participant