Skip to content

Commit 7020d2a

Browse files
committed
fix(test): pin pkg.pr.new migration builds by commit
1 parent dcef017 commit 7020d2a

6 files changed

Lines changed: 70 additions & 52 deletions

File tree

.github/scripts/test-pkg-pr-new-migrate.sh

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,11 @@ original_home="$HOME"
6666
cache_root="${XDG_CACHE_HOME:-$original_home/.cache}"
6767
pr_home="${VP_PKG_PR_NEW_HOME:-$cache_root/vite-plus/pkg-pr-new/$pr_ref}"
6868
installer_home="$(mktemp -d "${TMPDIR:-/tmp}/vite-plus-pr-installer.XXXXXX")"
69-
cached_version_dir="$pr_home/pkg-pr-new-$pr_ref"
70-
vp_bin="$pr_home/bin/vp"
71-
vite_plus_package_json="$pr_home/current/node_modules/vite-plus/package.json"
72-
global_cli_entry="$pr_home/current/node_modules/vite-plus/dist/bin.js"
73-
commit_marker="$cached_version_dir/.pkg-pr-new-commit"
7469
pkg_pr_new_base="https://pkg.pr.new/voidzero-dev/vite-plus"
75-
vite_plus_spec="$pkg_pr_new_base@$pr_ref"
76-
vite_plus_core_spec="$pkg_pr_new_base/@voidzero-dev/vite-plus-core@$pr_ref"
70+
requested_vite_plus_spec="$pkg_pr_new_base@$pr_ref"
7771

7872
resolve_pkg_pr_new_commit() {
79-
curl -fsSIL "$vite_plus_spec" | tr -d '\r' | awk -F ': ' '
73+
curl -fsSIL "$requested_vite_plus_spec" | tr -d '\r' | awk -F ': ' '
8074
tolower($1) == "x-commit-key" {
8175
count = split($2, parts, ":")
8276
print parts[count]
@@ -85,6 +79,32 @@ resolve_pkg_pr_new_commit() {
8579
'
8680
}
8781

82+
available_commit="$(resolve_pkg_pr_new_commit || true)"
83+
case "$available_commit" in
84+
'' | *[!0-9a-fA-F]*)
85+
echo "error: could not resolve an immutable pkg.pr.new commit for $pr_ref" >&2
86+
exit 1
87+
;;
88+
esac
89+
if [ "${#available_commit}" -ne 40 ]; then
90+
echo "error: pkg.pr.new returned an invalid commit for $pr_ref: $available_commit" >&2
91+
exit 1
92+
fi
93+
94+
# PR-number URLs are mutable and pkg.pr.new packages reference their internal
95+
# workspace dependencies by commit SHA. Persisting the PR URL alongside those
96+
# SHA URLs makes package managers install duplicate copies of the same package.
97+
# Resolve once, then use the immutable SHA for the global install and every
98+
# dependency spec written by migration.
99+
resolved_ref="$available_commit"
100+
cached_version_dir="$pr_home/pkg-pr-new-$resolved_ref"
101+
vp_bin="$pr_home/bin/vp"
102+
vite_plus_package_json="$pr_home/current/node_modules/vite-plus/package.json"
103+
global_cli_entry="$pr_home/current/node_modules/vite-plus/dist/bin.js"
104+
commit_marker="$cached_version_dir/.pkg-pr-new-commit"
105+
vite_plus_spec="$pkg_pr_new_base@$resolved_ref"
106+
vite_plus_core_spec="$pkg_pr_new_base/@voidzero-dev/vite-plus-core@$resolved_ref"
107+
88108
read_installed_commit() {
89109
if [ -f "$commit_marker" ]; then
90110
head -n 1 "$commit_marker"
@@ -103,14 +123,12 @@ read_installed_commit() {
103123
fi
104124
}
105125

106-
available_commit="$(resolve_pkg_pr_new_commit || true)"
107126
installed_commit="$(read_installed_commit || true)"
108127
current_target="$(readlink "$pr_home/current" 2>/dev/null || true)"
109128
reuse_install=0
110129

111-
if [ -n "$available_commit" ] &&
112-
[ "$installed_commit" = "$available_commit" ] &&
113-
[ "$current_target" = "pkg-pr-new-$pr_ref" ] &&
130+
if [ "$installed_commit" = "$resolved_ref" ] &&
131+
[ "$current_target" = "pkg-pr-new-$resolved_ref" ] &&
114132
[ -x "$vp_bin" ] &&
115133
[ -f "$vite_plus_package_json" ] &&
116134
[ -f "$global_cli_entry" ]; then
@@ -123,38 +141,36 @@ cleanup() {
123141
trap cleanup EXIT
124142

125143
if [ "$reuse_install" -eq 1 ]; then
126-
printf '%s\n' "$available_commit" > "$commit_marker"
127-
echo "Reusing installed Vite+ pkg.pr.new build $pr_ref ($available_commit) from $pr_home"
144+
printf '%s\n' "$resolved_ref" > "$commit_marker"
145+
echo "Reusing installed Vite+ pkg.pr.new build $resolved_ref (requested $pr_ref) from $pr_home"
128146
else
129-
if [ -z "$available_commit" ]; then
130-
echo "Could not verify the current pkg.pr.new commit; reinstalling $pr_ref."
147+
if [ -n "$installed_commit" ] && [ "$installed_commit" != "$resolved_ref" ]; then
148+
echo "pkg.pr.new build changed: $installed_commit -> $resolved_ref"
131149
elif [ -n "$installed_commit" ]; then
132-
echo "pkg.pr.new build changed: $installed_commit -> $available_commit"
150+
echo "Reinstalling pkg.pr.new build $resolved_ref with an immutable cache key"
151+
fi
152+
153+
# This helper owns a dedicated VP_HOME for each requested PR/ref. Remember
154+
# the previous immutable install so it can be removed only after the new one
155+
# succeeds, while retaining shared runtime and package-manager caches.
156+
previous_target=""
157+
if [ -n "$current_target" ] && [ "$current_target" != "pkg-pr-new-$resolved_ref" ]; then
158+
case "$current_target" in
159+
pkg-pr-new-*) previous_target="$current_target" ;;
160+
esac
133161
fi
134162

135-
# Numeric pkg.pr.new references are mutable PR aliases. If the published
136-
# commit changed, the reused lockfile can retain the checksum from the older
137-
# tarball and fail with ERR_PNPM_TARBALL_INTEGRITY. Keep the downloaded
138-
# runtime/package-manager cache, but force the wrapper dependency to resolve
139-
# again. Commit SHA references are immutable and use their own cache path.
140-
case "$pr_ref" in
141-
*[!0-9]*) ;;
142-
*)
143-
rm -rf "$cached_version_dir/node_modules"
144-
rm -f "$cached_version_dir/pnpm-lock.yaml"
145-
;;
146-
esac
147-
148-
echo "Installing Vite+ pkg.pr.new build $pr_ref into $pr_home"
163+
echo "Installing Vite+ pkg.pr.new build $resolved_ref (requested $pr_ref) into $pr_home"
149164
HOME="$installer_home" \
150165
VP_HOME="$pr_home" \
151-
VP_PR_VERSION="$pr_ref" \
166+
VP_PR_VERSION="$resolved_ref" \
152167
VP_NODE_MANAGER=no \
153168
bash "$installer"
154169

