Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

These are **local mirrors** (vendored copies) of composite actions from the
private [`pncit/shared-actions`](https://github.com/pncit/shared-actions) repo,
currently at `v2.4.0` (`dfb52a3`).
currently at `v3.0.0` (`8bc187e`).

## Why they're copied here

Expand All @@ -29,5 +29,4 @@ point.
| local action | upstream |
|---|---|
| `validate-codebase/action.yml` | `pncit/shared-actions/.github/actions/validate-codebase` |
| `verify-node-toolchain/action.yml` | `pncit/shared-actions/.github/actions/verify-node-toolchain` |
| `verify-version-bump/action.yml` | `pncit/shared-actions/.github/actions/verify-version-bump` |
97 changes: 50 additions & 47 deletions .github/actions/validate-codebase/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ description: >-
# matches what their workflow needs to check.
#
# Does its own checkout + setup-node so it's self-contained — invoke
# directly from a job's `steps:` with just `uses:` and the npm-token.
# directly from a job's `steps:` with the npm-token and the two toolchain
# versions (`vars.NODE_VERSION`, `vars.NPM_VERSION`).

# Vendored from pncit/shared-actions@v2.4.0 (dfb52a3) because this repo is PUBLIC
# Vendored from pncit/shared-actions@v3.0.0 (8bc187e) because this repo is PUBLIC
# and shared-actions is PRIVATE — a public repo can't `uses:` a private
# action. Byte-for-byte identical to upstream apart from this comment;
# re-copy when upstream changes (see .github/actions/README.md).
Expand All @@ -36,42 +37,50 @@ inputs:
required: false
default: 'https://registry.npmjs.org'

npm-version:
node-version:
description: >-
Exact npm version to pin after setup-node, e.g. "12.0.2". `.nvmrc`
pins a Node *major*, so setup-node resolves to whatever 24.x is
newest on the day — which is how npm crossed the 11 -> 12 boundary
(and started blocking unapproved install scripts) with nothing
committed on either side. Pinning here makes that upgrade a
deliberate, reviewed edit to one default instead of a surprise.
Set to the empty string to opt out and take the bundled npm.
required: false
default: '12.0.2'
node-major-version:
Exact Node version to install with setup-node, e.g. "24.20.0".
Callers pass `vars.NODE_VERSION`. There is deliberately no default
and no `.nvmrc` fallback: the same value is handed to `deploy` /
`validate-build` as the `NODE_VERSION` build arg, so the image is
built on the Node that tested it, and a bump is one org variable
instead of a per-repo sweep. Empty fails the job.
required: true
npm-version:
description: >-
Optional. Required Node major, e.g. "24" — typically
vars.NODE_MAJOR_VERSION. When this and npm-major-version are both
set, verify-node-toolchain runs *after* setup-node, so it measures
the toolchain that actually runs `npm ci`. Callers that invoke
verify-node-toolchain as a top-level step are measuring the
runner's system Node/npm, which is not what this action uses.
required: false
default: ''
npm-major-version:
description: 'Optional. Required npm major, e.g. "12". See node-major-version.'
required: false
default: ''
Exact npm version to install after setup-node, e.g. "12.0.2".
Callers pass `vars.NPM_VERSION`; deploy / validate-build receive the
same value as the `NPM_VERSION` build arg. `.nvmrc`-style Node
majors let the bundled npm cross 11 -> 12 (and start blocking
unapproved install scripts) with nothing committed — pinning here
and in the Dockerfile from one variable is what stops that. Empty
fails the job.
required: true

runs:
using: composite
steps:
# `required: true` doesn't catch an unset org variable — it arrives as
# "". Fail here with a message that names the variable rather than
# letting setup-node resolve "" to a surprise.
- name: Require toolchain versions
shell: bash
env:
NODE_VERSION: ${{ inputs.node-version }}
NPM_VERSION: ${{ inputs.npm-version }}
run: |
ok=true
[[ -n "$NODE_VERSION" ]] || { echo "::error::node-version is empty — set the org variable NODE_VERSION (or a repo override) and pass vars.NODE_VERSION."; ok=false; }
[[ -n "$NPM_VERSION" ]] || { echo "::error::npm-version is empty — set the org variable NPM_VERSION (or a repo override) and pass vars.NPM_VERSION."; ok=false; }
$ok

- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .nvmrc
node-version: ${{ inputs.node-version }}
# The GitHub cache service only pays off on a fresh VM. On the
# self-hosted fleet ~/.npm persists between jobs, so `npm ci` is
# already warm — while `cache: npm` cost every job with a changed
Expand All @@ -89,44 +98,38 @@ runs:
# v4-era flag and is no longer needed. Specifying it produced an
# "Unexpected input" warning during the first real deploy run.

# Pin npm before anything reads it. setup-node gives us whatever npm
# its Node bundles; this makes the version an explicit, reviewable
# input instead of a moving target.
# setup-node gives us whatever npm its Node bundles; replace it before
# anything reads it.
- name: Pin npm
if: inputs.npm-version != ''
shell: bash
run: |
npm i -g "npm@${NPM_VERSION}"
echo "npm pinned to $(npm --version) ($(command -v npm))"
env:
NPM_VERSION: ${{ inputs.npm-version }}

# Runs here, after Setup Node and the pin, so it asserts against the
# toolchain `npm ci` will actually use.
# Inlined copy of verify-node-toolchain (keep the two in step). A nested
# `uses: pncit/shared-actions/...` can't be SHA-pinned to a release that
# doesn't exist yet, and it breaks the byte-for-byte vendored copies in
# the public repos (a nested private ref is resolved at prepare time even
# when the step's `if:` is false).
# Assert the toolchain `npm ci` is about to use is the one that was
# asked for — a tool-cache miss on a self-hosted runner can leave
# setup-node falling back to the system Node. Prefix match so a
# less-specific variable value ("24") still works if anyone sets one.
- name: Verify Node toolchain
if: inputs.node-major-version != '' && inputs.npm-major-version != ''
shell: bash
env:
NODE_MAJOR_VERSION: ${{ inputs.node-major-version }}
NPM_MAJOR_VERSION: ${{ inputs.npm-major-version }}
WANT_NODE: ${{ inputs.node-version }}
WANT_NPM: ${{ inputs.npm-version }}
run: |
NODE_VERSION=$(node --version)
NPM_VERSION=$(npm --version)
echo "node: $NODE_VERSION ($(which node))"
echo "npm: $NPM_VERSION ($(which npm))"
if [[ ! "$NODE_VERSION" =~ ^v${NODE_MAJOR_VERSION}\. ]]; then
echo "::error::Expected Node ${NODE_MAJOR_VERSION}.x, got $NODE_VERSION."
echo "::error::The runner is falling back to system Node — install Node ${NODE_MAJOR_VERSION} on the runner or fix actions/setup-node."
if [[ "$NODE_VERSION" != "v${WANT_NODE}" && "$NODE_VERSION" != "v${WANT_NODE}".* ]]; then
echo "::error::Expected Node ${WANT_NODE}, got $NODE_VERSION."
echo "::error::The runner is falling back to system Node — check actions/setup-node's download/tool-cache on this runner."
exit 1
fi
if [[ ! "$NPM_VERSION" =~ ^${NPM_MAJOR_VERSION}\. ]]; then
echo "::error::Expected npm ${NPM_MAJOR_VERSION}.x, got $NPM_VERSION."
echo "::error::npm version mismatch resolves nested optional deps differently and breaks npm ci against the committed lockfile."
if [[ "$NPM_VERSION" != "${WANT_NPM}" && "$NPM_VERSION" != "${WANT_NPM}".* ]]; then
echo "::error::Expected npm ${WANT_NPM}, got $NPM_VERSION."
echo "::error::The npm pin did not take; npm version mismatch resolves nested optional deps differently and breaks npm ci against the committed lockfile."
exit 1
fi

Expand Down Expand Up @@ -155,7 +158,7 @@ runs:
run: |
if grep -q 'allowScripts' "${RUNNER_TEMP}/npm-ci.log"; then
grep 'allowScripts' "${RUNNER_TEMP}/npm-ci.log" >&2
echo "::warning::npm flagged or skipped one or more install scripts. If any is a native module, it did not build and the install still reported success. Approve with: npx npm@${NPM_VERSION:-12} install-scripts approve <pkg>, then commit the package.json allowScripts change."
echo "::warning::npm flagged or skipped one or more install scripts. If any is a native module, it did not build and the install still reported success. Approve with: npx npm@${NPM_VERSION} install-scripts approve <pkg>, then commit the package.json allowScripts change."
fi
env:
NPM_VERSION: ${{ inputs.npm-version }}
Expand Down
71 changes: 0 additions & 71 deletions .github/actions/verify-node-toolchain/action.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/actions/verify-version-bump/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ description: >-
# Does its own checkout (fetch-depth 2 plus a fetch of the reference), so it
# can run first in a job; a later validate-codebase will check out again.

# Vendored from pncit/shared-actions@v2.4.0 (dfb52a3) because this repo is PUBLIC
# Vendored from pncit/shared-actions@v3.0.0 (8bc187e) because this repo is PUBLIC
# and shared-actions is PRIVATE — a public repo can't `uses:` a private
# action. Byte-for-byte identical to upstream apart from this comment;
# re-copy when upstream changes (see .github/actions/README.md).
Expand Down
25 changes: 9 additions & 16 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,6 @@ jobs:
with:
fetch-depth: 2

# Install the repo's Node (.nvmrc) before the toolchain check: the hosted
# image's system Node is whatever Ubuntu ships, not necessarily ours.
# validate-codebase below runs setup-node again; that's a cache hit.
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .nvmrc

# Env check: fail fast if the Node/npm majors don't match what the repo
# expects (NODE_MAJOR_VERSION / NPM_MAJOR_VERSION are pncit org-level
# Actions variables). Also catches .nvmrc drifting from the org standard.
- uses: ./.github/actions/verify-node-toolchain
with:
node-major-version: ${{ vars.NODE_MAJOR_VERSION }}
npm-major-version: ${{ vars.NPM_MAJOR_VERSION }}

# Version-bump gate: @pncit/node-quickbooks is a published library, so
# every PR into master must bump package.json's version, or
# publish-on-version-bump has nothing to publish after the squash.
Expand All @@ -73,11 +58,19 @@ jobs:
# HEAD^ and fail every unversioned merge; npm-publish.yml already skips
# when there is nothing new to publish.
- uses: ./.github/actions/verify-version-bump
with:
# .nvmrc went with shared-actions v3.0.0 (Node is vars.NODE_VERSION now);
# deleting it ships nothing, so it must not force a release either.
exempt-paths: |
.github/**
.nvmrc
if: github.event_name == 'pull_request'

# Codebase checks: npm ci + lint + typecheck + test. This action does its
# own checkout + setup-node (node-version-file: .nvmrc) and matches the
# own checkout + setup-node (vars.NODE_VERSION) and matches the
# @pncit scope / npmjs registry by default.
- uses: ./.github/actions/validate-codebase
with:
npm-token: ${{ secrets.NPM_TOKEN }}
node-version: ${{ vars.NODE_VERSION }}
npm-version: ${{ vars.NPM_VERSION }}
1 change: 0 additions & 1 deletion .nvmrc

This file was deleted.

Loading