Skip to content

Commit

Permalink
chore: update GitHub artifact client
Browse files Browse the repository at this point in the history
Signed-off-by: Keith Zantow <kzantow@gmail.com>
  • Loading branch information
kzantow committed May 3, 2024
1 parent ab5d7b5 commit 0dd6a3e
Show file tree
Hide file tree
Showing 11 changed files with 393,974 additions and 49,287 deletions.
146,667 changes: 130,365 additions & 16,302 deletions dist/attachReleaseAssets/index.js

Large diffs are not rendered by default.

146,663 changes: 130,363 additions & 16,300 deletions dist/downloadSyft/index.js

Large diffs are not rendered by default.

146,515 changes: 130,289 additions & 16,226 deletions dist/runSyftAction/index.js

Large diffs are not rendered by default.

3,286 changes: 2,881 additions & 405 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"author": "Keith Zantow <keith.zantow@anchore.com>",
"license": "Apache-2.0",
"dependencies": {
"@actions/artifact": "^1.1.1",
"@actions/artifact": "^2.1.7",
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"@actions/github": "^5.1.1",
Expand Down
46 changes: 23 additions & 23 deletions src/github/GithubClient.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import {
create as createArtifactClient,
UploadOptions,
} from "@actions/artifact";
import { DownloadHttpClient } from "@actions/artifact/lib/internal/download-http-client";
import artifactClient, { UploadArtifactOptions } from "@actions/artifact";
import * as core from "@actions/core";
import * as github from "@actions/github";
import { GitHub } from "@actions/github/lib/utils";
Expand Down Expand Up @@ -137,34 +133,41 @@ export class GithubClient {
/**
* Lists the workflow artifacts for the current workflow
*/
async listWorkflowArtifacts(): Promise<Artifact[]> {
async listCurrentWorkflowArtifacts(): Promise<Artifact[]> {
// The REST listWorkflowRunArtifacts endpoint does not seem to work during
// the workflow run, presumably the are available afterwards much like the
// Github UI only shows artifacts after completion of a run, so we have
// the workflow run, presumably they are available afterward, much like the
// GitHub UI only shows artifacts after completion of a run, so we have
// to do a little bit of hackery here. We _could_ download all artifacts
// using a supported API, but internally it's using this anyway
const downloadClient = new DownloadHttpClient();
const response = await downloadClient.listArtifacts();
const response = await artifactClient.listArtifacts();

debugLog("listWorkflowArtifacts response:", response);
debugLog("listCurrentWorkflowArtifacts response:", response);

return response.value;
return response.artifacts;
}

/**
* Downloads a workflow artifact for the current workflow run
* @param name artifact name
* @param id specified if using a workflow run artifact
* @return full path to the artifact
*/
async downloadWorkflowArtifact({ name, id }: Artifact): Promise<string> {
if (id) {
return this.downloadWorkflowRunArtifact({ artifactId: id });
}
const client = createArtifactClient();
const tempPath = fs.mkdtempSync(path.join(os.tmpdir(), "sbom-action-"));
const response = await suppressOutput(async () =>
client.downloadArtifact(name, tempPath)
);
const response = await suppressOutput(async () => {
const response = await artifactClient.getArtifact(name);
return await artifactClient.downloadArtifact(response.artifact.id, {
path: tempPath,
});
});

if (!response.downloadPath) {
debugLog("downloadArtifact response empty", response);
return "";
}

debugLog(
"downloadArtifact response:",
Expand All @@ -173,7 +176,7 @@ export class GithubClient {
core.isDebug() && fs.readdirSync(response.downloadPath)
);

return `${response.downloadPath}/${response.artifactName}`;
return `${response.downloadPath}`;
}

/**
Expand All @@ -192,7 +195,6 @@ export class GithubClient {
retention?: number;
}): Promise<void> {
const rootDirectory = path.dirname(file);
const client = createArtifactClient();

debugLog(
"uploadArtifact:",
Expand All @@ -203,15 +205,13 @@ export class GithubClient {
core.isDebug() && fs.readdirSync(rootDirectory)
);

const options: UploadOptions = {
continueOnError: false,
};
const options: UploadArtifactOptions = {};
if (retention) {
options.retentionDays = retention;
}

const info = await suppressOutput(async () =>
client.uploadArtifact(name, [file], rootDirectory, options)
artifactClient.uploadArtifact(name, [file], rootDirectory, options)
);

debugLog("uploadArtifact response:", info);
Expand Down Expand Up @@ -246,7 +246,7 @@ export class GithubClient {

/**
* Lists the workflow run artifacts for a completed workflow
* @param runId the workflow run number
* @param branch the branch name
*/
async findLatestWorkflowRunForBranch({
branch,
Expand Down
2 changes: 1 addition & 1 deletion src/github/SyftGithubAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ export async function attachReleaseAssets(): Promise<void> {
const sbomArtifactPattern = sbomArtifactInput || `^${getArtifactName()}$`;
const matcher = new RegExp(sbomArtifactPattern);

const artifacts = await client.listWorkflowArtifacts();
const artifacts = await client.listCurrentWorkflowArtifacts();
let matched = artifacts.filter((a) => {
const matches = matcher.test(a.name);
if (matches) {
Expand Down
2 changes: 1 addition & 1 deletion tests/GithubClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ describe("Github Client", () => {
"token"
);

let artifacts = await client.listWorkflowArtifacts();
let artifacts = await client.listCurrentWorkflowArtifacts();

expect(artifacts.length).toBe(0);

Expand Down
2 changes: 1 addition & 1 deletion tests/SyftGithubAction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ describe("Action", () => {
artifacts: [{
runId: 6,
name: "sbom.spdx.json",
file: "the_sbom",
files: ["the_sbom"],
}],
});

Expand Down
2 changes: 1 addition & 1 deletion tests/integration/formatExports.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const testSource = async (source: string, format = "spdx"): Promise<string> => {
.spyOn(client, "getClient")
.mockImplementation(() => {
return {
listWorkflowArtifacts() {
listCurrentWorkflowArtifacts() {
return Promise.resolve(artifacts);
},
uploadWorkflowArtifact({ file }) {
Expand Down
74 changes: 48 additions & 26 deletions tests/mocks.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import {
DownloadArtifactOptions,
DownloadArtifactResponse,
FindOptions,
ListArtifactsResponse,
UploadArtifactOptions,
UploadArtifactResponse
} from "@actions/artifact";

/**
* Get all the mocks and mock data
*/
export function getMocks() {
class Data {
artifacts: Partial<(Artifact & { runId: number, id: number, file: string })>[] = [];
artifacts: Partial<(Artifact & { runId: number, id: number, files: string[] })>[] = [];

assets: Partial<ReleaseAsset>[] = [];

Expand Down Expand Up @@ -109,39 +118,52 @@ export function getMocks() {
};
},

"@actions/artifact/lib/internal/download-http-client": () => {
"@actions/artifact": () => {
return {
DownloadHttpClient: class {
async listArtifacts() {
/*
export interface ArtifactClient {
uploadArtifact(name: string, files: string[], rootDirectory: string, options?: UploadArtifactOptions): Promise<UploadArtifactResponse>;
listArtifacts(options?: ListArtifactsOptions & FindOptions): Promise<ListArtifactsResponse>;
getArtifact(artifactName: string, options?: FindOptions): Promise<GetArtifactResponse>;
downloadArtifact(artifactId: number, options?: DownloadArtifactOptions & FindOptions): Promise<DownloadArtifactResponse>;
deleteArtifact(artifactName: string, options?: FindOptions): Promise<DeleteArtifactResponse>;
}
*/
uploadArtifact(name: string, files: string[], rootDirectory: string, options?: UploadArtifactOptions): UploadArtifactResponse {
const id = data.artifacts.length;
data.artifacts.push({
id,
name: path.basename(name),
files,
rootDirectory,
options,
} as never);
return {
id,
};
},
downloadArtifact(artifactId: number, options?: DownloadArtifactOptions & FindOptions): DownloadArtifactResponse {
const tempPath = options?.path || "/tmp";
const artifact = data.artifacts.find(a => a.id == artifactId);
if (artifact) {
const name = "my-artifact-name";
fs.writeFileSync(`${tempPath}/${name}`, "file");
return {
value: data.artifacts.filter(a => !a.runId),
downloadPath: `${tempPath}/${name}`,
};
}
throw new Error(`no artifact for id: ${artifactId}`);
},
};
},

"@actions/artifact": () => {
return {
create() {
listArtifacts() {
return {
uploadArtifact(name: string, file: string, rootDirectory: string, options?: any) {
data.artifacts.push({
name: path.basename(name),
file,
rootDirectory,
options,
} as never);
},
downloadArtifact(name: string, tempPath: string) {
fs.writeFileSync(`${tempPath}/${name}`, "file");
return {
downloadPath: tempPath,
artifactName: name,
};
},
artifacts: data.artifacts.filter(a => !a.runId),
};
},
getArtifact(artifactName: string, options?: FindOptions) {
return {
artifact: data.artifacts.find(a => a.name == artifactName)
}
},
};
},

Expand Down

0 comments on commit 0dd6a3e

Please sign in to comment.