155-
if [ -n "$available_commit" ]; then
156-
printf '%s\n' "$available_commit" > "$commit_marker"
170+
if [ -n "$previous_target" ]; then
171+
rm -rf "$pr_home/$previous_target"
157172
fi
173+
printf '%s\n' "$resolved_ref" > "$commit_marker"
158174
fi
159175

160176
if [ ! -x "$vp_bin" ]; then
@@ -195,6 +211,8 @@ hash -r
195211

196212
echo
197213
echo "Using isolated global CLI:"
214+
echo " requested ref: $pr_ref"
215+
echo " resolved commit: $resolved_ref"
198216
echo " executable: $vp_bin"
199217
echo " installation: $(readlink "$pr_home/current" 2>/dev/null || echo unknown)"
200218
echo " vite-plus spec: $VP_VERSION"

packages/cli/snap-tests-global/migration-upgrade-pkg-pr-new-npm/snap.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,23 @@
33
• Node <semver> npm <semver>
44
• 2 config updates applied
55

6-
> cat package.json # direct dependencies and npm overrides use the same PR URLs
6+
> cat package.json # direct dependencies and npm overrides use the same immutable commit URLs
77
{
88
"name": "migration-upgrade-pkg-pr-new-npm",
99
"devDependencies": {
10-
"vite": "https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@1891",
11-
"vite-plus": "https://pkg.pr.new/voidzero-dev/vite-plus@1891"
10+
"vite": "https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@0c515e3fbf5c140db35280d700df0bd600838617",
11+
"vite-plus": "https://pkg.pr.new/voidzero-dev/vite-plus@0c515e3fbf5c140db35280d700df0bd600838617"
1212
},
1313
"overrides": {
14-
"vite": "https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@1891"
14+
"vite": "https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@0c515e3fbf5c140db35280d700df0bd600838617"
1515
},
1616
"packageManager": "npm@<semver>",
1717
"scripts": {
1818
"prepare": "vp config"
1919
}
2020
}
2121

