mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-09-09 04:02:35 +00:00
Merge pull request #2905 from deepseek-harness/turtle/local-build-banner-version
Show build version in local Web banner
This commit is contained in:
+6
-7
@@ -6,8 +6,9 @@ import { resolve } from 'node:path'
|
||||
import { parseArgs } from 'node:util'
|
||||
import {
|
||||
CLIENT_BUILD_RECORD_PATH,
|
||||
CLIENT_BUILD_PROFILE_SELECTOR,
|
||||
clientBuildProcessEnvironment,
|
||||
repositoryCommitHash,
|
||||
repositoryClientBuildEnvironment,
|
||||
resolveClientBuildEnvironment,
|
||||
writeClientBuildRecord,
|
||||
} from './client-build-environment.ts'
|
||||
@@ -34,12 +35,10 @@ function main(): void {
|
||||
allowPositionals: false,
|
||||
})
|
||||
const root = resolve(import.meta.dirname, '..')
|
||||
const parentEnvironment = {
|
||||
...process.env,
|
||||
DSH_CLIENT_COMMIT_HASH: repositoryCommitHash(root, process.env),
|
||||
}
|
||||
const clientEnvironment = resolveClientBuildEnvironment(parentEnvironment, values.profile)
|
||||
const buildEnvironment = clientBuildProcessEnvironment(parentEnvironment, clientEnvironment)
|
||||
const repositoryEnvironment = repositoryClientBuildEnvironment(root, process.env)
|
||||
const profile = values.profile ?? process.env[CLIENT_BUILD_PROFILE_SELECTOR]
|
||||
const clientEnvironment = resolveClientBuildEnvironment(repositoryEnvironment, profile)
|
||||
const buildEnvironment = clientBuildProcessEnvironment(process.env, clientEnvironment)
|
||||
|
||||
rmSync(resolve(root, CLIENT_BUILD_RECORD_PATH), { force: true })
|
||||
runScript('build:lib', buildEnvironment)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { execFileSync } from 'node:child_process'
|
||||
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { dirname, join, resolve } from 'node:path'
|
||||
@@ -7,8 +8,12 @@ import {
|
||||
assertClientBuildEnvironment,
|
||||
clientBuildEnvironmentDefines,
|
||||
clientBuildProcessEnvironment,
|
||||
officialClientBuildEnvironment,
|
||||
readClientBuildRecord,
|
||||
repositoryClientBuildEnvironment,
|
||||
repositoryCommitHash,
|
||||
repositoryGitDirty,
|
||||
repositoryVersion,
|
||||
resolveClientBuildEnvironment,
|
||||
writeClientBuildRecord,
|
||||
} from './client-build-environment.ts'
|
||||
@@ -51,12 +56,34 @@ function buildFixture(environment: Record<string, string>): string {
|
||||
return fixtureRoot
|
||||
}
|
||||
|
||||
function git(root: string, args: readonly string[]): string {
|
||||
return execFileSync('git', [...args], {
|
||||
cwd: root,
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
}).trim()
|
||||
}
|
||||
|
||||
function repositoryFixture(version = '1.2.3-rc.4'): string {
|
||||
const fixtureRoot = mkdtempSync(join(tmpdir(), 'dsh-client-build-repository-'))
|
||||
roots.push(fixtureRoot)
|
||||
write(join(fixtureRoot, 'package.json'), `${JSON.stringify({ version })}\n`)
|
||||
write(join(fixtureRoot, 'tracked.txt'), 'committed\n')
|
||||
git(fixtureRoot, ['init'])
|
||||
git(fixtureRoot, ['config', 'user.name', 'DSH test'])
|
||||
git(fixtureRoot, ['config', 'user.email', 'dsh-test@example.invalid'])
|
||||
git(fixtureRoot, ['add', 'package.json', 'tracked.txt'])
|
||||
git(fixtureRoot, ['commit', '-m', 'fixture'])
|
||||
return fixtureRoot
|
||||
}
|
||||
|
||||
describe('client build environment', () => {
|
||||
it('requires an exact public environment for a named artifact profile', () => {
|
||||
const expected = {
|
||||
DSH_CLIENT_BUILD_PROFILE: 'official',
|
||||
DSH_CLIENT_COMMIT_HASH: COMMIT_HASH.slice(0, 7),
|
||||
DSH_CLIENT_TITLE: 'DeepSeek Harness',
|
||||
DSH_CLIENT_VERSION: '1.2.3',
|
||||
} as const
|
||||
|
||||
expect(() => { assertClientBuildEnvironment({ PATH: '/bin', ...expected }, expected) }).not.toThrow()
|
||||
@@ -73,7 +100,9 @@ describe('client build environment', () => {
|
||||
DSH_BUILD_CLIENT_PROFILE: 'official',
|
||||
DSH_CLIENT_BUILD_PROFILE: 'local',
|
||||
DSH_CLIENT_COMMIT_HASH: COMMIT_HASH.slice(0, 7),
|
||||
DSH_CLIENT_GIT_DIRTY: 'true',
|
||||
DSH_CLIENT_TITLE: 'Local title',
|
||||
DSH_CLIENT_VERSION: '1.2.3',
|
||||
DSH_CLIENT_EXTRA: 'local-extra',
|
||||
}
|
||||
|
||||
@@ -84,24 +113,108 @@ describe('client build environment', () => {
|
||||
DSH_CLIENT_BUILD_PROFILE: 'official',
|
||||
DSH_CLIENT_COMMIT_HASH: COMMIT_HASH.slice(0, 7),
|
||||
DSH_CLIENT_TITLE: 'DeepSeek Harness',
|
||||
DSH_CLIENT_VERSION: '1.2.3',
|
||||
})
|
||||
expect(() => {
|
||||
resolveClientBuildEnvironment({ DSH_BUILD_CLIENT_PROFILE: 'official' })
|
||||
}).toThrow(/DSH_CLIENT_COMMIT_HASH/)
|
||||
expect(() => {
|
||||
resolveClientBuildEnvironment({
|
||||
DSH_BUILD_CLIENT_PROFILE: 'official',
|
||||
DSH_CLIENT_COMMIT_HASH: COMMIT_HASH.slice(0, 7),
|
||||
})
|
||||
}).toThrow(/DSH_CLIENT_VERSION/)
|
||||
expect(() => { resolveClientBuildEnvironment({}, 'unknown') }).toThrow(/unknown client build profile/)
|
||||
expect(clientBuildProcessEnvironment(parent, {
|
||||
DSH_CLIENT_BUILD_PROFILE: 'official',
|
||||
DSH_CLIENT_COMMIT_HASH: COMMIT_HASH.slice(0, 7),
|
||||
DSH_CLIENT_TITLE: 'DeepSeek Harness',
|
||||
DSH_CLIENT_VERSION: '1.2.3',
|
||||
})).toEqual({
|
||||
PATH: '/bin',
|
||||
DSH_CLIENT_BUILD_PROFILE: 'official',
|
||||
DSH_CLIENT_COMMIT_HASH: COMMIT_HASH.slice(0, 7),
|
||||
DSH_CLIENT_TITLE: 'DeepSeek Harness',
|
||||
DSH_CLIENT_VERSION: '1.2.3',
|
||||
})
|
||||
expect(repositoryCommitHash('/unused', { DSH_CLIENT_COMMIT_HASH: COMMIT_HASH })).toBe(COMMIT_HASH.slice(0, 7))
|
||||
})
|
||||
|
||||
it('owns repository version, commit, and dirty metadata for complete builds', () => {
|
||||
const fixtureRoot = repositoryFixture()
|
||||
const commit = git(fixtureRoot, ['rev-parse', '--short=7', 'HEAD'])
|
||||
|
||||
expect(repositoryVersion(fixtureRoot)).toBe('1.2.3-rc.4')
|
||||
expect(repositoryGitDirty(fixtureRoot)).toBe(false)
|
||||
expect(repositoryClientBuildEnvironment(fixtureRoot, {
|
||||
DSH_CLIENT_COMMIT_HASH: COMMIT_HASH,
|
||||
DSH_CLIENT_EXTRA: 'preserved',
|
||||
DSH_CLIENT_GIT_DIRTY: 'true',
|
||||
DSH_CLIENT_VERSION: 'spoofed',
|
||||
})).toEqual({
|
||||
DSH_CLIENT_COMMIT_HASH: COMMIT_HASH.slice(0, 7),
|
||||
DSH_CLIENT_EXTRA: 'preserved',
|
||||
DSH_CLIENT_VERSION: '1.2.3-rc.4',
|
||||
})
|
||||
expect(officialClientBuildEnvironment(fixtureRoot)).toEqual({
|
||||
DSH_CLIENT_BUILD_PROFILE: 'official',
|
||||
DSH_CLIENT_COMMIT_HASH: commit,
|
||||
DSH_CLIENT_TITLE: 'DeepSeek Harness',
|
||||
DSH_CLIENT_VERSION: '1.2.3-rc.4',
|
||||
})
|
||||
|
||||
write(join(fixtureRoot, '.gitignore'), 'ignored.txt\n')
|
||||
git(fixtureRoot, ['add', '.gitignore'])
|
||||
git(fixtureRoot, ['commit', '-m', 'ignore fixture'])
|
||||
write(join(fixtureRoot, 'ignored.txt'), 'ignored\n')
|
||||
expect(repositoryGitDirty(fixtureRoot)).toBe(false)
|
||||
rmSync(join(fixtureRoot, 'ignored.txt'))
|
||||
|
||||
write(join(fixtureRoot, 'tracked.txt'), 'unstaged\n')
|
||||
expect(repositoryGitDirty(fixtureRoot)).toBe(true)
|
||||
write(join(fixtureRoot, 'tracked.txt'), 'committed\n')
|
||||
expect(repositoryGitDirty(fixtureRoot)).toBe(false)
|
||||
|
||||
write(join(fixtureRoot, 'tracked.txt'), 'staged\n')
|
||||
git(fixtureRoot, ['add', 'tracked.txt'])
|
||||
expect(repositoryGitDirty(fixtureRoot)).toBe(true)
|
||||
git(fixtureRoot, ['commit', '-m', 'staged fixture'])
|
||||
expect(repositoryGitDirty(fixtureRoot)).toBe(false)
|
||||
|
||||
write(join(fixtureRoot, 'untracked.txt'), 'untracked\n')
|
||||
expect(repositoryGitDirty(fixtureRoot)).toBe(true)
|
||||
expect(repositoryClientBuildEnvironment(fixtureRoot, {
|
||||
DSH_CLIENT_COMMIT_HASH: COMMIT_HASH,
|
||||
})).toEqual({
|
||||
DSH_CLIENT_COMMIT_HASH: COMMIT_HASH.slice(0, 7),
|
||||
DSH_CLIENT_GIT_DIRTY: 'true',
|
||||
DSH_CLIENT_VERSION: '1.2.3-rc.4',
|
||||
})
|
||||
|
||||
rmSync(join(fixtureRoot, 'untracked.txt'))
|
||||
const submoduleSource = repositoryFixture('9.8.7')
|
||||
git(fixtureRoot, ['-c', 'protocol.file.allow=always', 'submodule', 'add', submoduleSource, 'submodule'])
|
||||
git(fixtureRoot, ['commit', '-am', 'submodule fixture'])
|
||||
expect(repositoryGitDirty(fixtureRoot)).toBe(false)
|
||||
write(join(fixtureRoot, 'submodule/tracked.txt'), 'modified submodule\n')
|
||||
expect(repositoryGitDirty(fixtureRoot)).toBe(true)
|
||||
})
|
||||
|
||||
it('omits dirty metadata when repository metadata is unavailable', () => {
|
||||
const fixtureRoot = mkdtempSync(join(tmpdir(), 'dsh-client-build-no-git-'))
|
||||
roots.push(fixtureRoot)
|
||||
write(join(fixtureRoot, 'package.json'), '{"version":"2.0.0"}\n')
|
||||
|
||||
expect(repositoryGitDirty(fixtureRoot)).toBeUndefined()
|
||||
expect(repositoryClientBuildEnvironment(fixtureRoot, {
|
||||
DSH_CLIENT_COMMIT_HASH: COMMIT_HASH,
|
||||
DSH_CLIENT_GIT_DIRTY: 'true',
|
||||
})).toEqual({
|
||||
DSH_CLIENT_COMMIT_HASH: COMMIT_HASH.slice(0, 7),
|
||||
DSH_CLIENT_VERSION: '2.0.0',
|
||||
})
|
||||
})
|
||||
|
||||
it('defines only public client values over a non-enumerable fallback', () => {
|
||||
expect(clientBuildEnvironmentDefines({
|
||||
PATH: '/bin',
|
||||
@@ -151,6 +264,7 @@ describe('client build environment', () => {
|
||||
DSH_CLIENT_BUILD_PROFILE: 'official',
|
||||
DSH_CLIENT_COMMIT_HASH: COMMIT_HASH.slice(0, 7),
|
||||
DSH_CLIENT_TITLE: 'DeepSeek Harness',
|
||||
DSH_CLIENT_VERSION: '1.2.3',
|
||||
}
|
||||
const official = buildFixture(officialEnvironment)
|
||||
const defaultBuild = buildFixture({})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createHash } from 'node:crypto'
|
||||
import { execFileSync } from 'node:child_process'
|
||||
import { execFileSync, spawnSync } from 'node:child_process'
|
||||
import {
|
||||
existsSync,
|
||||
globSync,
|
||||
@@ -25,6 +25,9 @@ const OFFICIAL_CLIENT_BUILD_ENVIRONMENT = {
|
||||
/** Public variable carrying the source commit embedded in client artifacts. */
|
||||
const CLIENT_COMMIT_HASH_VARIABLE = 'DSH_CLIENT_COMMIT_HASH'
|
||||
|
||||
/** Public variable carrying the repository package version embedded in client artifacts. */
|
||||
const CLIENT_VERSION_VARIABLE = 'DSH_CLIENT_VERSION'
|
||||
|
||||
/** Repository-relative path of the complete client build record. */
|
||||
export const CLIENT_BUILD_RECORD_PATH = '.dsh-build/client-build-environment.json'
|
||||
|
||||
@@ -57,6 +60,76 @@ export function repositoryCommitHash(root: string, environment: NodeJS.ProcessEn
|
||||
return value.slice(0, 7).toLowerCase()
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the repository package version used by browser build metadata.
|
||||
* @param root - repository root containing the authoritative package.json.
|
||||
* @returns the repository's semver-compatible package version.
|
||||
*/
|
||||
export function repositoryVersion(root: string): string {
|
||||
const path = resolve(root, 'package.json')
|
||||
let manifest: unknown
|
||||
try {
|
||||
manifest = JSON.parse(readFileSync(path, 'utf8'))
|
||||
} catch (error) {
|
||||
const detail = error instanceof Error ? error.message : String(error)
|
||||
throw new Error(`cannot read repository version from ${path}: ${detail}`)
|
||||
}
|
||||
if (!isObject(manifest) || typeof manifest.version !== 'string'
|
||||
|| !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(manifest.version)) {
|
||||
throw new Error(`repository package.json has an invalid version ${JSON.stringify(isObject(manifest) ? manifest.version : undefined)}`)
|
||||
}
|
||||
return manifest.version
|
||||
}
|
||||
|
||||
/**
|
||||
* Read whether Git reports any staged, unstaged, untracked, or submodule change.
|
||||
* @param root - repository root whose worktree is inspected.
|
||||
* @returns true or false inside a Git worktree; undefined without Git metadata.
|
||||
*/
|
||||
export function repositoryGitDirty(root: string): boolean | undefined {
|
||||
const probe = spawnSync('git', ['rev-parse', '--is-inside-work-tree'], {
|
||||
cwd: root,
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'ignore'],
|
||||
})
|
||||
if (probe.error !== undefined || probe.status !== 0 || probe.stdout.trim() !== 'true') return undefined
|
||||
|
||||
const status = spawnSync('git', ['status', '--porcelain=v1', '--untracked-files=normal'], {
|
||||
cwd: root,
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
})
|
||||
if (status.error !== undefined) throw status.error
|
||||
if (status.status !== 0) {
|
||||
throw new Error(`git status failed in ${root}: ${status.stderr.trim() || String(status.status)}`)
|
||||
}
|
||||
return status.stdout !== ''
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the public environment for a complete default build from one checkout.
|
||||
* Repository-owned metadata replaces inherited values; other public values pass through.
|
||||
* @param root - repository root supplying version and Git metadata.
|
||||
* @param environment - caller environment supplying optional commit and public extensions.
|
||||
* @returns complete public client environment for the default build.
|
||||
*/
|
||||
export function repositoryClientBuildEnvironment(
|
||||
root: string,
|
||||
environment: NodeJS.ProcessEnv = process.env,
|
||||
): ClientBuildEnvironment {
|
||||
const inherited = { ...clientBuildEnvironment(environment) }
|
||||
delete inherited.DSH_CLIENT_COMMIT_HASH
|
||||
delete inherited.DSH_CLIENT_GIT_DIRTY
|
||||
delete inherited.DSH_CLIENT_VERSION
|
||||
const dirty = repositoryGitDirty(root)
|
||||
return {
|
||||
...inherited,
|
||||
DSH_CLIENT_COMMIT_HASH: repositoryCommitHash(root, environment),
|
||||
...(dirty === true ? { DSH_CLIENT_GIT_DIRTY: 'true' } : {}),
|
||||
DSH_CLIENT_VERSION: repositoryVersion(root),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the exact public values required by an official build at one commit.
|
||||
* @param root - repository root whose HEAD must match the built source.
|
||||
@@ -69,6 +142,7 @@ export function officialClientBuildEnvironment(
|
||||
): Readonly<Record<`DSH_CLIENT_${string}`, string>> {
|
||||
return {
|
||||
DSH_CLIENT_COMMIT_HASH: repositoryCommitHash(root, environment),
|
||||
DSH_CLIENT_VERSION: repositoryVersion(root),
|
||||
...OFFICIAL_CLIENT_BUILD_ENVIRONMENT,
|
||||
}
|
||||
}
|
||||
@@ -115,10 +189,18 @@ export function resolveClientBuildEnvironment(
|
||||
if (profile === undefined) return clientBuildEnvironment(environment)
|
||||
if (profile === 'official') {
|
||||
const commitHash = environment[CLIENT_COMMIT_HASH_VARIABLE]
|
||||
const version = environment[CLIENT_VERSION_VARIABLE]
|
||||
if (commitHash === undefined) {
|
||||
throw new Error(`${CLIENT_COMMIT_HASH_VARIABLE} is required for the official client build profile`)
|
||||
}
|
||||
return { DSH_CLIENT_COMMIT_HASH: commitHash, ...OFFICIAL_CLIENT_BUILD_ENVIRONMENT }
|
||||
if (version === undefined) {
|
||||
throw new Error(`${CLIENT_VERSION_VARIABLE} is required for the official client build profile`)
|
||||
}
|
||||
return {
|
||||
DSH_CLIENT_COMMIT_HASH: commitHash,
|
||||
DSH_CLIENT_VERSION: version,
|
||||
...OFFICIAL_CLIENT_BUILD_ENVIRONMENT,
|
||||
}
|
||||
}
|
||||
throw new Error(`unknown client build profile ${JSON.stringify(profile)}; expected "official"`)
|
||||
}
|
||||
|
||||
+39
-1
@@ -3,7 +3,45 @@ import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { expect, it } from 'vitest'
|
||||
import type { TsdownBundle } from 'tsdown'
|
||||
import { discoverLibraryDirs, discoverPluginDirs, watchClientPlugins } from './dev-web.ts'
|
||||
import { writeClientBuildRecord } from './client-build-environment.ts'
|
||||
import {
|
||||
devWebBuildEnvironment,
|
||||
discoverLibraryDirs,
|
||||
discoverPluginDirs,
|
||||
watchClientPlugins,
|
||||
} from './dev-web.ts'
|
||||
|
||||
it('samples one local environment at startup without validating watcher outputs', async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), 'dsh-dev-web-environment-'))
|
||||
try {
|
||||
await mkdir(join(root, 'apps/web/dist'), { recursive: true })
|
||||
await mkdir(join(root, 'packages/client/example/lib'), { recursive: true })
|
||||
await writeFile(join(root, 'package.json'), JSON.stringify({ version: '1.2.3' }))
|
||||
await writeFile(join(root, 'apps/web/dist/index.html'), '<main></main>')
|
||||
await writeFile(join(root, 'packages/client/example/lib/client.js'), 'module.exports = {}\n')
|
||||
writeClientBuildRecord(root, {
|
||||
DSH_CLIENT_BUILD_PROFILE: 'official',
|
||||
DSH_CLIENT_COMMIT_HASH: 'fffffff',
|
||||
DSH_CLIENT_TITLE: 'DeepSeek Harness',
|
||||
DSH_CLIENT_VERSION: '1.2.2',
|
||||
})
|
||||
await writeFile(join(root, 'packages/client/example/lib/client.js'), 'module.exports = { changed: true }\n')
|
||||
|
||||
expect(devWebBuildEnvironment(root, {
|
||||
PATH: '/bin',
|
||||
DSH_BUILD_CLIENT_PROFILE: 'official',
|
||||
DSH_CLIENT_COMMIT_HASH: 'abc1234',
|
||||
DSH_CLIENT_EXTRA: 'launch-value',
|
||||
})).toEqual({
|
||||
PATH: '/bin',
|
||||
DSH_CLIENT_COMMIT_HASH: 'abc1234',
|
||||
DSH_CLIENT_EXTRA: 'launch-value',
|
||||
DSH_CLIENT_VERSION: '1.2.3',
|
||||
})
|
||||
} finally {
|
||||
await rm(root, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
||||
it('discovers dsh.client packages with sibling roles', async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), 'dsh-dev-web-discovery-'))
|
||||
|
||||
@@ -34,6 +34,11 @@ import { fileURLToPath, pathToFileURL } from 'node:url'
|
||||
import { execa } from 'execa'
|
||||
import { build } from 'tsdown'
|
||||
import type { TsdownBundle } from 'tsdown'
|
||||
import {
|
||||
CLIENT_BUILD_PROFILE_SELECTOR,
|
||||
clientBuildProcessEnvironment,
|
||||
repositoryClientBuildEnvironment,
|
||||
} from './client-build-environment.ts'
|
||||
|
||||
const repoRoot = fileURLToPath(new URL('..', import.meta.url))
|
||||
|
||||
@@ -49,6 +54,19 @@ const SHELL_PACKAGE = '@deepseek-ai/dsh-web-frontend'
|
||||
*/
|
||||
const TEST_INFRASTRUCTURE_PREFIX = 'packages/test-support/'
|
||||
|
||||
/**
|
||||
* Sample one local public environment for every long-lived watcher stage.
|
||||
* @param root - repository root supplying version and Git metadata.
|
||||
* @param environment - watcher launch environment supplying public extensions.
|
||||
* @returns process environment shared by tsdown and spawned watcher stages.
|
||||
*/
|
||||
export function devWebBuildEnvironment(
|
||||
root: string,
|
||||
environment: NodeJS.ProcessEnv = process.env,
|
||||
): NodeJS.ProcessEnv {
|
||||
return clientBuildProcessEnvironment(environment, repositoryClientBuildEnvironment(root, environment))
|
||||
}
|
||||
|
||||
/**
|
||||
* Discover the watch workspace by declaration: every packages/<group>/<name>
|
||||
* whose package.json carries `dsh.client` with platform "web" is a client
|
||||
@@ -175,6 +193,16 @@ interface StageHandle {
|
||||
const invokedPath = process.argv[1]
|
||||
const isMain = invokedPath !== undefined && import.meta.url === pathToFileURL(resolve(invokedPath)).href
|
||||
if (isMain) {
|
||||
const buildEnvironment = devWebBuildEnvironment(repoRoot, process.env)
|
||||
for (const name of Object.keys(process.env)) {
|
||||
if (name === CLIENT_BUILD_PROFILE_SELECTOR || name.startsWith('DSH_CLIENT_')) {
|
||||
Reflect.deleteProperty(process.env, name)
|
||||
}
|
||||
}
|
||||
for (const [name, value] of Object.entries(buildEnvironment)) {
|
||||
if (name.startsWith('DSH_CLIENT_') && value !== undefined) process.env[name] = value
|
||||
}
|
||||
|
||||
const pluginDirs = discoverPluginDirs()
|
||||
const libraryDirs = discoverLibraryDirs()
|
||||
if (pluginDirs.length === 0) {
|
||||
|
||||
@@ -29,6 +29,7 @@ function write(path: string, content: string): void {
|
||||
function buildFixture(environment: Record<string, string>): string {
|
||||
const root = mkdtempSync(join(tmpdir(), 'dsh-release-build-'))
|
||||
roots.push(root)
|
||||
write(join(root, 'package.json'), `${JSON.stringify({ version: environment.DSH_CLIENT_VERSION ?? '0.0.1' })}\n`)
|
||||
write(join(root, 'apps/web/dist/index.html'), '<main></main>')
|
||||
write(join(root, 'packages/client/example/lib/client.js'), 'module.exports = {}\n')
|
||||
writeClientBuildRecord(root, environment)
|
||||
@@ -106,11 +107,13 @@ describe('release families', () => {
|
||||
vi.stubEnv('DSH_CLIENT_COMMIT_HASH', officialEnvironment.DSH_CLIENT_COMMIT_HASH)
|
||||
const official = buildFixture(officialEnvironment)
|
||||
const defaultBuild = buildFixture({})
|
||||
const missing = join(defaultBuild, 'missing')
|
||||
write(join(missing, 'package.json'), `${JSON.stringify({ version: officialEnvironment.DSH_CLIENT_VERSION })}\n`)
|
||||
|
||||
expect(() => { dsh.verifyBuildArtifacts(official) }).not.toThrow()
|
||||
expect(() => { dsh.verifyBuildArtifacts(defaultBuild) }).toThrow(/DSH_CLIENT_TITLE/)
|
||||
expect(() => { dsh.verifyBuildArtifacts(join(defaultBuild, 'missing')) }).toThrow(/record.*missing/)
|
||||
expect(() => { vendor.verifyBuildArtifacts(join(defaultBuild, 'missing')) }).not.toThrow()
|
||||
expect(() => { dsh.verifyBuildArtifacts(missing) }).toThrow(/record.*missing/)
|
||||
expect(() => { vendor.verifyBuildArtifacts(missing) }).not.toThrow()
|
||||
|
||||
write(join(official, 'packages/client/example/lib/client.js'), 'module.exports = { changed: true }\n')
|
||||
expect(() => { dsh.verifyBuildArtifacts(official) }).toThrow(/artifacts differ/)
|
||||
|
||||
Reference in New Issue
Block a user