Skip to content

Commit 055bcf5

Browse files
committed
feat: support DAP API key in workflow and ingest
1 parent 5d74d7b commit 055bcf5

3 files changed

Lines changed: 27 additions & 3 deletions

File tree

.github/workflows/daily-scan.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ jobs:
4444
URL_LIMIT: ${{ inputs.url_limit }}
4545
TRAFFIC_WINDOW: ${{ inputs.traffic_window || 'daily' }}
4646
DRY_RUN: ${{ inputs.dry_run || false }}
47+
DAP_API_KEY: ${{ secrets.DAP_API_KEY }}
4748
steps:
4849
- name: Checkout
4950
uses: actions/checkout@v4

src/cli/run-daily-scan.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ function parseArgs(argv) {
3030
scanMode: 'mock',
3131
mockFailUrl: [],
3232
outputRoot: null,
33+
dapApiKey: undefined,
3334
concurrency: 4,
3435
timeoutMs: 20000,
3536
maxRetries: 1
@@ -68,6 +69,9 @@ function parseArgs(argv) {
6869
case '--output-root':
6970
args.outputRoot = argv[++index];
7071
break;
72+
case '--dap-api-key':
73+
args.dapApiKey = argv[++index];
74+
break;
7175
case '--concurrency':
7276
args.concurrency = Number(argv[++index]);
7377
break;
@@ -234,6 +238,7 @@ export async function runDailyScan(inputArgs = parseArgs(process.argv)) {
234238
const args = inputArgs;
235239
const repoRoot = path.resolve(args.outputRoot ?? getDefaultRepoRoot());
236240
const configPath = args.configPath ?? getDefaultConfigPath();
241+
const dapApiKey = args.dapApiKey ?? process.env.DAP_API_KEY;
237242

238243
let runMetadata;
239244

@@ -251,11 +256,17 @@ export async function runDailyScan(inputArgs = parseArgs(process.argv)) {
251256
source: 'dap'
252257
});
253258

259+
const dapEndpoint = runtimeConfig.sources?.dap_top_pages_endpoint;
260+
if (!args.sourceFile && dapEndpoint?.includes('api.gsa.gov') && !dapApiKey) {
261+
throw new Error('DAP_API_KEY is required to fetch top pages from api.gsa.gov. Set repo secret DAP_API_KEY or pass --dap-api-key.');
262+
}
263+
254264
const normalized = await getNormalizedTopPages({
255-
endpoint: runtimeConfig.sources?.dap_top_pages_endpoint,
265+
endpoint: dapEndpoint,
256266
sourceFile: args.sourceFile,
257267
limit: runtimeConfig.scan.url_limit,
258-
sourceDate: runMetadata.run_date
268+
sourceDate: runMetadata.run_date,
269+
dapApiKey
259270
});
260271

261272
const warningEvents = normalized.warnings.map((warning) =>

src/ingest/dap-source.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@ export async function fetchDapRecords({ endpoint, fetchImpl = fetch }) {
8585
return extractArrayPayload(payload);
8686
}
8787

88+
function buildDapEndpoint(endpoint, apiKey) {
89+
const url = new URL(endpoint);
90+
91+
if (apiKey && !url.searchParams.has('api_key')) {
92+
url.searchParams.set('api_key', apiKey);
93+
}
94+
95+
return url.toString();
96+
}
97+
8898
export async function readDapRecordsFromFile(filePath) {
8999
const raw = await fs.readFile(filePath, 'utf-8');
90100
const payload = JSON.parse(raw);
@@ -96,13 +106,15 @@ export async function getNormalizedTopPages({
96106
sourceFile,
97107
limit,
98108
sourceDate,
109+
dapApiKey,
99110
fetchImpl = fetch
100111
}) {
101112
let rawRecords;
102113
if (sourceFile) {
103114
rawRecords = await readDapRecordsFromFile(sourceFile);
104115
} else {
105-
rawRecords = await fetchDapRecords({ endpoint, fetchImpl });
116+
const resolvedEndpoint = buildDapEndpoint(endpoint, dapApiKey);
117+
rawRecords = await fetchDapRecords({ endpoint: resolvedEndpoint, fetchImpl });
106118
}
107119

108120
return normalizeDapRecords(rawRecords, { limit, sourceDate });

0 commit comments

Comments
 (0)