Files
przeprogramowani__10x-cli/tests/smoke/package.test.ts
“mkczarkowski” 261d084165 fix(smoke): skip npm pack test on Windows — hangs on CI runners
npm pack --dry-run --json consistently exceeds 30s on windows-latest
runners. Since package contents are platform-independent, this test
only needs to run on Ubuntu (check job).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 15:50:03 +02:00

143 lines
4.5 KiB
TypeScript

/**
* Smoke tests for the npm package tarball.
*
* Verifies the published package contains the right files, excludes
* sensitive content, and targets the correct registry.
*/
import { describe, it, expect } from "bun:test";
import { execSync } from "node:child_process";
import { readFileSync, writeFileSync, copyFileSync, appendFileSync, mkdtempSync, mkdirSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
const ROOT = resolve(import.meta.dir, "../..");
describe("npm pack contents", () => {
it.skipIf(process.platform === "win32")("includes required files and excludes dev artifacts", () => {
const output = execSync("npm pack --dry-run --json", {
cwd: ROOT,
encoding: "utf8",
stdio: ["pipe", "pipe", "pipe"],
});
const [pack] = JSON.parse(output);
const filePaths = pack.files.map(
(f: { path: string }) => f.path,
) as string[];
// Must include
expect(filePaths.some((f: string) => f.startsWith("dist/"))).toBe(true);
expect(filePaths).toContain("package.json");
expect(filePaths).toContain("README.md");
// Must NOT include
const forbidden = ["src/", "test/", "tests/", ".env", "node_modules/"];
for (const prefix of forbidden) {
const leaked = filePaths.filter((f: string) => f.startsWith(prefix));
expect(leaked).toEqual([]);
}
// No secret-like files
const secrets = filePaths.filter((f: string) =>
/secret/i.test(f),
);
expect(secrets).toEqual([]);
}, 30_000);
});
describe("registry target", () => {
it(".npmrc resolves to registry.npmjs.org, not GitHub Packages", () => {
const npmrc = readFileSync(resolve(ROOT, ".npmrc"), "utf8");
expect(npmrc).toContain("registry=https://registry.npmjs.org/");
expect(npmrc).not.toContain("npm.pkg.github.com");
});
});
describe("auto-version script", () => {
/**
* Helper: creates a temp git repo, runs auto-version.mjs, returns
* { stdout, stderr, exitCode, packageJson }.
*/
function runAutoVersion(commits: string[]): {
stdout: string;
stderr: string;
exitCode: number;
packageJson: string;
} {
const tmpDir = mkdtempSync(join(tmpdir(), "10x-autoversion-"));
try {
// Write files via Node.js to avoid shell quoting issues on Windows.
writeFileSync(join(tmpDir, "package.json"), '{"version":"1.0.0"}');
mkdirSync(join(tmpDir, "src"), { recursive: true });
writeFileSync(join(tmpDir, "src/index.ts"), "// placeholder\n");
// Initialize repo with a v1.0.0 tag.
execSync(
[
"git init -q",
'git config user.name "test"',
'git config user.email "test@test.com"',
"git add -A",
'git commit -m "initial" -q',
"git tag v1.0.0",
].join(" && "),
{ cwd: tmpDir, stdio: "pipe" },
);
// Add commits that touch src/ so the git-diff release gate fires.
for (const msg of commits) {
appendFileSync(join(tmpDir, "src/index.ts"), "// change\n");
execSync(`git add -A && git commit -m "${msg}" -q`, {
cwd: tmpDir,
stdio: "pipe",
});
}
copyFileSync(
join(ROOT, "scripts/auto-version.mjs"),
join(tmpDir, "auto-version.mjs"),
);
const homeEnv = process.platform === "win32"
? { USERPROFILE: tmpDir }
: { HOME: tmpDir };
const proc = Bun.spawnSync(["bun", "auto-version.mjs"], {
cwd: tmpDir,
stdout: "pipe",
stderr: "pipe",
env: { ...process.env, ...homeEnv, NODE_PATH: `${ROOT}/node_modules` },
});
const pkgContent = (() => {
try {
return readFileSync(`${tmpDir}/package.json`, "utf8");
} catch {
return "";
}
})();
return {
stdout: proc.stdout.toString(),
stderr: proc.stderr.toString(),
exitCode: proc.exitCode,
packageJson: pkgContent,
};
} finally {
rmSync(tmpDir, { recursive: true, force: true });
}
}
it("exits with code 1 when no releasable commits exist", () => {
const result = runAutoVersion(["chore(release): v1.0.0"]);
expect(result.exitCode).toBe(1);
expect(result.stderr).toContain("No version bump needed");
});
it("bumps minor for feat: commits", () => {
const result = runAutoVersion(["feat: add new command"]);
expect(result.exitCode).toBe(0);
expect(result.packageJson).toContain('"version": "1.1.0"');
expect(result.stdout).toContain("NEW_VERSION=v1.1.0");
});
});