22-
> node -e "const p = require('./package.json'); const vp = 'https://pkg.pr.new/voidzero-dev/vite-plus@1891'; const core = 'https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@1891'; if (p.devDependencies['vite-plus'] !== vp || p.devDependencies.vite !== core || p.overrides.vite !== core || p.overrides['@voidzero-dev/vite-plus-core'] !== undefined) process.exit(1)" # pkg.pr.new specs use the minimal override shape
22+
> node -e "const p = require('./package.json'); const sha = '0c515e3fbf5c140db35280d700df0bd600838617'; const vp = 'https://pkg.pr.new/voidzero-dev/vite-plus@' + sha; const core = 'https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@' + sha; if (p.devDependencies['vite-plus'] !== vp || p.devDependencies.vite !== core || p.overrides.vite !== core || p.overrides['@voidzero-dev/vite-plus-core'] !== undefined || JSON.stringify(p).includes('@1891')) process.exit(1)" # pkg.pr.new specs use one immutable commit and the minimal override shape
2323
> node -e "require('node:fs').copyFileSync('package.json', 'package.after-first-migration.json')" # capture first migration result
2424
> vp migrate --no-interactive # pkg.pr.new migration is idempotent
2525
◇ Migrated . to Vite+

packages/cli/snap-tests-global/migration-upgrade-pkg-pr-new-npm/steps.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"env": {
33
"VP_FORCE_MIGRATE": "1",
4-
"VP_OVERRIDE_PACKAGES": "{\"vite\":\"https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@1891\",\"vitest\":\"4.1.9\"}",
5-
"VP_VERSION": "https://pkg.pr.new/voidzero-dev/vite-plus@1891"
4+
"VP_OVERRIDE_PACKAGES": "{\"vite\":\"https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@0c515e3fbf5c140db35280d700df0bd600838617\",\"vitest\":\"4.1.9\"}",
5+
"VP_VERSION": "https://pkg.pr.new/voidzero-dev/vite-plus@0c515e3fbf5c140db35280d700df0bd600838617"
66
},
77
"commands": [
88
"vp migrate --no-interactive # pkg.pr.new targets replace every stale managed spec",
9-
"cat package.json # direct dependencies and npm overrides use the same PR URLs",
10-
"node -e \"const p = require('./package.json'); const vp = 'https://pkg.pr.new/voidzero-dev/vite-plus@1891'; const core = 'https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@1891'; if (p.devDependencies['vite-plus'] !== vp || p.devDependencies.vite !== core || p.overrides.vite !== core || p.overrides['@voidzero-dev/vite-plus-core'] !== undefined) process.exit(1)\" # pkg.pr.new specs use the minimal override shape",
9+
"cat package.json # direct dependencies and npm overrides use the same immutable commit URLs",
10+
"node -e \"const p = require('./package.json'); const sha = '0c515e3fbf5c140db35280d700df0bd600838617'; const vp = 'https://pkg.pr.new/voidzero-dev/vite-plus@' + sha; const core = 'https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@' + sha; if (p.devDependencies['vite-plus'] !== vp || p.devDependencies.vite !== core || p.overrides.vite !== core || p.overrides['@voidzero-dev/vite-plus-core'] !== undefined || JSON.stringify(p).includes('@1891')) process.exit(1)\" # pkg.pr.new specs use one immutable commit and the minimal override shape",
1111
"node -e \"require('node:fs').copyFileSync('package.json', 'package.after-first-migration.json')\" # capture first migration result",
1212
"vp migrate --no-interactive # pkg.pr.new migration is idempotent",
1313
"node -e \"const fs = require('node:fs'); if (fs.readFileSync('package.json', 'utf8') !== fs.readFileSync('package.after-first-migration.json', 'utf8')) process.exit(1)\" # rerun leaves package.json unchanged"

packages/cli/snap-tests-global/migration-upgrade-pkg-pr-new-pnpm/snap.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
"packageManager": "pnpm@<semver>",
1616
"pnpm": {
1717
"overrides": {
18-
"vite": "https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@1891",
18+
"vite": "https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@0c515e3fbf5c140db35280d700df0bd600838617",
1919
"vitest": "<semver>",
20-
"vite-plus": "https://pkg.pr.new/voidzero-dev/vite-plus@1891"
20+
"vite-plus": "https://pkg.pr.new/voidzero-dev/vite-plus@0c515e3fbf5c140db35280d700df0bd600838617"
2121
}
2222
},
2323
"scripts": {
@@ -32,8 +32,8 @@ packages:
3232
blockExoticSubdeps: false
3333

3434
catalog:
35-
vite: https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@1891
36-
vite-plus: https://pkg.pr.new/voidzero-dev/vite-plus@1891
35+
vite: https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@0c515e3fbf5c140db35280d700df0bd600838617
36+
vite-plus: https://pkg.pr.new/voidzero-dev/vite-plus@0c515e3fbf5c140db35280d700df0bd600838617
3737
vitest: <semver>
3838

3939
overrides:
@@ -48,7 +48,7 @@ peerDependencyRules:
4848
vite: '*'
4949
vitest: '*'
5050

51-
> node -e "const fs = require('node:fs'); const y = fs.readFileSync('pnpm-workspace.yaml', 'utf8'); if (!y.includes('blockExoticSubdeps: false') || !y.includes('https://pkg.pr.new/voidzero-dev/vite-plus@1891') || !y.includes('https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@1891')) process.exit(1)" # pnpm policy and PR targets are persisted
51+
> node -e "const fs = require('node:fs'); const y = fs.readFileSync('pnpm-workspace.yaml', 'utf8'); const sha = '0c515e3fbf5c140db35280d700df0bd600838617'; if (!y.includes('blockExoticSubdeps: false') || !y.includes('https://pkg.pr.new/voidzero-dev/vite-plus@' + sha) || !y.includes('https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@' + sha) || y.includes('@1891')) process.exit(1)" # pnpm policy and immutable commit targets are persisted
5252
> node -e "const fs = require('node:fs'); fs.copyFileSync('package.json', 'package.after-first-migration.json'); fs.copyFileSync('pnpm-workspace.yaml', 'workspace.after-first-migration.yaml')" # capture first migration result
5353
> vp migrate --no-interactive # pkg.pr.new pnpm migration is idempotent
5454
◇ Migrated . to Vite+

packages/cli/snap-tests-global/migration-upgrade-pkg-pr-new-pnpm/steps.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
"env": {
33
"PNPM_CONFIG_BLOCK_EXOTIC_SUBDEPS": "false",
44
"VP_FORCE_MIGRATE": "1",
5-
"VP_OVERRIDE_PACKAGES": "{\"vite\":\"https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@1891\",\"vitest\":\"4.1.9\"}",
6-
"VP_VERSION": "https://pkg.pr.new/voidzero-dev/vite-plus@1891"
5+
"VP_OVERRIDE_PACKAGES": "{\"vite\":\"https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@0c515e3fbf5c140db35280d700df0bd600838617\",\"vitest\":\"4.1.9\"}",
6+
"VP_VERSION": "https://pkg.pr.new/voidzero-dev/vite-plus@0c515e3fbf5c140db35280d700df0bd600838617"
77
},
88
"commands": [
99
"vp migrate --no-interactive # pkg.pr.new pnpm migration allows URL-resolved subdependencies",
1010
"cat package.json # direct dependencies use catalogs aligned to the pkg.pr.new build",
1111
"cat pnpm-workspace.yaml # pkg.pr.new URLs are pinned and exotic subdependencies are allowed",
12-
"node -e \"const fs = require('node:fs'); const y = fs.readFileSync('pnpm-workspace.yaml', 'utf8'); if (!y.includes('blockExoticSubdeps: false') || !y.includes('https://pkg.pr.new/voidzero-dev/vite-plus@1891') || !y.includes('https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@1891')) process.exit(1)\" # pnpm policy and PR targets are persisted",
12+
"node -e \"const fs = require('node:fs'); const y = fs.readFileSync('pnpm-workspace.yaml', 'utf8'); const sha = '0c515e3fbf5c140db35280d700df0bd600838617'; if (!y.includes('blockExoticSubdeps: false') || !y.includes('https://pkg.pr.new/voidzero-dev/vite-plus@' + sha) || !y.includes('https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@' + sha) || y.includes('@1891')) process.exit(1)\" # pnpm policy and immutable commit targets are persisted",
1313
"node -e \"const fs = require('node:fs'); fs.copyFileSync('package.json', 'package.after-first-migration.json'); fs.copyFileSync('pnpm-workspace.yaml', 'workspace.after-first-migration.yaml')\" # capture first migration result",
1414
"vp migrate --no-interactive # pkg.pr.new pnpm migration is idempotent",
1515
"node -e \"const fs = require('node:fs'); if (fs.readFileSync('package.json', 'utf8') !== fs.readFileSync('package.after-first-migration.json', 'utf8') || fs.readFileSync('pnpm-workspace.yaml', 'utf8') !== fs.readFileSync('workspace.after-first-migration.yaml', 'utf8')) process.exit(1)\" # rerun leaves manifests unchanged"

packages/cli/src/migration/__tests__/migrator.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1550,7 +1550,7 @@ describe('ensureVitePlusBootstrap', () => {
15501550
const savedForceMigrate = process.env.VP_FORCE_MIGRATE;
15511551
const savedViteOverride = VITE_PLUS_OVERRIDE_PACKAGES.vite;
15521552
const viteOverride =
1553-
'https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@1891';
1553+
'https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@0c515e3fbf5c140db35280d700df0bd600838617';
15541554
process.env.VP_FORCE_MIGRATE = '1';
15551555
VITE_PLUS_OVERRIDE_PACKAGES.vite = viteOverride;
15561556
try {

0 commit comments

Comments
 (0)