Skip to content

Commit 5eb7519

Browse files
authored
Merge pull request #3358 from github/henrymercer/database-upload-telemetry
Add status report for uploading databases to API
2 parents c07cc0d + e962687 commit 5eb7519

File tree

4 files changed

+93
-30
lines changed

4 files changed

+93
-30
lines changed

lib/analyze-action.js

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

src/analyze-action.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ import { runAutobuild } from "./autobuild";
2020
import { getTotalCacheSize, shouldStoreCache } from "./caching-utils";
2121
import { getCodeQL } from "./codeql";
2222
import { Config, getConfig } from "./config-utils";
23-
import { cleanupAndUploadDatabases } from "./database-upload";
23+
import {
24+
cleanupAndUploadDatabases,
25+
DatabaseUploadResult,
26+
} from "./database-upload";
2427
import {
2528
DependencyCacheUploadStatusReport,
2629
uploadDependencyCaches,
@@ -54,15 +57,13 @@ interface AnalysisStatusReport
5457
extends uploadLib.UploadStatusReport,
5558
QueriesStatusReport {}
5659

57-
interface DependencyCachingUploadStatusReport {
58-
dependency_caching_upload_results?: DependencyCacheUploadStatusReport;
59-
}
60-
6160
interface FinishStatusReport
6261
extends StatusReportBase,
6362
DatabaseCreationTimings,
64-
AnalysisStatusReport,
65-
DependencyCachingUploadStatusReport {}
63+
AnalysisStatusReport {
64+
dependency_caching_upload_results?: DependencyCacheUploadStatusReport;
65+
database_upload_results: DatabaseUploadResult[];
66+
}
6667

6768
interface FinishWithTrapUploadStatusReport extends FinishStatusReport {
6869
/** Size of TRAP caches that we uploaded, in bytes. */
@@ -81,6 +82,7 @@ async function sendStatusReport(
8182
didUploadTrapCaches: boolean,
8283
trapCacheCleanup: TrapCacheCleanupStatusReport | undefined,
8384
dependencyCacheResults: DependencyCacheUploadStatusReport | undefined,
85+
databaseUploadResults: DatabaseUploadResult[],
8486
logger: Logger,
8587
) {
8688
const status = getActionsStatus(error, stats?.analyze_failure_language);
@@ -101,6 +103,7 @@ async function sendStatusReport(
101103
...(dbCreationTimings || {}),
102104
...(trapCacheCleanup || {}),
103105
dependency_caching_upload_results: dependencyCacheResults,
106+
database_upload_results: databaseUploadResults,
104107
};
105108
if (config && didUploadTrapCaches) {
106109
const trapCacheUploadStatusReport: FinishWithTrapUploadStatusReport = {
@@ -218,6 +221,7 @@ async function run() {
218221
let dbCreationTimings: DatabaseCreationTimings | undefined = undefined;
219222
let didUploadTrapCaches = false;
220223
let dependencyCacheResults: DependencyCacheUploadStatusReport | undefined;
224+
let databaseUploadResults: DatabaseUploadResult[] = [];
221225
util.initializeEnvironment(actionsUtil.getActionVersion());
222226

223227
// Make inputs accessible in the `post` step, details at
@@ -389,7 +393,7 @@ async function run() {
389393
// Possibly upload the database bundles for remote queries.
390394
// Note: Take care with the ordering of this call since databases may be cleaned up
391395
// at the `overlay` or `clear` level.
392-
await cleanupAndUploadDatabases(
396+
databaseUploadResults = await cleanupAndUploadDatabases(
393397
repositoryNwo,
394398
codeql,
395399
config,
@@ -461,6 +465,7 @@ async function run() {
461465
didUploadTrapCaches,
462466
trapCacheCleanupTelemetry,
463467
dependencyCacheResults,
468+
databaseUploadResults,
464469
logger,
465470
);
466471
return;
@@ -483,6 +488,7 @@ async function run() {
483488
didUploadTrapCaches,
484489
trapCacheCleanupTelemetry,
485490
dependencyCacheResults,
491+
databaseUploadResults,
486492
logger,
487493
);
488494
} else if (runStats !== undefined) {
@@ -496,6 +502,7 @@ async function run() {
496502
didUploadTrapCaches,
497503
trapCacheCleanupTelemetry,
498504
dependencyCacheResults,
505+
databaseUploadResults,
499506
logger,
500507
);
501508
} else {
@@ -509,6 +516,7 @@ async function run() {
509516
didUploadTrapCaches,
510517
trapCacheCleanupTelemetry,
511518
dependencyCacheResults,
519+
databaseUploadResults,
512520
logger,
513521
);
514522
}

src/database-upload.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ test("Don't crash if uploading a database fails", async (t) => {
231231
(v) =>
232232
v.type === "warning" &&
233233
v.message ===
234-
"Failed to upload database for javascript: Error: some error message",
234+
"Failed to upload database for javascript: some error message",
235235
) !== undefined,
236236
);
237237
});

src/database-upload.ts

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,43 @@ import { RepositoryNwo } from "./repository";
1313
import * as util from "./util";
1414
import { bundleDb, CleanupLevel, parseGitHubUrl } from "./util";
1515

16+
/** Information about a database upload. */
17+
export interface DatabaseUploadResult {
18+
/** Language of the database. */
19+
language: string;
20+
/** Size of the zipped database in bytes. */
21+
zipped_upload_size_bytes?: number;
22+
/** Whether the uploaded database is an overlay base. */
23+
is_overlay_base?: boolean;
24+
/** Time taken to upload database in milliseconds. */
25+
upload_duration_ms?: number;
26+
/** If there was an error during database upload, this is its message. */
27+
error?: string;
28+
}
29+
1630
export async function cleanupAndUploadDatabases(
1731
repositoryNwo: RepositoryNwo,
1832
codeql: CodeQL,
1933
config: Config,
2034
apiDetails: GitHubApiDetails,
2135
features: FeatureEnablement,
2236
logger: Logger,
23-
): Promise<void> {
37+
): Promise<DatabaseUploadResult[]> {
2438
if (actionsUtil.getRequiredInput("upload-database") !== "true") {
2539
logger.debug("Database upload disabled in workflow. Skipping upload.");
26-
return;
40+
return [];
2741
}
2842

2943
if (!config.analysisKinds.includes(AnalysisKind.CodeScanning)) {
3044
logger.debug(
3145
`Not uploading database because 'analysis-kinds: ${AnalysisKind.CodeScanning}' is not enabled.`,
3246
);
33-
return;
47+
return [];
3448
}
3549

3650
if (util.isInTestMode()) {
3751
logger.debug("In test mode. Skipping database upload.");
38-
return;
52+
return [];
3953
}
4054

4155
// Do nothing when not running against github.com
@@ -44,20 +58,22 @@ export async function cleanupAndUploadDatabases(
4458
config.gitHubVersion.type !== util.GitHubVariant.GHEC_DR
4559
) {
4660
logger.debug("Not running against github.com or GHEC-DR. Skipping upload.");
47-
return;
61+
return [];
4862
}
4963

5064
if (!(await gitUtils.isAnalyzingDefaultBranch())) {
5165
// We only want to upload a database if we are analyzing the default branch.
5266
logger.debug("Not analyzing default branch. Skipping upload.");
53-
return;
67+
return [];
5468
}
5569

56-
const cleanupLevel =
70+
// If config.overlayDatabaseMode is OverlayBase, then we have overlay base databases for all languages.
71+
const shouldUploadOverlayBase =
5772
config.overlayDatabaseMode === OverlayDatabaseMode.OverlayBase &&
58-
(await features.getValue(Feature.UploadOverlayDbToApi))
59-
? CleanupLevel.Overlay
60-
: CleanupLevel.Clear;
73+
(await features.getValue(Feature.UploadOverlayDbToApi));
74+
const cleanupLevel = shouldUploadOverlayBase
75+
? CleanupLevel.Overlay
76+
: CleanupLevel.Clear;
6177

6278
// Clean up the database, since intermediate results may still be written to the
6379
// database if there is high RAM pressure.
@@ -77,6 +93,7 @@ export async function cleanupAndUploadDatabases(
7793
uploadsBaseUrl = uploadsBaseUrl.slice(0, -1);
7894
}
7995

96+
const reports: DatabaseUploadResult[] = [];
8097
for (const language of config.languages) {
8198
try {
8299
// Upload the database bundle.
@@ -90,6 +107,7 @@ export async function cleanupAndUploadDatabases(
90107
actionsUtil.getRequiredInput("checkout_path"),
91108
);
92109
try {
110+
const startTime = performance.now();
93111
await client.request(
94112
`POST /repos/:owner/:repo/code-scanning/codeql/databases/:language?name=:name&commit_oid=:commit_oid`,
95113
{
@@ -107,13 +125,27 @@ export async function cleanupAndUploadDatabases(
107125
},
108126
},
109127
);
128+
const endTime = performance.now();
129+
reports.push({
130+
language,
131+
zipped_upload_size_bytes: bundledDbSize,
132+
is_overlay_base: shouldUploadOverlayBase,
133+
upload_duration_ms: endTime - startTime,
134+
});
110135
logger.debug(`Successfully uploaded database for ${language}`);
111136
} finally {
112137
bundledDbReadStream.close();
113138
}
114139
} catch (e) {
115140
// Log a warning but don't fail the workflow
116-
logger.warning(`Failed to upload database for ${language}: ${e}`);
141+
logger.warning(
142+
`Failed to upload database for ${language}: ${util.getErrorMessage(e)}`,
143+
);
144+
reports.push({
145+
language,
146+
error: util.getErrorMessage(e),
147+
});
117148
}
118149
}
150+
return reports;
119151
}

0 commit comments

Comments
 (0)