Skip to content

Commit a35c026

Browse files
committed
fix: actions
1 parent c1fca92 commit a35c026

3 files changed

Lines changed: 42 additions & 49 deletions

File tree

.github/hooks/hooks.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
{
1212
"type": "command",
1313
"command": "node .github/hooks/scripts/stop-build.js",
14-
"timeout": 180
14+
"timeout": 300
1515
}
1616
]
1717
}
Lines changed: 40 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
#!/usr/bin/env node
22

33
/**
4-
* Stop hook: runs `dotnet build` and reports only warnings/errors.
5-
* - No C# changes in working tree: skips the build entirely.
6-
* - Clean build: brief success message via systemMessage.
7-
* - Warnings present: systemMessage with filtered warning lines.
8-
* - Build failure / errors: blocks the agent via hookSpecificOutput so it can
9-
* address errors before concluding.
4+
* Stop hook: runs `nx affected -t test --base="HEAD"` and blocks on failures.
5+
* - No affected projects: skips entirely.
6+
* - All tests pass: brief success message via systemMessage.
7+
* - Any test failures: blocks the agent via hookSpecificOutput so it can
8+
* address failures before concluding.
109
*
1110
* Reads stdin to check stop_hook_active and avoid infinite loops.
1211
*/
@@ -30,71 +29,65 @@ if (hookInput.stop_hook_active) {
3029

3130
const repoRoot = path.resolve(__dirname, '../../..');
3231

33-
// Short-circuit if no C#-related files are dirty (staged or unstaged vs HEAD).
34-
const CSHARP_PATTERN = /\.(cs|csproj|fsproj|slnx|sln|props|targets)$|^(global\.json|NuGet\.Config)$/i;
32+
// Determine which projects are affected by uncommitted working tree changes.
33+
const affectedResult = spawnSync(
34+
'pnpm',
35+
['nx', 'show', 'projects', '--affected', '--base=HEAD', '--json'],
36+
{ cwd: repoRoot, encoding: 'utf-8', timeout: 30000 },
37+
);
3538

36-
const gitStatus = spawnSync('git', ['status', '--porcelain'], {
37-
cwd: repoRoot,
38-
encoding: 'utf-8',
39-
});
40-
const dirtyFiles = (gitStatus.stdout || '').trim().split('\n').filter(Boolean);
41-
const hasCSharpChanges = dirtyFiles.some(line => {
42-
// Each line is "XY filename" or "XY old -> new"; grab the last path segment.
43-
const filePath = line.slice(3).trim().split(' -> ').pop();
44-
return CSHARP_PATTERN.test(path.basename(filePath));
45-
});
39+
let affectedProjects = [];
40+
try {
41+
affectedProjects = JSON.parse(affectedResult.stdout || '[]');
42+
} catch (_) {
43+
// Parse failure — treat as no affected projects.
44+
}
4645

47-
if (!hasCSharpChanges) {
46+
if (affectedProjects.length === 0) {
4847
process.stdout.write(JSON.stringify({
49-
systemMessage: 'dotnet build: skipped (no C# changes detected in working tree).',
48+
systemMessage: 'nx affected test: skipped (no affected projects in working tree).',
5049
}));
5150
process.exit(0);
5251
}
5352

54-
const result = spawnSync('dotnet', ['build', 'Flowthru.slnx'], {
55-
cwd: repoRoot,
56-
encoding: 'utf-8',
57-
timeout: 180000,
58-
});
53+
// Run tests for all affected projects.
54+
const result = spawnSync(
55+
'pnpm',
56+
[
57+
'nx', 'affected', '-t', 'test',
58+
'--base=HEAD',
59+
'--output-style=stream',
60+
'--logger', 'console;verbosity=minimal',
61+
],
62+
{ cwd: repoRoot, encoding: 'utf-8', timeout: 300000 },
63+
);
5964

6065
const stdout = (result.stdout || '').trim();
6166
const stderr = (result.stderr || '').trim();
6267
const combined = [stdout, stderr].filter(Boolean).join('\n');
6368

64-
// Extract compiler diagnostics: lines containing ': warning XXXX' or ': error XXXX'.
65-
const diagnosticLines = combined
66-
.split('\n')
67-
.filter(line => /:\s*(warning|error)\s+[A-Za-z]*\d+/i.test(line));
69+
if (result.status !== 0) {
70+
// Extract failed test lines for a focused summary.
71+
const failureLines = combined
72+
.split('\n')
73+
.filter(line => /failed|error|FAILED|ERROR/i.test(line))
74+
.slice(0, 40); // cap at 40 lines to avoid overwhelming the agent
6875

69-
const hasErrors = result.status !== 0 || diagnosticLines.some(l => /:\s*error\s+/i.test(l));
70-
const hasWarnings = diagnosticLines.some(l => /:\s*warning\s+/i.test(l));
76+
const summary = failureLines.length > 0 ? failureLines.join('\n') : combined;
7177

72-
if (hasErrors) {
73-
// Block the agent so it addresses errors before concluding.
74-
const diagnosticSummary = diagnosticLines.length > 0
75-
? diagnosticLines.join('\n')
76-
: combined; // fall back to full output if pattern didn't match anything
7778
process.stdout.write(JSON.stringify({
7879
hookSpecificOutput: {
7980
hookEventName: 'Stop',
8081
decision: 'block',
8182
reason: [
82-
'dotnet build FAILED — address these errors before concluding.',
83+
`nx affected test FAILED (affected: ${affectedProjects.join(', ')}) — address these failures before concluding.`,
8384
'',
84-
diagnosticSummary,
85+
summary,
8586
].join('\n'),
8687
},
8788
}));
88-
} else if (hasWarnings) {
89-
process.stdout.write(JSON.stringify({
90-
systemMessage: [
91-
'dotnet build succeeded with warnings:',
92-
'',
93-
diagnosticLines.join('\n'),
94-
].join('\n'),
95-
}));
9689
} else {
9790
process.stdout.write(JSON.stringify({
98-
systemMessage: 'dotnet build: succeeded with no warnings or errors.',
91+
systemMessage: `nx affected test: passed (${affectedProjects.length} project(s): ${affectedProjects.join(', ')}).`,
9992
}));
10093
}

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ jobs:
9898
--logger "console;verbosity=minimal"
9999
100100
- name: Generate coverage badges
101-
if: ${{ secrets.REPORTGENERATOR_LICENSE != '' }}
101+
continue-on-error: true
102102
env:
103103
REPORTGENERATOR_LICENSE: ${{ secrets.REPORTGENERATOR_LICENSE }}
104104
run: |

0 commit comments

Comments
 (0)