From 39dc81546046e62ad3eba5b731ec97ccf8804f02 Mon Sep 17 00:00:00 2001 From: Copilot Date: Thu, 23 Apr 2026 09:08:24 +0300 Subject: [PATCH 1/3] test: fix .NET detection tests to use upgrade instead of init Same fix as PR #1030 on dev. Changes 3 tests in Group 6 from init-only to init+upgrade pattern, matching the behavior change from PR #847. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- test/migrate-directory.test.cjs | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/test/migrate-directory.test.cjs b/test/migrate-directory.test.cjs index 795e32726..b41995a81 100644 --- a/test/migrate-directory.test.cjs +++ b/test/migrate-directory.test.cjs @@ -249,13 +249,17 @@ describe('detectProjectType: .NET extensions (.slnx, .fsproj, .vbproj)', () => { beforeEach(() => { tmpDir = makeTempDir(); }); afterEach(() => cleanDir(tmpDir)); - it('init in a dir with .slnx generates a dotnet stub CI workflow', () => { + it('upgrade in a dir with .slnx generates a dotnet stub CI workflow', () => { fs.writeFileSync(path.join(tmpDir, 'MyApp.slnx'), ''); - const result = runSquad([], tmpDir); - assert.equal(result.exitCode, 0, `init should succeed: ${result.stdout}`); + // init creates .squad/ structure but skips CI workflows (by design since PR #847) + const initResult = runSquad([], tmpDir); + assert.equal(initResult.exitCode, 0, `init should succeed: ${initResult.stdout}`); + // upgrade installs CI/CD workflows including project-type-specific ones + const result = runSquad(['upgrade'], tmpDir); + assert.equal(result.exitCode, 0, `upgrade should succeed: ${result.stdout}`); const ciPath = path.join(tmpDir, '.github', 'workflows', 'squad-ci.yml'); - assert.ok(fs.existsSync(ciPath), 'squad-ci.yml should be created'); + assert.ok(fs.existsSync(ciPath), 'squad-ci.yml should be created by upgrade'); const ciContent = fs.readFileSync(ciPath, 'utf8'); assert.ok( ciContent.includes('dotnet') || ciContent.toLowerCase().includes('dotnet'), @@ -268,10 +272,12 @@ describe('detectProjectType: .NET extensions (.slnx, .fsproj, .vbproj)', () => { ); }); - it('init in a dir with .fsproj generates a dotnet stub CI workflow', () => { + it('upgrade in a dir with .fsproj generates a dotnet stub CI workflow', () => { fs.writeFileSync(path.join(tmpDir, 'MyLib.fsproj'), ''); - const result = runSquad([], tmpDir); - assert.equal(result.exitCode, 0, `init should succeed: ${result.stdout}`); + const initResult = runSquad([], tmpDir); + assert.equal(initResult.exitCode, 0, `init should succeed: ${initResult.stdout}`); + const result = runSquad(['upgrade'], tmpDir); + assert.equal(result.exitCode, 0, `upgrade should succeed: ${result.stdout}`); const ciPath = path.join(tmpDir, '.github', 'workflows', 'squad-ci.yml'); const ciContent = fs.readFileSync(ciPath, 'utf8'); @@ -281,10 +287,12 @@ describe('detectProjectType: .NET extensions (.slnx, .fsproj, .vbproj)', () => { ); }); - it('init in a dir with .vbproj generates a dotnet stub CI workflow', () => { + it('upgrade in a dir with .vbproj generates a dotnet stub CI workflow', () => { fs.writeFileSync(path.join(tmpDir, 'MyApp.vbproj'), ''); - const result = runSquad([], tmpDir); - assert.equal(result.exitCode, 0, `init should succeed: ${result.stdout}`); + const initResult = runSquad([], tmpDir); + assert.equal(initResult.exitCode, 0, `init should succeed: ${initResult.stdout}`); + const result = runSquad(['upgrade'], tmpDir); + assert.equal(result.exitCode, 0, `upgrade should succeed: ${result.stdout}`); const ciPath = path.join(tmpDir, '.github', 'workflows', 'squad-ci.yml'); const ciContent = fs.readFileSync(ciPath, 'utf8'); From f209dfac2b36d3ef17c4106adbae520571d28b96 Mon Sep 17 00:00:00 2001 From: Copilot Date: Fri, 24 Apr 2026 21:36:16 +0300 Subject: [PATCH 2/3] fix: use tmpdir for upgrade test root to avoid monorepo detection When TEST_ROOT is inside the repo, detectParentGitRepo() redirects agent file placement to the git root instead of TEST_ROOT, causing test assertions to fail. Using os.tmpdir() places the test directory outside any git repo, matching the fix already on dev. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- test/cli/upgrade.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/cli/upgrade.test.ts b/test/cli/upgrade.test.ts index 4a040e162..76b0b728e 100644 --- a/test/cli/upgrade.test.ts +++ b/test/cli/upgrade.test.ts @@ -7,12 +7,13 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { mkdir, rm, readFile, writeFile } from 'fs/promises'; import { join } from 'path'; import { existsSync, mkdirSync, writeFileSync, readFileSync, rmSync, chmodSync } from 'fs'; +import { tmpdir } from 'os'; import { randomBytes } from 'crypto'; import { runInit } from '@bradygaster/squad-cli/core/init'; import { runUpgrade, ensureGitattributes, ensureGitignore, ensureDirectories, ensureCastingDefaults, selfUpgradeCli } from '@bradygaster/squad-cli/core/upgrade'; import { getPackageVersion } from '@bradygaster/squad-cli/core/version'; -const TEST_ROOT = join(process.cwd(), `.test-cli-upgrade-${randomBytes(4).toString('hex')}`); +const TEST_ROOT = join(tmpdir(), `.test-cli-upgrade-${randomBytes(4).toString('hex')}`); describe('CLI: upgrade command', () => { beforeEach(async () => { From 7e941a01f5cd04c0ef07a4074283f43c93676318 Mon Sep 17 00:00:00 2001 From: Copilot Date: Fri, 24 Apr 2026 21:58:43 +0300 Subject: [PATCH 3/3] fix: align init, loop, and template-sync tests with dev branch - init.test.ts: use tmpdir() instead of process.cwd() to avoid monorepo detection - loop.test.ts: update error regex from /gh CLI/ to /Copilot CLI/ to match new message - template-sync.test.ts: add beforeAll sync and bump timeout to 60s Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- test/cli/init.test.ts | 3 ++- test/cli/loop.test.ts | 2 +- test/template-sync.test.ts | 16 ++++++++++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/test/cli/init.test.ts b/test/cli/init.test.ts index f0c599a92..4f5d69f78 100644 --- a/test/cli/init.test.ts +++ b/test/cli/init.test.ts @@ -7,11 +7,12 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { mkdir, rm, readdir, readFile } from 'fs/promises'; import { join } from 'path'; import { existsSync } from 'fs'; +import { tmpdir } from 'os'; import { randomBytes } from 'crypto'; import { runInit } from '@bradygaster/squad-cli/core/init'; import { getPackageVersion } from '@bradygaster/squad-cli/core/version'; -const TEST_ROOT = join(process.cwd(), `.test-cli-init-${randomBytes(4).toString('hex')}`); +const TEST_ROOT = join(tmpdir(), `.test-cli-init-${randomBytes(4).toString('hex')}`); describe('CLI: init command', () => { beforeEach(async () => { diff --git a/test/cli/loop.test.ts b/test/cli/loop.test.ts index 54b5b48fa..a3030a5dc 100644 --- a/test/cli/loop.test.ts +++ b/test/cli/loop.test.ts @@ -365,7 +365,7 @@ describe('runLoop', () => { }); await expect(runLoop(DEST, defaultOptions)).rejects.toThrow( - /gh CLI/i, + /Copilot CLI/i, ); }); diff --git a/test/template-sync.test.ts b/test/template-sync.test.ts index 66938078b..f4d5e674c 100644 --- a/test/template-sync.test.ts +++ b/test/template-sync.test.ts @@ -13,7 +13,7 @@ * 4. Semantic checks — universe counts, casting-policy internal consistency. */ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, beforeAll } from 'vitest'; import { readFileSync, existsSync, readdirSync } from 'node:fs'; import { resolve, dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -22,6 +22,18 @@ import { execSync } from 'node:child_process'; const __dirname = dirname(fileURLToPath(import.meta.url)); const ROOT = resolve(__dirname, '..'); +// Re-sync templates before any byte-comparison checks. +// Other test files (e.g., acceptance tests) may run `squad init` in the +// repo root, overwriting .github/agents/squad.agent.md from the CLI +// template and making it diverge from .squad-templates/squad.agent.md. +beforeAll(() => { + execSync('node scripts/sync-templates.mjs', { + cwd: ROOT, + encoding: 'utf-8', + timeout: 60_000, + }); +}); + // --------------------------------------------------------------------------- // Helpers // --------------------------------------------------------------------------- @@ -153,7 +165,7 @@ describe('sync-templates.mjs script execution', () => { const output = execSync('node scripts/sync-templates.mjs', { cwd: ROOT, encoding: 'utf-8', - timeout: 30_000, + timeout: 60_000, }); expect(output).toContain('Synced'); });