Add an opt-in CAS installer and synchronous Node.js module loader. Generate package-instance manifests and embed the runtime in the Rust CLI. Load compatible package files directly from verified store blobs while retaining ordinary complete GVS installations for explicitly materialized dependency trees. Reuse the existing fetch, graph hashing, linking, build approval, and command shim pipelines. Preserve loader references during store pruning and preload the loader for normal script and command execution. Keep application filesystem APIs intact. Document the install mode; keep compatibility experiment results in the implementation task. Related to https://github.com/pnpm/tasks/issues/64. Future linker-specific settings and nested hoisting configuration are tracked separately in https://github.com/pnpm/tasks/issues/72. Only the loaded-linker object form is included here.
124 lines
5.8 KiB
JavaScript
124 lines
5.8 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { execFileSync } from 'node:child_process'
|
|
import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
import os from 'node:os'
|
|
import path from 'node:path'
|
|
import { test } from 'node:test'
|
|
import { prepareDocsSync } from './prepare-docs-sync.mjs'
|
|
|
|
function fixture (t, tag = 'v12.8.2') {
|
|
const repo = mkdtempSync(path.join(os.tmpdir(), 'pnpm-docs-release-'))
|
|
t.after(() => rmSync(repo, { recursive: true, force: true, maxRetries: 3 }))
|
|
const git = (...args) => execFileSync('git', args, { cwd: repo, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim()
|
|
const version = tag.startsWith('pnpr@') ? tag.slice(5) : tag.slice(1)
|
|
for (const [product, current] of [['pnpm/npm/pnpm', '12.8.2'], ['pnpm11/pnpm', '11.28.2'], ['pnpr/npm/pnpr', '0.1.0-alpha.14']]) {
|
|
mkdirSync(path.join(repo, product), { recursive: true })
|
|
const productVersion = version.split('.')[0] === current.split('.')[0] ? version : current
|
|
writeFileSync(path.join(repo, product, 'package.json'), JSON.stringify({ version: productVersion }))
|
|
}
|
|
git('init', '--quiet')
|
|
git('config', 'commit.gpgsign', 'false')
|
|
git('config', 'user.name', 'Test')
|
|
git('config', 'user.email', 'test@example.com')
|
|
git('add', '.')
|
|
git('commit', '--quiet', '-m', 'chore: release')
|
|
git('update-ref', `refs/tags/${tag}`, 'HEAD')
|
|
const sha = git('rev-parse', 'HEAD')
|
|
let verified = false
|
|
const options = {
|
|
releaseTag: tag,
|
|
git: (...args) => {
|
|
if (args[0] === 'verify-tag') { verified = true; return '' }
|
|
return git(...args)
|
|
},
|
|
publicationState: spec => {
|
|
assert.equal(verified, true)
|
|
assert.equal(spec, `${tag.startsWith('pnpr@') ? '@pnpm/pnpr' : 'pnpm'}@${version}`)
|
|
return 'published'
|
|
},
|
|
}
|
|
return { repo, git, sha, options }
|
|
}
|
|
|
|
test('selects only the signed and published release snapshot', t => {
|
|
const f = fixture(t)
|
|
assert.deepEqual(prepareDocsSync(f.options), {
|
|
publish: true, line: '12.x', version: '12.8.2', release_commit: f.sha, docs_commit: f.sha,
|
|
})
|
|
assert.throws(() => prepareDocsSync({ ...f.options, publicationState: () => 'missing' }), /not been published/)
|
|
assert.throws(() => prepareDocsSync({ ...f.options, git: (...args) => args[0] === 'verify-tag' ? f.git(...args) : f.options.git(...args) }))
|
|
})
|
|
|
|
test('ignores prereleases and rejects releases outside stable v11 and v12', () => {
|
|
assert.throws(() => prepareDocsSync({ releaseTag: 'pnpm-wasm-v1.0.0' }), /Expected a pnpm or pnpr release tag/)
|
|
assert.equal(prepareDocsSync({ releaseTag: 'v12.9.0-beta.1' }), undefined)
|
|
for (const tag of ['v10.30.0', 'v13.0.0']) {
|
|
assert.throws(() => prepareDocsSync({ releaseTag: tag }), /v11 and v12/)
|
|
}
|
|
})
|
|
|
|
test('manual corrections must contain only the selected version docs', t => {
|
|
const f = fixture(t)
|
|
mkdirSync(path.join(f.repo, 'pnpm/docs'), { recursive: true })
|
|
writeFileSync(path.join(f.repo, 'pnpm/docs/install.md'), 'correction')
|
|
f.git('add', '.')
|
|
f.git('commit', '--quiet', '-m', 'docs: correction')
|
|
const options = { ...f.options, releaseTag: 'v12.8.2', docsRef: f.git('rev-parse', 'HEAD') }
|
|
assert.equal(prepareDocsSync(options).docs_commit, options.docsRef)
|
|
assert.throws(() => prepareDocsSync({ ...options, docsRef: 'main' }), /full commit SHA/)
|
|
writeFileSync(path.join(f.repo, 'unreleased.js'), 'new behavior')
|
|
f.git('add', '.')
|
|
f.git('commit', '--quiet', '-m', 'feat: unreleased behavior')
|
|
assert.throws(() => prepareDocsSync({ ...options, docsRef: f.git('rev-parse', 'HEAD') }), /change only/)
|
|
})
|
|
|
|
|
|
test('v11 corrections use the TypeScript product documentation', t => {
|
|
const f = fixture(t, 'v11.28.3')
|
|
mkdirSync(path.join(f.repo, 'pnpm11/docs'), { recursive: true })
|
|
writeFileSync(path.join(f.repo, 'pnpm11/docs/install.md'), 'correction')
|
|
f.git('add', '.')
|
|
f.git('commit', '--quiet', '-m', 'docs: v11 correction')
|
|
const result = prepareDocsSync({ ...f.options, releaseTag: 'v11.28.3', docsRef: f.git('rev-parse', 'HEAD') })
|
|
assert.equal(result.line, '11.x')
|
|
})
|
|
|
|
|
|
test('pnpr alpha releases and corrections select only the registry documentation', t => {
|
|
const f = fixture(t, 'pnpr@0.1.0-alpha.15')
|
|
assert.equal(prepareDocsSync(f.options).line, 'pnpr')
|
|
mkdirSync(path.join(f.repo, 'pnpr/docs'), { recursive: true })
|
|
writeFileSync(path.join(f.repo, 'pnpr/docs/installation.md'), 'correction')
|
|
f.git('add', '.')
|
|
f.git('commit', '--quiet', '-m', 'docs: registry correction')
|
|
const result = prepareDocsSync({ ...f.options, releaseTag: 'pnpr@0.1.0-alpha.15', docsRef: f.git('rev-parse', 'HEAD') })
|
|
assert.equal(result.line, 'pnpr')
|
|
assert.equal(result.docs_commit, f.git('rev-parse', 'HEAD'))
|
|
})
|
|
|
|
test('manual publication from main needs no release or npm publication', t => {
|
|
const f = fixture(t)
|
|
assert.deepEqual(prepareDocsSync({
|
|
githubRef: 'refs/heads/main',
|
|
git: f.git,
|
|
publicationState: () => assert.fail('main publication must not query npm'),
|
|
}), { publish: true, main_sync: true, docs_commit: f.sha })
|
|
})
|
|
|
|
test('manual publication without a release is restricted to main and its checked-out snapshot', () => {
|
|
for (const githubRef of [undefined, 'refs/heads/feature', 'refs/tags/v12.8.2']) {
|
|
assert.throws(() => prepareDocsSync({ githubRef }), /must run from main/)
|
|
}
|
|
assert.throws(() => prepareDocsSync({
|
|
githubRef: 'refs/heads/main', docsRef: 'a'.repeat(40),
|
|
}), /docs_commit requires a release_tag/)
|
|
})
|
|
|
|
test('a release event only dispatches the sync from the default branch', () => {
|
|
const workflow = readFileSync(new URL('../workflows/sync-docs.yml', import.meta.url), 'utf8')
|
|
const dispatch = workflow.split('\n dispatch:\n')[1].split('\n sync:\n')[0]
|
|
assert.doesNotMatch(dispatch, /environment:|secrets\./)
|
|
assert.match(dispatch, /--ref "\$DEFAULT_BRANCH"/)
|
|
assert.match(workflow, /\n sync:\n if: github\.event_name == 'workflow_dispatch'\n/)
|
|
})
|