From 86f4d1acb2cff2e51a1d988e44f3d7621362a51e Mon Sep 17 00:00:00 2001 From: windka Date: Thu, 20 Aug 2026 11:31:03 +0200 Subject: [PATCH 1/3] chore: unpin the standard and declare the coverage configuration The standard was pinned to a commit tarball (codeload.../tar.gz/1726fe5, node-red-standards 0.3.0), so this repo stopped receiving it three releases ago while `standards-check` kept reporting a clean audit against the frozen copy. That is also why .github/workflows/node.js.yml here still has no coverage step: the workflow that added one never arrived. Now `github:windkh/node-red-standards`, which dependabot can move; 0.5.0 treats any other specifier for itself as drift. Adding the c8 block matters more than it looks. There was none, and `c8 --check-coverage` with no block falls back to c8's own defaults -- 90% lines. Measured here: 56.56% lines, 71.6% branches, 64% functions. So the moment the current node.js.yml arrives with its `npm run coverage:check` step, CI would have gone red on a threshold nobody chose. The thresholds are therefore set explicitly at the measured floor, and the reporter now emits lcov so the workflow's coverage artifact contains something readable instead of only c8's raw V8 dump. Verified: lint, format:check, 20 tests, coverage:check all pass. Co-Authored-By: Claude Opus 5 --- package-lock.json | 7 +++---- package.json | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 43a0477..9dbbe0f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "globals": "^17.6.0", "node-red": "^5.0.1", "node-red-node-test-helper": "^0.3.6", - "node-red-standards": "https://codeload.github.com/windkh/node-red-standards/tar.gz/1726fe5133771b88b9c4fd17e64413cca595992e", + "node-red-standards": "github:windkh/node-red-standards", "prettier": "^3.8.3" }, "engines": { @@ -4004,9 +4004,8 @@ } }, "node_modules/node-red-standards": { - "version": "0.3.0", - "resolved": "https://codeload.github.com/windkh/node-red-standards/tar.gz/1726fe5133771b88b9c4fd17e64413cca595992e", - "integrity": "sha512-5rbvWdgI/OSN6ZQBl3U1iTLJ8CWyCHhGll6vZxB/qA1Ye1ROdUP0NSSzyHh1vgzVI3drpklgEI0H9DvHYRIFXg==", + "version": "0.5.0", + "resolved": "git+ssh://git@github.com/windkh/node-red-standards.git#e4bd2440264cea0c42ee6de10ebd7f62a179629d", "dev": true, "license": "MIT", "bin": { diff --git a/package.json b/package.json index ad8090c..b8c2fe6 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,24 @@ "globals": "^17.6.0", "node-red": "^5.0.1", "node-red-node-test-helper": "^0.3.6", - "node-red-standards": "https://codeload.github.com/windkh/node-red-standards/tar.gz/1726fe5133771b88b9c4fd17e64413cca595992e", + "node-red-standards": "github:windkh/node-red-standards", "prettier": "^3.8.3" + }, + "c8": { + "reporter": [ + "text", + "lcov" + ], + "exclude": [ + "test/**", + "test-helpers/**", + "examples/**", + "doc/**", + "eslint.config.js" + ], + "lines": 56, + "statements": 56, + "branches": 71, + "functions": 64 } } From 370f1f26f982fe359811dcee0f15be0f9f5172fd Mon Sep 17 00:00:00 2001 From: windka Date: Thu, 20 Aug 2026 13:31:05 +0200 Subject: [PATCH 2/3] chore: point the lockfile at node-red-standards 0.5.1 0.5.1 adds one audit check: c8.lines must be stated explicitly. c8 defaults it to 90 rather than 0, so an omitted floor is a coverage gate nobody chose. This repo already declares one, so the check passes as-is. Refreshed with `npm update` rather than `npm install`, which does not re-resolve a git dependency whose existing entry already satisfies the specifier -- the mechanism that had kept this reference stale. Co-Authored-By: Claude Opus 5 --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9dbbe0f..0e73c34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4004,8 +4004,8 @@ } }, "node_modules/node-red-standards": { - "version": "0.5.0", - "resolved": "git+ssh://git@github.com/windkh/node-red-standards.git#e4bd2440264cea0c42ee6de10ebd7f62a179629d", + "version": "0.5.1", + "resolved": "git+ssh://git@github.com/windkh/node-red-standards.git#f3982d0a9447df04a6074bf654aca39e174a5fc3", "dev": true, "license": "MIT", "bin": { From edd5ec33de5b129fb92dbda66fb75a8ae0096615 Mon Sep 17 00:00:00 2001 From: windka Date: Thu, 20 Aug 2026 16:28:36 +0200 Subject: [PATCH 3/3] ci: adopt the current node.js.yml and standards-check.yml The last of the pin damage. While node-red-standards was frozen at 0.3.0 these two workflows never received an update, and both mattered. standards-check.yml did `npm ci` + `npx nrstd audit`, i.e. it audited against the version in this repo's own lockfile -- 0.3.0, whose rule set had ten checks, none of which this repo failed. So it reported a clean 10/10 for three releases while .gitattributes, the workflows and the c8 block went unexamined, because those rules did not exist in the frozen copy. The template form (`npx --yes github:windkh/node-red-standards audit`) always resolves the current standard, which is the only form that can detect drift -- a drift detector pinned to an old rule set reports on the wrong question. It is also faster: 13s against 21s, since there is no install to do. node.js.yml had no coverage step at all, which is why the missing c8 block here stayed invisible. It now runs `npm run coverage:check` and uploads the readable half of the report as a build artifact. Also drops `npm run build --if-present`, a leftover from GitHub's starter workflow -- there is no build script. npm-publish.yml is deliberately left alone. It is not stale, it is a different model: triggered by a version tag and creating the GitHub release itself, where the template is triggered by a manually created release. That is a decision to make rather than a drift to correct, raised separately. Verified locally on this branch: lint, format:check, 20 tests, coverage:check exits 0, and coverage/lcov.info plus coverage/lcov-report are produced -- the paths the artifact step uploads. Co-Authored-By: Claude Opus 5 --- .github/workflows/node.js.yml | 32 ++++++++++++++++++--------- .github/workflows/standards-check.yml | 22 ++++++++++-------- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 5d7b89a..acd024b 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -1,32 +1,44 @@ -# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs - name: Node.js CI on: push: - branches: ['main'] + branches: [master, main] pull_request: - branches: ['main'] + branches: [master, main] jobs: build: runs-on: ubuntu-latest - strategy: matrix: node-version: [20.x, 22.x] - # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ - steps: - uses: actions/checkout@v7 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v7 with: node-version: ${{ matrix.node-version }} - cache: 'npm' + cache: npm - run: npm ci - - run: npm run build --if-present - run: npm run lint - run: npm run format:check - run: npm test + - run: npm run coverage:check + # Uploaded from one matrix leg only — the report is identical across them, and + # two legs writing the same artifact name is an error. Makes a coverage + # regression inspectable from the failing run instead of only reproducible locally. + - name: Upload coverage report + if: matrix.node-version == '22.x' + uses: actions/upload-artifact@v7 + with: + name: coverage-report + # Only the readable report, not all of `coverage/`. c8 also writes its + # raw V8 dump to coverage/tmp, which is ~97% of the bytes and inspectable + # by nothing — measured at 23 MB of tmp against a 647 kB report. Uploading + # the directory ships that dead weight on every run for the whole + # retention window, and the step exists to make a failure *readable*. + # Requires c8 to emit a report: `"reporter": ["text", "lcov"]`. + path: | + coverage/lcov-report + coverage/lcov.info + retention-days: 14 diff --git a/.github/workflows/standards-check.yml b/.github/workflows/standards-check.yml index 7dcb64b..dfb0840 100644 --- a/.github/workflows/standards-check.yml +++ b/.github/workflows/standards-check.yml @@ -1,11 +1,14 @@ -# Enforces the shared standard. Tool-neutral, no AI. Fails CI if this repo drifts. +# Synced into target repos by `nrstd sync` as .github/workflows/standards-check.yml. +# Fails CI if the repo drifts from the shared standard. Tool-neutral (no AI). +# `nrstd audit` exits non-zero on any gap, so a repo adopting this should run +# `nrstd sync --write` first — otherwise its next push goes red on pre-existing drift. name: Standards check - on: push: branches: [master, main] pull_request: - +permissions: + contents: read jobs: standards: runs-on: ubuntu-latest @@ -14,9 +17,10 @@ jobs: - uses: actions/setup-node@v7 with: node-version: 20.x - cache: 'npm' - # node-red-standards is declared as a devDependency (public repo, - # HTTPS tarball URL), so `npm ci` installs it and `npx nrstd` - # runs the local binary without an additional network fetch. - - run: npm ci - - run: npx nrstd audit + # Resolved from Git, not the npm registry: this package is deliberately + # unpublished (README "Install", option B), so a bare + # `npx --yes node-red-standards` fails every run with E404 before it can + # audit anything — which reads as drift when it is really a missing + # package. The repo is public, so no token is needed. If it is ever + # published, the short form becomes available and this can go back. + - run: npx --yes github:windkh/node-red-standards audit