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
7 changes: 7 additions & 0 deletions .changeset/exact-node-security-pins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@kethalia/workflows": patch
---

Allow exact Node.js security versions through a string `node-version-spec` input
in the build/lint/test and quality workflows. Preserve the existing numeric
`node-version` input for callers selecting a major version.
11 changes: 11 additions & 0 deletions .github/fixtures/node-version-coverage.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Synthetic artifacts for the workflow's upload/download contract, not project coverage.
const assert = require('node:assert/strict');
const fs = require('node:fs');

assert.match(process.version, /^v22\./);
const metric = { total: 0, covered: 0, skipped: 0, pct: 100 };
fs.mkdirSync('coverage', { recursive: true });
fs.writeFileSync('coverage/coverage-summary.json', JSON.stringify({
total: { lines: metric, statements: metric, functions: metric, branches: metric },
}));
fs.writeFileSync('coverage/coverage-final.json', '{}');
24 changes: 16 additions & 8 deletions .github/workflows/ci-build-lint-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ on:
type: number
required: false
default: 22
node-version-spec:
description: Exact Node.js version or range; overrides the legacy numeric node-version
type: string
required: false
default: ""
build-command:
description: Build command (e.g., "pnpm build")
type: string
Expand Down Expand Up @@ -86,12 +91,12 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
node-version: ${{ inputs.node-version-spec || inputs.node-version }}
cache: pnpm
- id: key
name: Compute node_modules cache key
run: |
echo "modules=${{ runner.os }}-node${{ inputs.node-version }}-modules-${{ hashFiles('**/pnpm-lock.yaml', '**/schema.prisma') }}" >> "$GITHUB_OUTPUT"
echo "modules=${{ runner.os }}-node${{ inputs.node-version-spec || inputs.node-version }}-modules-${{ hashFiles('**/pnpm-lock.yaml', '**/schema.prisma') }}" >> "$GITHUB_OUTPUT"
- name: Cache node_modules
id: modules-cache
uses: actions/cache@v4
Expand All @@ -117,7 +122,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
node-version: ${{ inputs.node-version-spec || inputs.node-version }}
cache: pnpm
- name: Restore node_modules
uses: actions/cache@v4
Expand Down Expand Up @@ -150,7 +155,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
node-version: ${{ inputs.node-version-spec || inputs.node-version }}
cache: pnpm
- name: Restore node_modules
uses: actions/cache@v4
Expand Down Expand Up @@ -185,7 +190,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
node-version: ${{ inputs.node-version-spec || inputs.node-version }}
cache: pnpm
- name: Restore node_modules
uses: actions/cache@v4
Expand Down Expand Up @@ -227,7 +232,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
node-version: ${{ inputs.node-version-spec || inputs.node-version }}
cache: pnpm
- name: Restore node_modules
uses: actions/cache@v4
Expand Down Expand Up @@ -273,7 +278,7 @@ jobs:
node-version: ${{ matrix.node-version }}
cache: pnpm
- name: Restore node_modules
if: matrix.node-version == inputs.node-version
if: matrix.node-version == (inputs.node-version-spec || inputs.node-version)
uses: actions/cache@v4
with:
path: |
Expand All @@ -297,7 +302,10 @@ jobs:
- name: Run tests
run: ${{ inputs.test-command }}
- name: Upload coverage reports
if: matrix.node-version == inputs.node-version
if: >-
matrix.node-version == (inputs.node-version-spec || inputs.node-version) ||
(!contains(fromJson(inputs.test-node-versions), inputs.node-version-spec || inputs.node-version) &&
strategy.job-index == 0)
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.coverage-artifact-name }}
Expand Down
19 changes: 12 additions & 7 deletions .github/workflows/ci-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ on:
type: number
required: false
default: 22
node-version-spec:
description: Exact Node.js version or range; overrides the legacy numeric node-version
type: string
required: false
default: ""
verify-command:
description: Package verification command (e.g., "pnpm validate:publish")
type: string
Expand Down Expand Up @@ -72,7 +77,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
node-version: ${{ inputs.node-version-spec || inputs.node-version }}
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Download build artifacts
Expand All @@ -96,7 +101,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
node-version: ${{ inputs.node-version-spec || inputs.node-version }}
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm changeset status --since=origin/${{ inputs.base-branch }}
Expand All @@ -111,7 +116,7 @@ jobs:
steps:
- uses: kethalia/workflows/.github/actions/setup-pnpm@v4.0.0
with:
node-version: ${{ inputs.node-version }}
node-version: ${{ inputs.node-version-spec || inputs.node-version }}
- run: pnpm audit --audit-level=${{ inputs.audit-level }}

