Use new artifact dependency if not on GHES & feature flag enabled

This commit is contained in:
Angela P Wen
2024-09-25 13:58:25 -07:00
parent 6d887c18f0
commit 4de3002533
21 changed files with 278 additions and 51 deletions
+31 -4
View File
@@ -5,21 +5,48 @@
*/
import * as core from "@actions/core";
import { getTemporaryDirectory } from "./actions-util";
import { getGitHubVersion } from "./api-client";
import { getConfig } from "./config-utils";
import * as debugArtifacts from "./debug-artifacts";
import { EnvVar } from "./environment";
import { Features } from "./feature-flags";
import { getActionsLogger, withGroup } from "./logging";
import { getErrorMessage } from "./util";
import { parseRepositoryNwo } from "./repository";
import {
checkGitHubVersionInRange,
getErrorMessage,
getRequiredEnvParam,
} from "./util";
async function runWrapper() {
try {
const logger = getActionsLogger();
const gitHubVersion = await getGitHubVersion();
checkGitHubVersionInRange(gitHubVersion, logger);
const repositoryNwo = parseRepositoryNwo(
getRequiredEnvParam("GITHUB_REPOSITORY"),
);
const features = new Features(
gitHubVersion,
repositoryNwo,
getTemporaryDirectory(),
logger,
);
// Upload SARIF artifacts if we determine that this is a first-party analysis run.
// For third-party runs, this artifact will be uploaded in the `upload-sarif-post` step.
if (process.env[EnvVar.INIT_ACTION_HAS_RUN] === "true") {
await withGroup("Uploading combined SARIF debug artifact", () =>
debugArtifacts.uploadCombinedSarifArtifacts(logger),
);
const config = await getConfig(getTemporaryDirectory(), logger);
if (config !== undefined) {
await withGroup("Uploading combined SARIF debug artifact", () =>
debugArtifacts.uploadCombinedSarifArtifacts(
logger,
config.gitHubVersion.type,
features,
),
);
}
}
} catch (error) {
core.setFailed(
+11 -1
View File
@@ -1,6 +1,9 @@
import test from "ava";
import * as debugArtifacts from "./debug-artifacts";
import { Feature } from "./feature-flags";
import { createFeatures } from "./testing-utils";
import { GitHubVariant } from "./util";
test("sanitizeArtifactName", (t) => {
t.deepEqual(
@@ -20,7 +23,14 @@ test("sanitizeArtifactName", (t) => {
test("uploadDebugArtifacts", async (t) => {
// Test that no error is thrown if artifacts list is empty.
const mockFeature = createFeatures([Feature.ArtifactUpgrade]);
await t.notThrowsAsync(
debugArtifacts.uploadDebugArtifacts([], "rootDir", "artifactName"),
debugArtifacts.uploadDebugArtifacts(
[],
"rootDir",
"artifactName",
GitHubVariant.DOTCOM,
mockFeature,
),
);
});
+37 -4
View File
@@ -1,6 +1,7 @@
import * as fs from "fs";
import * as path from "path";
import * as artifact from "@actions/artifact";
import * as artifactLegacy from "@actions/artifact-legacy";
import * as core from "@actions/core";
import AdmZip from "adm-zip";
@@ -11,6 +12,7 @@ import { dbIsFinalized } from "./analyze";
import { getCodeQL } from "./codeql";
import { Config } from "./config-utils";
import { EnvVar } from "./environment";
import { Feature, FeatureEnablement } from "./feature-flags";
import { Language } from "./languages";
import { Logger, withGroup } from "./logging";
import {
@@ -18,6 +20,7 @@ import {
doesDirectoryExist,
getCodeQLDatabasePath,
getErrorMessage,
GitHubVariant,
listFolder,
} from "./util";
@@ -29,7 +32,11 @@ export function sanitizeArtifactName(name: string): string {
* Upload Actions SARIF artifacts for debugging when CODEQL_ACTION_DEBUG_COMBINED_SARIF
* environment variable is set
*/
export async function uploadCombinedSarifArtifacts(logger: Logger) {
export async function uploadCombinedSarifArtifacts(
logger: Logger,
gitHubVariant: GitHubVariant,
features: FeatureEnablement,
) {
const tempDir = getTemporaryDirectory();
// Upload Actions SARIF artifacts for debugging when environment variable is set
@@ -61,6 +68,8 @@ export async function uploadCombinedSarifArtifacts(logger: Logger) {
toUpload,
baseTempDir,
"combined-sarif-artifacts",
gitHubVariant,
features,
);
} catch (e) {
logger.warning(
@@ -153,6 +162,7 @@ async function tryBundleDatabase(
export async function tryUploadAllAvailableDebugArtifacts(
config: Config,
logger: Logger,
features: FeatureEnablement,
) {
const filesToUpload: string[] = [];
try {
@@ -214,6 +224,8 @@ export async function tryUploadAllAvailableDebugArtifacts(
filesToUpload,
config.dbLocation,
config.debugArtifactName,
config.gitHubVersion.type,
features,
),
);
} catch (e) {
@@ -227,6 +239,8 @@ export async function uploadDebugArtifacts(
toUpload: string[],
rootDir: string,
artifactName: string,
ghVariant: GitHubVariant,
features: FeatureEnablement,
) {
if (toUpload.length === 0) {
return;
@@ -246,16 +260,35 @@ export async function uploadDebugArtifacts(
}
}
await artifactLegacy.create().uploadArtifact(
// `@actions/artifact@v2` is not yet supported on GHES so the legacy version of the client will be used on GHES
// until it is supported. We also use the legacy version of the client if the feature flag is disabled.
const artifactUploader =
ghVariant !== GitHubVariant.GHES &&
(await features.getValue(Feature.ArtifactUpgrade))
? new artifact.DefaultArtifactClient()
: artifactLegacy.create();
const artifactUploaderArgs: [
string, // artifact name
string[], // file paths to upload
string, // root directory
artifact.UploadArtifactOptions,
] = [
sanitizeArtifactName(`${artifactName}${suffix}`),
toUpload.map((file) => path.normalize(file)),
path.normalize(rootDir),
{
continueOnError: true,
// ensure we don't keep the debug artifacts around for too long since they can be large.
retentionDays: 7,
},
);
];
try {
await artifactUploader.uploadArtifact(...artifactUploaderArgs);
} catch (e) {
// A failure to upload debug artifacts should not fail the entire action.
core.warning(`Failed to upload debug artifacts: ${e}`);
}
}
/**
+6
View File
@@ -40,6 +40,7 @@ export interface FeatureEnablement {
* Legacy features should end with `_enabled`.
*/
export enum Feature {
ArtifactUpgrade = "artifact_upgrade",
CleanupTrapCaches = "cleanup_trap_caches",
CppDependencyInstallation = "cpp_dependency_installation_enabled",
DisableCsharpBuildless = "disable_csharp_buildless",
@@ -80,6 +81,11 @@ export const featureConfig: Record<
toolsFeature?: ToolsFeature;
}
> = {
[Feature.ArtifactUpgrade]: {
defaultValue: false,
envVar: "CODEQL_ACTION_ARTIFACT_UPGRADE",
minimumVersion: undefined,
},
[Feature.CleanupTrapCaches]: {
defaultValue: false,
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
+2 -1
View File
@@ -161,6 +161,7 @@ export async function run(
uploadAllAvailableDebugArtifacts: (
config: Config,
logger: Logger,
features: FeatureEnablement,
) => Promise<void>,
printDebugLogs: (config: Config) => Promise<void>,
config: Config,
@@ -210,7 +211,7 @@ export async function run(
logger.info(
"Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts...",
);
await uploadAllAvailableDebugArtifacts(config, logger);
await uploadAllAvailableDebugArtifacts(config, logger, features);
await printDebugLogs(config);
}
+55 -12
View File
@@ -3,12 +3,22 @@
* It will run after the all steps in this job, in reverse order in relation to
* other `post:` hooks.
*/
import * as artifact from "@actions/artifact";
import * as artifactLegacy from "@actions/artifact-legacy";
import * as core from "@actions/core";
import * as actionsUtil from "./actions-util";
import { getGitHubVersion } from "./api-client";
import * as configUtils from "./config-utils";
import { getErrorMessage } from "./util";
import { Feature, Features } from "./feature-flags";
import { getActionsLogger } from "./logging";
import { parseRepositoryNwo } from "./repository";
import {
checkGitHubVersionInRange,
getErrorMessage,
getRequiredEnvParam,
GitHubVariant,
} from "./util";
async function runWrapper() {
try {
@@ -31,18 +41,51 @@ async function runWrapper() {
core.info(
"Debug mode is on. Uploading proxy log as Actions debugging artifact...",
);
if (config?.gitHubVersion.type === undefined) {
core.warning(
`Did not upload debug artifacts because cannot determine the GitHub variant running.`,
);
return;
}
const logger = getActionsLogger();
const gitHubVersion = await getGitHubVersion();
checkGitHubVersionInRange(gitHubVersion, logger);
const repositoryNwo = parseRepositoryNwo(
getRequiredEnvParam("GITHUB_REPOSITORY"),
);
const features = new Features(
gitHubVersion,
repositoryNwo,
actionsUtil.getTemporaryDirectory(),
logger,
);
try {
await artifactLegacy
.create()
.uploadArtifact(
"proxy-log-file",
[logFilePath],
actionsUtil.getTemporaryDirectory(),
{
continueOnError: true,
retentionDays: 7,
},
);
// `@actions/artifact@v2` is not yet supported on GHES so the legacy version of the client will be used on GHES
// until it is supported. We also use the legacy version of the client if the feature flag is disabled.
const artifactUploader =
config?.gitHubVersion.type !== GitHubVariant.GHES &&
(await features.getValue(Feature.ArtifactUpgrade))
? new artifact.DefaultArtifactClient()
: artifactLegacy.create();
const artifactUploaderArgs: [
string, // artifact name
string[], // file paths to upload
string, // root directory
artifact.UploadArtifactOptions,
] = [
"proxy-log-file",
[logFilePath],
actionsUtil.getTemporaryDirectory(),
{
// ensure we don't keep the debug artifacts around for too long since they can be large.
retentionDays: 7,
},
];
await artifactUploader.uploadArtifact(...artifactUploaderArgs);
} catch (e) {
// A failure to upload debug artifacts should not fail the entire action.
core.warning(`Failed to upload debug artifacts: ${e}`);
+32 -2
View File
@@ -5,19 +5,49 @@
*/
import * as core from "@actions/core";
import { getTemporaryDirectory } from "./actions-util";
import { getGitHubVersion } from "./api-client";
import * as debugArtifacts from "./debug-artifacts";
import { EnvVar } from "./environment";
import { Features } from "./feature-flags";
import { getActionsLogger, withGroup } from "./logging";
import { getErrorMessage } from "./util";
import { parseRepositoryNwo } from "./repository";
import {
checkGitHubVersionInRange,
getErrorMessage,
getRequiredEnvParam,
} from "./util";
async function runWrapper() {
try {
const logger = getActionsLogger();
const gitHubVersion = await getGitHubVersion();
checkGitHubVersionInRange(gitHubVersion, logger);
const repositoryNwo = parseRepositoryNwo(
getRequiredEnvParam("GITHUB_REPOSITORY"),
);
const features = new Features(
gitHubVersion,
repositoryNwo,
getTemporaryDirectory(),
logger,
);
// Upload SARIF artifacts if we determine that this is a third-party analysis run.
// For first-party runs, this artifact will be uploaded in the `analyze-post` step.
if (process.env[EnvVar.INIT_ACTION_HAS_RUN] !== "true") {
if (gitHubVersion.type === undefined) {
core.warning(
`Did not upload debug artifacts because cannot determine the GitHub variant running.`,
);
return;
}
await withGroup("Uploading combined SARIF debug artifact", () =>
debugArtifacts.uploadCombinedSarifArtifacts(logger),
debugArtifacts.uploadCombinedSarifArtifacts(
logger,
gitHubVersion.type,
features,
),
);
}
} catch (error) {