chore: migrate to pnpm and harden GitHub Actions workflows (v5)#376
Merged
Conversation
|
|
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
commit: |
📊 Package size report 0.01%↑
Unchanged files
🤖 This report was automatically generated by pkg-size-action |
This was referenced May 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related changes bundled together: migrate the repo from npm to pnpm workspaces, and harden every GitHub Actions workflow against supply-chain attacks (motivated by the TanStack npm compromise).
Package manager migration: npm → pnpm
pnpm-workspace.yamldeclaringdemoandcodemodas workspace packages, withesbuildallow-listed for build scripts.packageManager: pnpm@11.1.1to the rootpackage.jsonso Corepack /pnpm/action-setupcan lock to a specific version.package-lock.jsonfiles (root,demo/,codemod/) and replaced them with a single rootpnpm-lock.yaml."chakra-react-select": "workspace:*"instead of"file:..".npm:dev:*→pnpm:dev:*,npm:lint:*→pnpm:lint:*inconcurrentlyinvocations.install:all/install:demo/install:codemodscripts — a singlepnpm installat the root now sets up the entire workspace.dev:demo,prepublishOnly, andcodemod/prepublishOnlyrewritten to usepnpm..gitignoreaddspnpm-debug.log*.CONTRIBUTING.mdupdated to referencepnpm install/pnpm dev/pnpm lintinstead of the npm equivalents.Supply-chain defenses gained just by being on pnpm 11
Beyond the workflow hardening below, the migration itself raises the security floor:
minimumReleaseAgedefaults to 1440 minutes (1 day) in pnpm 11. pnpm refuses to install any package version younger than 24 hours. In the TanStack incident the malicious tarballs were live for roughly 30 minutes before detection — pnpm 11 would have rejected them outright. npm has no equivalent built-in.allowBuilds. pnpm 10+ won't execute lifecycle scripts (preinstall,install,postinstall, etc.) from dependencies unless they're explicitly allow-listed. This branch'spnpm-workspace.yamlallows onlyesbuild. Compromised tarballs in the npm registry overwhelmingly rely on postinstall payloads for initial execution; this neuters that entire class of attack for unlisted packages.packageManagerfield pins pnpm itself. Corepack /pnpm/action-setuplock topnpm@11.1.1with an integrity hash, so a compromised pnpm release can't silently roll forward in CI or on contributors' machines.node_moduleslayout. Each package can onlyrequire/importwhat it explicitly declared as a dependency. A malicious transitive dep can't sneak into the resolution graph of a sibling package the way it can with npm's flat layout.pnpm-lock.yamlat the workspace root replaces three separatepackage-lock.jsonfiles. One source of truth to review for unexpected dependency changes, andpnpm install --frozen-lockfile(which pnpm auto-applies in CI) refuses to mutate it.Dependency bumps
In
package.json:react-select:5.10.x→^5.10.2(switched to semver caret)oxfmt:^0.x→^0.49.0oxlint:^1.57.0→^1.64.0oxlint-tsgolint:^0.17.4→^0.22.1typescript:^6.0.2→^6.0.3GitHub Actions hardening
Applied to
lint.yml,package-size-report.yml,pkg-pr.yml, plus a newzizmor.ymlworkflow. All changes pass azizmoraudit with zero findings.Adopted pnpm's recommended CI setup (pnpm.io/continuous-integration):
corepack enablewithpnpm/action-setup(auto-reads pnpm version from thepackageManagerfield). More future-proof — Node.js has been moving away from bundling Corepack — and avoids the signature-hash check that occasionally caused intermittent CI failures.actions/checkoutv4 → v6.0.2 andactions/setup-nodev4 → v6.4.0.Supply-chain hardening (motivated by TanStack incident postmortem and follow-up):
# vX.Y.Zcomment. Defends against a tag being force-pushed to a malicious commit (cf. thetj-actions/changed-filescompromise from March 2025).persist-credentials: falseto everyactions/checkoutstep. By default checkout leavesGITHUB_TOKENin.git/config; if any subsequent step uploads the workspace as an artifact, the token leaks. None of these workflows need git auth after checkout.permissions: {}(deny-by-default) and minimal per-job permissions blocks:lint.yml:contents: readpackage-size-report.yml:contents: read,pull-requests: write(for pkg-size comment)pkg-pr.yml:contents: read,pull-requests: write,id-token: write(for pkg-pr-new OIDC + comment)zizmor.yml:contents: read,security-events: write(for SARIF upload)Trigger pattern standardized across push+PR workflows:
push: { branches: [main, v5] }+ unrestrictedpull_request:. This avoids the duplicate-run problem of PRs firing both events while still covering direct pushes to long-lived branches.New
.github/workflows/zizmor.ymlruns zizmor on every PR and push tomain/v5, uploading findings as SARIF to GitHub Code Scanning. Future regressions in workflow hygiene (unpinned actions, broad permissions, dangerous triggers, etc.) will surface as Security tab alerts and fail theCode scanning results / Zizmorcheck at the configured severity threshold.Test plan
pnpm installcleanly resolves at the workspace root with no peer-dep warningspnpm devstarts the demo at http://localhost:5152 and live-rebuilds the packagepnpm lint(lint:src + lint:types + lint:exports) passespnpm buildproduces a workingdist/