# -------------------------------------------------------------------------
Expand All @@ -124,7 +129,7 @@ jobs:
steps:
- uses: kethalia/workflows/.github/actions/setup-pnpm@v4.0.0
with:
node-version: ${{ inputs.node-version }}
node-version: ${{ inputs.node-version-spec || inputs.node-version }}
- run: ${{ inputs.sherif-command }}

# -------------------------------------------------------------------------
Expand All @@ -137,7 +142,7 @@ jobs:
steps:
- uses: kethalia/workflows/.github/actions/setup-pnpm@v4.0.0
with:
node-version: ${{ inputs.node-version }}
node-version: ${{ inputs.node-version-spec || inputs.node-version }}
- run: ${{ inputs.knip-command }}

# -------------------------------------------------------------------------
Expand All @@ -161,7 +166,7 @@ jobs:
steps:
- uses: kethalia/workflows/.github/actions/setup-pnpm@v4.0.0
with:
node-version: ${{ inputs.node-version }}
node-version: ${{ inputs.node-version-spec || inputs.node-version }}
- run: ${{ inputs.cspell-command }}

# -------------------------------------------------------------------------
Expand All @@ -174,5 +179,5 @@ jobs:
steps:
- uses: kethalia/workflows/.github/actions/setup-pnpm@v4.0.0
with:
node-version: ${{ inputs.node-version }}
node-version: ${{ inputs.node-version-spec || inputs.node-version }}
- run: ${{ inputs.madge-command }}
39 changes: 39 additions & 0 deletions .github/workflows/internal-node-version-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Internal — Node version compatibility

on:
pull_request:
paths:
- .github/fixtures/node-version-coverage.cjs
- .github/workflows/ci-build-lint-test.yml
- .github/workflows/ci-quality.yml
- .github/workflows/internal-node-version-smoke.yml
workflow_dispatch:

permissions:
contents: read
pull-requests: write

jobs:
exact:
uses: ./.github/workflows/ci-build-lint-test.yml
with:
node-version: 24
node-version-spec: '22.23.4'
build-command: node -e "require('node:assert/strict').equal(process.version, 'v22.23.4')"
test-command: node .github/fixtures/node-version-coverage.cjs
test-node-versions: '[22]'
artifact-paths: package.json

legacy:
uses: ./.github/workflows/ci-build-lint-test.yml
with:
node-version: 22
build-command: node -e "require('node:assert/strict').match(process.version, /^v22\./)"
artifact-paths: .github/no-build-artifact

quality:
uses: ./.github/workflows/ci-quality.yml
with:
node-version-spec: '22.23.4'
changeset-check: true
audit: false
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,15 @@ jobs:

File: [`ci-build-lint-test.yml`](.github/workflows/ci-build-lint-test.yml). Build → lint → format → typecheck → test (matrix) pipeline with optional incremental build cache and artifact upload.

Coverage comes from the matrix entry matching the effective setup version. If
the matrix uses different selectors (for example `[22]` with an exact setup pin
`22.23.4`), its first entry publishes coverage instead. Node modules are restored
from the prepare cache only for an exact matching matrix entry.

| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| `node-version` | number | false | `22` | Node.js version |
| `node-version` | number | false | `22` | Legacy major-version selector |
| `node-version-spec` | string | false | `""` | Exact version or range, e.g. `"22.23.4"`; takes precedence over `node-version`. Set `test-node-versions` separately for build/test matrix jobs. |
| `build-command` | string | true | — | Build command (e.g., "pnpm build") |
| `lint-command` | string | false | `""` | Lint command (e.g., "pnpm lint") |
| `format-command` | string | false | `""` | Format check command (e.g., "pnpm format:check") |
Expand Down Expand Up @@ -183,7 +189,8 @@ File: [`ci-quality.yml`](.github/workflows/ci-quality.yml). Aggregate quality ga

| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| `node-version` | number | false | `22` | Node.js version |
| `node-version` | number | false | `22` | Legacy major-version selector |
| `node-version-spec` | string | false | `""` | Exact version or range, e.g. `"22.23.4"`; takes precedence over `node-version`. Set `test-node-versions` separately for build/test matrix jobs. |
| `verify-command` | string | false | `""` | Package verification command (e.g., "pnpm validate:publish") |
| `changeset-check` | boolean | false | `true` | Whether to run changeset status check on PRs |
| `base-branch` | string | false | `main` | Base branch for changeset comparison (e.g., "main") |
Expand Down
Loading