|
1 | | -import { describe, test, expect, beforeAll } from "bun:test"; |
| 1 | +import { describe, test, expect, beforeAll, afterAll } from "bun:test"; |
2 | 2 | import { resolve } from "path"; |
| 3 | +import * as fs from "fs"; |
| 4 | +import * as os from "os"; |
3 | 5 |
|
4 | 6 | // Import from source directly since we're using Bun |
5 | 7 | import * as init from "../lib/init"; |
@@ -415,3 +417,111 @@ describe("CLI commands", () => { |
415 | 417 | expect(r.stderr).toMatch(/Cannot use --api-key with --demo mode/); |
416 | 418 | }); |
417 | 419 | }); |
| 420 | + |
| 421 | +describe("imageTag priority behavior", () => { |
| 422 | + // Tests for the imageTag priority: --tag flag > PGAI_TAG env var > pkg.version |
| 423 | + // This verifies the fix that prevents stale .env PGAI_TAG from being used |
| 424 | + |
| 425 | + let tempDir: string; |
| 426 | + |
| 427 | + beforeAll(() => { |
| 428 | + tempDir = fs.mkdtempSync(resolve(os.tmpdir(), "pgai-test-")); |
| 429 | + }); |
| 430 | + |
| 431 | + afterAll(() => { |
| 432 | + if (tempDir && fs.existsSync(tempDir)) { |
| 433 | + fs.rmSync(tempDir, { recursive: true, force: true }); |
| 434 | + } |
| 435 | + }); |
| 436 | + |
| 437 | + test("stale .env PGAI_TAG is NOT used - CLI version takes precedence", () => { |
| 438 | + // Create a stale .env with an old tag value |
| 439 | + const testDir = resolve(tempDir, "stale-tag-test"); |
| 440 | + fs.mkdirSync(testDir, { recursive: true }); |
| 441 | + fs.writeFileSync(resolve(testDir, ".env"), "PGAI_TAG=beta\n"); |
| 442 | + // Create minimal docker-compose.yml so resolvePaths() finds it |
| 443 | + fs.writeFileSync(resolve(testDir, "docker-compose.yml"), "version: '3'\nservices: {}\n"); |
| 444 | + |
| 445 | + // Run from the test directory (so resolvePaths finds docker-compose.yml) |
| 446 | + const cliPath = resolve(import.meta.dir, "..", "bin", "postgres-ai.ts"); |
| 447 | + const bunBin = typeof process.execPath === "string" && process.execPath.length > 0 ? process.execPath : "bun"; |
| 448 | + const result = Bun.spawnSync([bunBin, cliPath, "mon", "local-install", "--db-url", "postgresql://u:p@h:5432/d", "--yes"], { |
| 449 | + env: { ...process.env, PGAI_TAG: undefined }, |
| 450 | + cwd: testDir, |
| 451 | + }); |
| 452 | + |
| 453 | + // Read the .env that was written |
| 454 | + const envContent = fs.readFileSync(resolve(testDir, ".env"), "utf8"); |
| 455 | + |
| 456 | + // The .env should NOT contain the stale "beta" tag - it should use pkg.version |
| 457 | + expect(envContent).not.toMatch(/PGAI_TAG=beta/); |
| 458 | + // It should contain the CLI version (0.0.0-dev.0 in dev) |
| 459 | + expect(envContent).toMatch(/PGAI_TAG=\d+\.\d+\.\d+|PGAI_TAG=0\.0\.0-dev/); |
| 460 | + }); |
| 461 | + |
| 462 | + test("--tag flag takes priority over pkg.version", () => { |
| 463 | + const testDir = resolve(tempDir, "tag-flag-test"); |
| 464 | + fs.mkdirSync(testDir, { recursive: true }); |
| 465 | + fs.writeFileSync(resolve(testDir, "docker-compose.yml"), "version: '3'\nservices: {}\n"); |
| 466 | + |
| 467 | + const cliPath = resolve(import.meta.dir, "..", "bin", "postgres-ai.ts"); |
| 468 | + const bunBin = typeof process.execPath === "string" && process.execPath.length > 0 ? process.execPath : "bun"; |
| 469 | + const result = Bun.spawnSync([bunBin, cliPath, "mon", "local-install", "--tag", "v1.2.3-custom", "--db-url", "postgresql://u:p@h:5432/d", "--yes"], { |
| 470 | + env: { ...process.env, PGAI_TAG: undefined }, |
| 471 | + cwd: testDir, |
| 472 | + }); |
| 473 | + |
| 474 | + const envContent = fs.readFileSync(resolve(testDir, ".env"), "utf8"); |
| 475 | + expect(envContent).toMatch(/PGAI_TAG=v1\.2\.3-custom/); |
| 476 | + |
| 477 | + // Verify stdout confirms the tag being used |
| 478 | + const stdout = new TextDecoder().decode(result.stdout); |
| 479 | + expect(stdout).toMatch(/Using image tag: v1\.2\.3-custom/); |
| 480 | + }); |
| 481 | + |
| 482 | + test("PGAI_TAG env var is intentionally ignored (Bun auto-loads .env)", () => { |
| 483 | + // Note: We do NOT use process.env.PGAI_TAG because Bun auto-loads .env files, |
| 484 | + // which would cause stale .env values to pollute the environment. |
| 485 | + // Users should use --tag flag to override, not env vars. |
| 486 | + const testDir = resolve(tempDir, "env-var-ignored-test"); |
| 487 | + fs.mkdirSync(testDir, { recursive: true }); |
| 488 | + fs.writeFileSync(resolve(testDir, "docker-compose.yml"), "version: '3'\nservices: {}\n"); |
| 489 | + |
| 490 | + const cliPath = resolve(import.meta.dir, "..", "bin", "postgres-ai.ts"); |
| 491 | + const bunBin = typeof process.execPath === "string" && process.execPath.length > 0 ? process.execPath : "bun"; |
| 492 | + const result = Bun.spawnSync([bunBin, cliPath, "mon", "local-install", "--db-url", "postgresql://u:p@h:5432/d", "--yes"], { |
| 493 | + env: { ...process.env, PGAI_TAG: "v2.0.0-from-env" }, |
| 494 | + cwd: testDir, |
| 495 | + }); |
| 496 | + |
| 497 | + const envContent = fs.readFileSync(resolve(testDir, ".env"), "utf8"); |
| 498 | + // PGAI_TAG env var should be IGNORED - uses pkg.version instead |
| 499 | + expect(envContent).not.toMatch(/PGAI_TAG=v2\.0\.0-from-env/); |
| 500 | + expect(envContent).toMatch(/PGAI_TAG=\d+\.\d+\.\d+|PGAI_TAG=0\.0\.0-dev/); |
| 501 | + }); |
| 502 | + |
| 503 | + test("existing registry and password are preserved while tag is updated", () => { |
| 504 | + const testDir = resolve(tempDir, "preserve-test"); |
| 505 | + fs.mkdirSync(testDir, { recursive: true }); |
| 506 | + // Create .env with stale tag but valid registry and password |
| 507 | + fs.writeFileSync(resolve(testDir, ".env"), |
| 508 | + "PGAI_TAG=stale-tag\nPGAI_REGISTRY=my.registry.com\nGF_SECURITY_ADMIN_PASSWORD=secret123\n"); |
| 509 | + fs.writeFileSync(resolve(testDir, "docker-compose.yml"), "version: '3'\nservices: {}\n"); |
| 510 | + |
| 511 | + const cliPath = resolve(import.meta.dir, "..", "bin", "postgres-ai.ts"); |
| 512 | + const bunBin = typeof process.execPath === "string" && process.execPath.length > 0 ? process.execPath : "bun"; |
| 513 | + const result = Bun.spawnSync([bunBin, cliPath, "mon", "local-install", "--db-url", "postgresql://u:p@h:5432/d", "--yes"], { |
| 514 | + env: { ...process.env, PGAI_TAG: undefined }, |
| 515 | + cwd: testDir, |
| 516 | + }); |
| 517 | + |
| 518 | + const envContent = fs.readFileSync(resolve(testDir, ".env"), "utf8"); |
| 519 | + |
| 520 | + // Tag should be updated (not stale-tag) |
| 521 | + expect(envContent).not.toMatch(/PGAI_TAG=stale-tag/); |
| 522 | + |
| 523 | + // But registry and password should be preserved |
| 524 | + expect(envContent).toMatch(/PGAI_REGISTRY=my\.registry\.com/); |
| 525 | + expect(envContent).toMatch(/GF_SECURITY_ADMIN_PASSWORD=secret123/); |
| 526 | + }); |
| 527 | +}); |
0 commit comments