Skip to content

Commit e02fc20

Browse files
Mossakaclaude
andcommitted
fix: reduce Smoke Copilot context size to fix safe_outputs invocation
Full repo checkout causes Copilot CLI to ingest 1M tokens of context (via --add-dir "${GITHUB_WORKSPACE}"), making it use bash commands instead of MCP tools. The safeoutputs-add_comment tool is never called, outputs.jsonl is never created, and the safe_outputs job always skips. Fix: Remove explicit actions/checkout from smoke-copilot.md (compiler generates sparse checkout by default). Update the postprocess script to: 1. Convert sparse checkout → full checkout (needed for npm ci/build) 2. Add a "Clean workspace for agent" step that removes src/, tests/, etc. after building, keeping only .github, .agents, dist, node_modules This reduces Copilot's context from ~1M to ~200k tokens, allowing it to properly use MCP safe-output tools. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 958473a commit e02fc20

3 files changed

Lines changed: 73 additions & 19 deletions

File tree

.github/workflows/smoke-copilot.lock.yml

Lines changed: 14 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/workflows/smoke-copilot.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,6 @@ safe-outputs:
4646
run-failure: "📰 DEVELOPING STORY: [{workflow_name}]({run_url}) reports {status}. Our correspondents are investigating the incident..."
4747
timeout-minutes: 5
4848
strict: true
49-
steps:
50-
- name: Checkout repository
51-
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
52-
with:
53-
persist-credentials: false
5449
---
5550

5651
# Smoke Test: Copilot Engine Validation

scripts/ci/postprocess-smoke-workflows.ts

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,59 @@ function buildLocalInstallSteps(indent: string): string {
6060
].join('\n') + '\n';
6161
}
6262

63+
// Matches the sparse checkout step so we can convert it to full checkout
64+
// (needed for npm ci/npm run build which require the full repo)
65+
const sparseCheckoutRegex =
66+
/^(\s*)- name: Checkout \.github and \.agents folders\n\1\s*uses: actions\/checkout@[^\n]+\n(?:\1\s*[^\n]*\n)*?\1\s*persist-credentials: false\n/m;
67+
68+
// Workflows where the workspace should be cleaned after build to reduce
69+
// Copilot CLI context size (full repo = 1M tokens, sparse = 200k tokens)
70+
const workflowsNeedingCleanup = new Set([
71+
path.join(repoRoot, '.github/workflows/smoke-copilot.lock.yml'),
72+
]);
73+
74+
function buildCleanupStep(indent: string): string {
75+
const stepIndent = indent;
76+
const runIndent = `${indent} `;
77+
const scriptIndent = `${runIndent} `;
78+
79+
return [
80+
`${stepIndent}- name: Clean workspace for agent`,
81+
`${runIndent}run: |`,
82+
`${scriptIndent}# Remove source code to reduce Copilot CLI context size`,
83+
`${scriptIndent}# Keep only .github, .agents, dist, node_modules (needed for awf binary)`,
84+
`${scriptIndent}cd "$GITHUB_WORKSPACE"`,
85+
`${scriptIndent}find . -maxdepth 1 -not -name '.' -not -name '.github' -not -name '.agents' -not -name 'dist' -not -name 'node_modules' -not -name '.git' | xargs rm -rf`,
86+
].join('\n') + '\n';
87+
}
88+
6389
for (const workflowPath of workflowPaths) {
64-
const content = fs.readFileSync(workflowPath, 'utf-8');
90+
let content = fs.readFileSync(workflowPath, 'utf-8');
91+
let modified = false;
92+
93+
// Step 1: Convert sparse checkout to full checkout (needed for npm ci)
94+
if (sparseCheckoutRegex.test(content)) {
95+
content = content.replace(sparseCheckoutRegex, (match, indent: string) => {
96+
return [
97+
`${indent}- name: Checkout repository`,
98+
`${indent} uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6`,
99+
`${indent} with:`,
100+
`${indent} persist-credentials: false`,
101+
].join('\n') + '\n';
102+
});
103+
modified = true;
104+
}
105+
106+
// Step 2: Replace "Install awf binary" with local build steps
65107
const matches = content.match(installStepRegexGlobal);
66108

67109
if (!matches || matches.length === 0) {
68-
console.log(`Skipping ${workflowPath}: no awf install step found.`);
110+
if (modified) {
111+
fs.writeFileSync(workflowPath, content);
112+
console.log(`Updated ${workflowPath} (checkout only)`);
113+
} else {
114+
console.log(`Skipping ${workflowPath}: no awf install step found.`);
115+
}
69116
continue;
70117
}
71118

@@ -76,11 +123,18 @@ for (const workflowPath of workflowPaths) {
76123
);
77124
}
78125

79-
const updated = content.replace(
126+
content = content.replace(
80127
installStepRegexGlobal,
81-
(_match, indent: string) => buildLocalInstallSteps(indent)
128+
(_match, indent: string) => {
129+
let steps = buildLocalInstallSteps(indent);
130+
// Add cleanup step for workflows that need reduced context
131+
if (workflowsNeedingCleanup.has(workflowPath)) {
132+
steps += buildCleanupStep(indent);
133+
}
134+
return steps;
135+
}
82136
);
83137

84-
fs.writeFileSync(workflowPath, updated);
138+
fs.writeFileSync(workflowPath, content);
85139
console.log(`Updated ${workflowPath}`);
86140
}

0 commit comments

Comments
 (0)