Fix/197 restrict scan publishing #267
@@ -270,7 +270,7 @@ Neither failure mentions the Node version as the cause, and the first one reads
|
|||||||
export PATH="/c/Users/tlamb/AppData/Local/nvm/v24.13.1:$PATH"
|
export PATH="/c/Users/tlamb/AppData/Local/nvm/v24.13.1:$PATH"
|
||||||
```
|
```
|
||||||
|
|
||||||
Thom is fine with switching the active version for a test run — `nvm use latest`, then **`nvm use 18.16.1` when finished**, which is not optional since the app's own tooling expects 18.
|
Thom is fine with the scripts switching the active version for a test run: they use the pinned `NODE_VERSION` (26.7.0) in `scripts/NodeVersion.ps1` and restore 18.16.1 when finished, including on failure. Do not run those scripts from an agent shell — they prompt for elevation and can leave the machine with no Node at all.
|
||||||
|
|
||||||
Unit tests and `tsc` run fine on 18, so a green `npm test` says nothing about whether the other two suites can even start.
|
Unit tests and `tsc` run fine on 18, so a green `npm test` says nothing about whether the other two suites can even start.
|
||||||
|
|
||||||
|
|||||||
@@ -33,13 +33,17 @@ Commands below are shown for **PowerShell** (Windows). A bash equivalent is note
|
|||||||
.\scripts\start-local.ps1 -Fresh # ...from an empty database
|
.\scripts\start-local.ps1 -Fresh # ...from an empty database
|
||||||
.\scripts\start-local.ps1 -Stop # stop everything
|
.\scripts\start-local.ps1 -Stop # stop everything
|
||||||
|
|
||||||
.\scripts␍un-tests.ps1 -Suite unit
|
.\scripts
|
||||||
.\scripts␍un-tests.ps1 -Suite integration
|
un-tests.ps1 -Suite unit
|
||||||
.\scripts␍un-tests.ps1 -Suite e2e
|
.\scripts
|
||||||
.\scripts␍un-tests.ps1 -Suite all
|
un-tests.ps1 -Suite integration
|
||||||
|
.\scripts
|
||||||
|
un-tests.ps1 -Suite e2e
|
||||||
|
.\scripts
|
||||||
|
un-tests.ps1 -Suite all
|
||||||
```
|
```
|
||||||
|
|
||||||
Both scripts run `nvm use latest` first and verify the result is Node 20 or newer, then put the machine back to 18.16.1 when they finish — including when they fail partway, so an interrupted run does not leave the version switched. **`nvm use` rewrites a machine-global symlink, so this changes the Node version for every terminal on the machine while a script is running, not only the one you ran it in.** Both scripts say so as they do it.
|
Both scripts switch to the pinned Node 26.7.0 (`NODE_VERSION` in `scripts/NodeVersion.ps1`) and verify that is what actually ends up running, then put the machine back to 18.16.1 when they finish — including when they fail partway, so an interrupted run does not leave the version switched. **`nvm use` rewrites a machine-global symlink, so this changes the Node version for every terminal on the machine while a script is running, not only the one you ran it in.** Both scripts say so as they do it.
|
||||||
|
|
||||||
The Node 20 floor is not arbitrary: `node-pg-migrate` pulls in an `lru-cache` that calls `diagnostics_channel.tracingChannel()`, which does not exist before Node 19.9. On Node 18 migrations die inside minified library code with `(0 , U.tracingChannel) is not a function`, which says nothing about versions.
|
The Node 20 floor is not arbitrary: `node-pg-migrate` pulls in an `lru-cache` that calls `diagnostics_channel.tracingChannel()`, which does not exist before Node 19.9. On Node 18 migrations die inside minified library code with `(0 , U.tracingChannel) is not a function`, which says nothing about versions.
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
"name": "redefined-designs-frontend",
|
"name": "redefined-designs-frontend",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.9.0"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc && tsc -p tsconfig.test.json --noEmit && vite build",
|
"build": "tsc && tsc -p tsconfig.test.json --noEmit && vite build",
|
||||||
|
|||||||
+39
-11
@@ -69,8 +69,17 @@ function Use-Node {
|
|||||||
# nvm wanted is not installed" into a claim that the newest install
|
# nvm wanted is not installed" into a claim that the newest install
|
||||||
# was too old, which sent the reader to `nvm install` holding a list
|
# was too old, which sent the reader to `nvm install` holding a list
|
||||||
# that already had newer versions on it.
|
# that already had newer versions on it.
|
||||||
|
# A POSITIVE match on what success looks like, not a negative
|
||||||
|
# one on an allowlist of English error strings. The negative form
|
||||||
|
# returned True for empty output, for $null, and for
|
||||||
|
# 'exit status 1: Access is denied.' — so an alias switch that
|
||||||
|
# produced nothing, or failed on the symlink permission error this
|
||||||
|
# file's own header warns about, was reported as success while the
|
||||||
|
# old version kept running. That is the bug #198 was filed about,
|
||||||
|
# narrowed rather than removed. It also broke whenever nvm reworded
|
||||||
|
# an error. See #208.
|
||||||
$switched = if ($Version -in @('latest', 'lts', 'newest')) {
|
$switched = if ($Version -in @('latest', 'lts', 'newest')) {
|
||||||
$output -notmatch 'activation error|not installed'
|
$output -match ('Now using node v' + [regex]::Escape($raw.TrimStart('v')))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$raw.TrimStart('v') -eq $Version.TrimStart('v')
|
$raw.TrimStart('v') -eq $Version.TrimStart('v')
|
||||||
@@ -100,9 +109,10 @@ nvm said:
|
|||||||
$output
|
$output
|
||||||
|
|
||||||
nvm-windows rewrites a symlink at $env:NVM_SYMLINK, and can report success
|
nvm-windows rewrites a symlink at $env:NVM_SYMLINK, and can report success
|
||||||
without having rewritten it. Check the version is installed, and that this shell
|
without having rewritten it. If that version is not installed, install it; if it
|
||||||
can write that link:
|
is, check this shell can write that link:
|
||||||
|
|
||||||
|
nvm install $Version
|
||||||
nvm list
|
nvm list
|
||||||
"@
|
"@
|
||||||
}
|
}
|
||||||
@@ -114,6 +124,20 @@ can write that link:
|
|||||||
# the specification.
|
# the specification.
|
||||||
$script:NODE_VERSION = '26.7.0'
|
$script:NODE_VERSION = '26.7.0'
|
||||||
|
|
||||||
|
# What the machine is put back to afterwards. Beside NODE_VERSION rather than
|
||||||
|
# duplicated as a parameter default in each script, because two copies of a
|
||||||
|
# version drift and the half that drifts is the half nobody runs. Both scripts
|
||||||
|
# still take -DefaultNodeVersion to override it.
|
||||||
|
$script:DEFAULT_NODE_VERSION = '18.16.1'
|
||||||
|
|
||||||
|
# Local runs are three major lines ahead of CI (Node 20 in every workflow) and of
|
||||||
|
# the production image (node:20-bookworm-slim). That divergence is deliberate but
|
||||||
|
# not free: post-20 syntax and node: APIs pass here and fail in the pipeline, and
|
||||||
|
# Node 26 ships an npm that can touch the lockfile in ways CI's npm reads
|
||||||
|
# differently. The `engines` field in both package.json files records the floor
|
||||||
|
# machine-readably; nothing yet catches "too new for where this ships". See #208
|
||||||
|
# part 4, which is an open decision rather than an oversight.
|
||||||
|
|
||||||
<#
|
<#
|
||||||
Switches to the pinned version and insists it clears the floor.
|
Switches to the pinned version and insists it clears the floor.
|
||||||
|
|
||||||
@@ -130,20 +154,24 @@ $script:NODE_VERSION = '26.7.0'
|
|||||||
A version that is not installed is Use-Node's error to report, and it now
|
A version that is not installed is Use-Node's error to report, and it now
|
||||||
reports nvm's own reason, so there is nothing to say about it here.
|
reports nvm's own reason, so there is nothing to say about it here.
|
||||||
#>
|
#>
|
||||||
function Use-NodeLatest {
|
function Use-PinnedNode {
|
||||||
param([scriptblock]$Step, [scriptblock]$Note)
|
param([scriptblock]$Step, [scriptblock]$Note)
|
||||||
|
|
||||||
Use-Node -Version $script:NODE_VERSION -Why 'this project needs Node 20 or newer' -Step $Step -Note $Note | Out-Null
|
# Checked BEFORE the switch, against the constant rather than against what
|
||||||
|
# ends up running. After the switch $major is whatever NODE_VERSION says,
|
||||||
$major = Get-NodeMajor
|
# so the old placement could never fire — it validated the switch it had
|
||||||
if ($major -lt 20) {
|
# just made instead of the pin it exists to guard. See #208.
|
||||||
|
$pinnedMajor = [int](($script:NODE_VERSION -replace '^v', '') -split '\.')[0]
|
||||||
|
if ($pinnedMajor -lt 20) {
|
||||||
throw @"
|
throw @"
|
||||||
Node is v$major after switching to $($script:NODE_VERSION), which is below the 20 this project needs.
|
NODE_VERSION in scripts/NodeVersion.ps1 is $($script:NODE_VERSION), which is below the 20 this project needs.
|
||||||
|
|
||||||
NODE_VERSION in scripts/NodeVersion.ps1 is pinned to a version that is too old.
|
node-pg-migrate, ts-jest and Playwright all need 20 or newer. Nothing was
|
||||||
node-pg-migrate, ts-jest and Playwright all need 20 or newer.
|
switched.
|
||||||
"@
|
"@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Use-Node -Version $script:NODE_VERSION -Why 'this project needs Node 20 or newer' -Step $Step -Note $Note | Out-Null
|
||||||
}
|
}
|
||||||
|
|
||||||
<#
|
<#
|
||||||
|
|||||||
+13
-3
@@ -8,7 +8,7 @@
|
|||||||
database bring-up and the TEST_PGPORT handling are shared by more than one
|
database bring-up and the TEST_PGPORT handling are shared by more than one
|
||||||
suite and would otherwise be copied around and drift apart.
|
suite and would otherwise be copied around and drift apart.
|
||||||
|
|
||||||
Switches Node to the latest installed version for the run and puts the
|
Switches Node to the pinned version in scripts/NodeVersion.ps1 for the run and puts the
|
||||||
machine default back afterwards, the same way start-local.ps1 does — and for
|
machine default back afterwards, the same way start-local.ps1 does — and for
|
||||||
the same reason, since ts-jest and Playwright are subject to the same Node
|
the same reason, since ts-jest and Playwright are subject to the same Node
|
||||||
20 floor as the migrations.
|
20 floor as the migrations.
|
||||||
@@ -47,7 +47,12 @@ param(
|
|||||||
[int]$TestDbPort = 55432,
|
[int]$TestDbPort = 55432,
|
||||||
[switch]$KeepTestDb,
|
[switch]$KeepTestDb,
|
||||||
[string]$Filter,
|
[string]$Filter,
|
||||||
[string]$DefaultNodeVersion = '18.16.1'
|
# Resolved after NodeVersion.ps1 is dot-sourced below, not here. A param
|
||||||
|
# block runs before anything else in the script, so $script:DEFAULT_NODE_VERSION
|
||||||
|
# is still $null at this point and using it as the default would silently
|
||||||
|
# restore nothing — leaving the machine on the pinned version, which is the
|
||||||
|
# exact failure the restore exists to prevent. See #208.
|
||||||
|
[string]$DefaultNodeVersion = ''
|
||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
@@ -74,6 +79,11 @@ function Invoke-Checked {
|
|||||||
|
|
||||||
. (Join-Path $PSScriptRoot 'NodeVersion.ps1')
|
. (Join-Path $PSScriptRoot 'NodeVersion.ps1')
|
||||||
|
|
||||||
|
# The one home for this value is NodeVersion.ps1, beside NODE_VERSION. It cannot
|
||||||
|
# be a param default (see the note there), so it is filled in here instead, and
|
||||||
|
# an explicit -DefaultNodeVersion still wins.
|
||||||
|
if (-not $DefaultNodeVersion) { $DefaultNodeVersion = $script:DEFAULT_NODE_VERSION }
|
||||||
|
|
||||||
# Bound once so the shared switcher reports in this script's output style.
|
# Bound once so the shared switcher reports in this script's output style.
|
||||||
$NodeOut = @{ Step = ${function:Write-Step}; Note = ${function:Write-Note} }
|
$NodeOut = @{ Step = ${function:Write-Step}; Note = ${function:Write-Note} }
|
||||||
|
|
||||||
@@ -160,7 +170,7 @@ running stack. Start it first:
|
|||||||
finally { Pop-Location }
|
finally { Pop-Location }
|
||||||
}
|
}
|
||||||
|
|
||||||
Use-NodeLatest @NodeOut
|
Use-PinnedNode @NodeOut
|
||||||
|
|
||||||
try {
|
try {
|
||||||
switch ($Suite) {
|
switch ($Suite) {
|
||||||
|
|||||||
+12
-2
@@ -39,7 +39,12 @@ param(
|
|||||||
# What -Stop puts the machine back to. nvm's default here is 18.16.1, which
|
# What -Stop puts the machine back to. nvm's default here is 18.16.1, which
|
||||||
# is too old to run this project's tooling but is what everything else on
|
# is too old to run this project's tooling but is what everything else on
|
||||||
# the machine expects.
|
# the machine expects.
|
||||||
[string]$DefaultNodeVersion = '18.16.1'
|
# Resolved after NodeVersion.ps1 is dot-sourced below, not here. A param
|
||||||
|
# block runs before anything else in the script, so $script:DEFAULT_NODE_VERSION
|
||||||
|
# is still $null at this point and using it as the default would silently
|
||||||
|
# restore nothing — leaving the machine on the pinned version, which is the
|
||||||
|
# exact failure the restore exists to prevent. See #208.
|
||||||
|
[string]$DefaultNodeVersion = ''
|
||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
@@ -78,6 +83,11 @@ function Assert-Docker {
|
|||||||
|
|
||||||
. (Join-Path $PSScriptRoot 'NodeVersion.ps1')
|
. (Join-Path $PSScriptRoot 'NodeVersion.ps1')
|
||||||
|
|
||||||
|
# The one home for this value is NodeVersion.ps1, beside NODE_VERSION. It cannot
|
||||||
|
# be a param default (see the note there), so it is filled in here instead, and
|
||||||
|
# an explicit -DefaultNodeVersion still wins.
|
||||||
|
if (-not $DefaultNodeVersion) { $DefaultNodeVersion = $script:DEFAULT_NODE_VERSION }
|
||||||
|
|
||||||
# Bound once so the shared switcher reports through this script's own output
|
# Bound once so the shared switcher reports through this script's own output
|
||||||
# style rather than printing in a voice of its own.
|
# style rather than printing in a voice of its own.
|
||||||
$NodeOut = @{ Step = ${function:Write-Step}; Note = ${function:Write-Note} }
|
$NodeOut = @{ Step = ${function:Write-Step}; Note = ${function:Write-Note} }
|
||||||
@@ -270,7 +280,7 @@ if ($Stop) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Use-NodeLatest @NodeOut
|
Use-PinnedNode @NodeOut
|
||||||
|
|
||||||
# Anything after the switch reverts on the way out of a failure. Without this a
|
# Anything after the switch reverts on the way out of a failure. Without this a
|
||||||
# run that dies in migrations leaves the machine on the new version with nothing
|
# run that dies in migrations leaves the machine on the new version with nothing
|
||||||
|
|||||||
Reference in New Issue
Block a user