import { describe, it, expect } from '@jest/globals'; import { promises as fs } from 'node:fs'; import * as path from 'node:path'; import * as os from 'node:os'; import { prepareArtifactBuild, validateArtifactOutput } from './artifact-build-context'; describe('bounded artifact build context', () => { it.each(['../dist', '/tmp/output', '.', 'dist/../etc', 'dist\\etc', ''])('rejects unsafe output: %s', (value) => { expect(() => validateArtifactOutput(value)).toThrow(); }); it('keeps credentials out of the source and forces a fresh bounded build', async () => { const source = await fs.mkdtemp(path.join(os.tmpdir(), 'artifact-context-test-')); let root: string | undefined; try { for (const dir of ['.git', 'node_modules', 'dist']) { await fs.mkdir(path.join(source, dir)); await fs.writeFile(path.join(source, dir, 'private'), 'not-build-input'); } await fs.writeFile(path.join(source, 'package.json'), '{"name":"test"}'); const plan = await prepareArtifactBuild(source, 'dist', 'npm ci', 'npm run build:linux', [{ key: 'BUILD_TOKEN', value: 'private-token' }]); root = plan.root; expect(await fs.readdir(path.join(root, 'context/source'))).toEqual(['package.json']); const config = JSON.parse(await fs.readFile(path.join(root, 'config.json'), 'utf8')); expect(config.env).toEqual({ BUILD_TOKEN: 'private-token' }); expect((await fs.stat(path.join(root, 'config.json'))).mode & 0o777).toBe(0o600); expect(plan.args).toContain('--artifact-output'); expect(plan.args.join(' ')).not.toContain('private-token'); expect(plan.args.some((arg) => arg.startsWith('BUILD_REQUEST_ID='))).toBe(true); } finally { await fs.rm(source, { recursive: true, force: true }); if (root) await fs.rm(root, { recursive: true, force: true }); } }); });