Skip to content

Commit a337079

Browse files
Merge pull request #12 from Asymptote-Labs/codex/github-app-preflight
Skip legacy action on github_app repos
2 parents f0aac1c + e09ab84 commit a337079

4 files changed

Lines changed: 121 additions & 9 deletions

File tree

dist/index.js

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

src/api/client.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import test from 'node:test';
2+
import assert from 'node:assert/strict';
3+
import {
4+
shouldSkipLegacyActionForIntegration,
5+
RepositoryIntegrationModeResponse,
6+
} from './client';
7+
8+
function createIntegrationModeResponse(
9+
overrides: Partial<RepositoryIntegrationModeResponse> = {}
10+
): RepositoryIntegrationModeResponse {
11+
return {
12+
repository_id: 'repo_123',
13+
found: true,
14+
integration_mode: 'legacy_action',
15+
...overrides,
16+
};
17+
}
18+
19+
test('skips the legacy action only for found github_app repositories', () => {
20+
assert.equal(
21+
shouldSkipLegacyActionForIntegration(
22+
createIntegrationModeResponse({ integration_mode: 'github_app' })
23+
),
24+
true
25+
);
26+
27+
assert.equal(
28+
shouldSkipLegacyActionForIntegration(
29+
createIntegrationModeResponse({ found: false, integration_mode: 'github_app' })
30+
),
31+
false
32+
);
33+
34+
assert.equal(
35+
shouldSkipLegacyActionForIntegration(createIntegrationModeResponse()),
36+
false
37+
);
38+
});

src/api/client.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ interface ClientOptions {
1717
baseUrl: string;
1818
}
1919

20+
export interface RepositoryIntegrationModeResponse {
21+
repository_id: string | null;
22+
found: boolean;
23+
integration_mode: 'legacy_action' | 'github_app';
24+
}
25+
26+
export function shouldSkipLegacyActionForIntegration(
27+
integration: RepositoryIntegrationModeResponse
28+
): boolean {
29+
return integration.found && integration.integration_mode === 'github_app';
30+
}
31+
2032
export class AsymptoteClient {
2133
private apiKey: string;
2234
private baseUrl: string;
@@ -146,6 +158,17 @@ export class AsymptoteClient {
146158
}
147159
}
148160

161+
async getRepositoryIntegrationMode(
162+
owner: string,
163+
name: string
164+
): Promise<RepositoryIntegrationModeResponse> {
165+
const params = new URLSearchParams({ owner, name });
166+
return this.request<RepositoryIntegrationModeResponse>(
167+
'GET',
168+
`/api/repository-integration-mode?${params.toString()}`
169+
);
170+
}
171+
149172
private sleep(ms: number): Promise<void> {
150173
return new Promise((resolve) => setTimeout(resolve, ms));
151174
}

src/index.ts

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import * as core from '@actions/core';
22
import * as github from '@actions/github';
33
import { getConfig } from './config';
4-
import { AsymptoteClient, RateLimitError, TimeoutError } from './api/client';
4+
import {
5+
AsymptoteClient,
6+
RateLimitError,
7+
shouldSkipLegacyActionForIntegration,
8+
TimeoutError,
9+
} from './api/client';
510
import { getPRDiff, getIncrementalDiff } from './github/diff';
611
import { postViolationComments, resolveOutdatedThreads } from './github.qkg1.topments';
712
import { createCheckRun } from './github/checks';
@@ -16,6 +21,11 @@ async function run(): Promise<void> {
1621
core.info('Asymptote Security Scan starting...');
1722
core.debug(`API URL: ${config.apiUrl}`);
1823

24+
const client = new AsymptoteClient({
25+
apiKey: config.apiKey,
26+
baseUrl: config.apiUrl,
27+
});
28+
1929
// 2. Verify PR context
2030
if (github.context.eventName !== 'pull_request') {
2131
core.setFailed(
@@ -34,6 +44,28 @@ async function run(): Promise<void> {
3444
}
3545
const octokit = github.getOctokit(githubToken);
3646

47+
try {
48+
const integration = await client.getRepositoryIntegrationMode(
49+
github.context.repo.owner,
50+
github.context.repo.repo
51+
);
52+
if (shouldSkipLegacyActionForIntegration(integration)) {
53+
core.info(
54+
'Repository is configured for GitHub App PR reviews; exiting legacy action without posting comments or checks.'
55+
);
56+
core.setOutput('decision', 'allow');
57+
core.setOutput('total_violations', 0);
58+
core.setOutput('critical_count', 0);
59+
core.setOutput('high_count', 0);
60+
core.setOutput('medium_count', 0);
61+
return;
62+
}
63+
} catch (error) {
64+
core.warning(
65+
`Failed to look up repository integration mode; continuing with legacy action path. ${error instanceof Error ? error.message : String(error)}`
66+
);
67+
}
68+
3769
// 4. Get PR diff (incremental on synchronize, full otherwise)
3870
const action = github.context.payload.action;
3971
const before = github.context.payload.before;
@@ -140,10 +172,6 @@ async function run(): Promise<void> {
140172

141173
// 5. Call Asymptote API
142174
core.info('Submitting diff for evaluation...');
143-
const client = new AsymptoteClient({
144-
apiKey: config.apiKey,
145-
baseUrl: config.apiUrl,
146-
});
147175

148176
let result;
149177
try {

0 commit comments

Comments
 (0)