diff --git a/app/git.js b/app/git.js index 243b67c..36a06f6 100644 --- a/app/git.js +++ b/app/git.js @@ -20,6 +20,11 @@ export const SYNC_PATHS = [ 'CLAUDE.md', 'GEMINI.md', ]; +const FORCE_SYNC_FILE_PATHS = [ + '.github/copilot-instructions.md', + 'CLAUDE.md', + 'GEMINI.md', +]; const SYNC_TREE_PATHS = [ '.codex/skills/triage-findings', '.claude/skills/triage-findings', @@ -77,6 +82,15 @@ function copyTree(sourceRoot, repoDir, relDir) { return copied; } +function copyFileOverwrite(sourceRoot, repoDir, relPath) { + const src = path.join(sourceRoot, relPath); + if (!fs.existsSync(src)) return null; + const dest = path.join(repoDir, relPath); + fs.mkdirSync(path.dirname(dest), { recursive: true }); + fs.copyFileSync(src, dest); + return relPath; +} + export function getRepoState(repoDir, _spawnSync = spawnSync) { const run = makeRunner(_spawnSync); const headSha = readGitOutput(run, ['rev-parse', 'HEAD'], repoDir); @@ -137,15 +151,18 @@ export async function commitAndPush(workspace, repoDir, _spawnSync = spawnSync, } } + // Force overwrite the direct instruction files first so the target repo always + // receives the action-owned versions even if the repo has drifted. + for (const relPath of FORCE_SYNC_FILE_PATHS) { + const copied = copyFileOverwrite(sourceRoot, repoDir, relPath); + if (copied) existingSyncPaths.add(copied); + } + // Copy standalone action files into the target repo. Existing files are overwritten. for (const relPath of SYNC_PATHS) { - const src = path.join(sourceRoot, relPath); - const dest = path.join(repoDir, relPath); - if (fs.existsSync(src)) { - fs.mkdirSync(path.dirname(dest), { recursive: true }); - fs.copyFileSync(src, dest); - existingSyncPaths.add(relPath); - } + if (FORCE_SYNC_FILE_PATHS.includes(relPath)) continue; + const copied = copyFileOverwrite(sourceRoot, repoDir, relPath); + if (copied) existingSyncPaths.add(copied); } if (existingSyncPaths.size > 0) { diff --git a/app/git.test.js b/app/git.test.js index f4bafee..f70d2c5 100644 --- a/app/git.test.js +++ b/app/git.test.js @@ -159,11 +159,15 @@ describe('commitAndPush', () => { const repoDir = path.join(workspace, 'repo'); fs.writeFileSync(path.join(repoDir, '.github/skills/triage-findings/SKILL.md'), 'stale'); fs.writeFileSync(path.join(repoDir, 'CLAUDE.md'), 'stale'); + fs.writeFileSync(path.join(repoDir, 'GEMINI.md'), 'stale'); + fs.writeFileSync(path.join(repoDir, '.github/copilot-instructions.md'), 'stale'); await commitAndPush(workspace, repoDir, makeSpawn(), sourceRoot); assert.equal(fs.readFileSync(path.join(repoDir, '.github/skills/triage-findings/SKILL.md'), 'utf8'), '.github/skills/triage-findings/SKILL.md'); assert.equal(fs.readFileSync(path.join(repoDir, 'CLAUDE.md'), 'utf8'), 'CLAUDE.md'); + assert.equal(fs.readFileSync(path.join(repoDir, 'GEMINI.md'), 'utf8'), 'GEMINI.md'); + assert.equal(fs.readFileSync(path.join(repoDir, '.github/copilot-instructions.md'), 'utf8'), '.github/copilot-instructions.md'); }); it('recursively overwrites skill tree files from the action source', async () => {