From 15051941e0c44f82d86fd8dbe329cf050cb48d42 Mon Sep 17 00:00:00 2001 From: Matthias Valvekens Date: Mon, 18 Dec 2023 00:06:54 +0100 Subject: [PATCH] Support downloading artifacts with common prefix This commit adds the `name-prefix` input parameter to allow downloading multiple artifacts of which the names share a common prefix. This is useful for aggregating artifacts produced by matrix runs (e.g. reports from matrixed test jobs). Provides a smoother migration path for the use cases in #248. --- README.md | 8 +++++++- action.yml | 6 +++++- src/constants.ts | 1 + src/download-artifact.ts | 22 +++++++++++++++++++--- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7c0e3f7..0719a14 100644 --- a/README.md +++ b/README.md @@ -46,9 +46,15 @@ For more information, see the [`@actions/artifact`](https://github.com/actions/t - uses: actions/download-artifact@v4 with: # Name of the artifact to download. - # Optional. If unspecified, all artifacts for the run are downloaded. + # Optional. If unspecified, all artifacts for the run are downloaded, unless restricted by `name-prefix`. name: + # Name prefix of artifacts to download. + # If specified, download all artifacts of which the name starts with the given prefix. + # This is useful for aggregating artifacts produced by matrix jobs, for example. + # Optional; only meaningful if `name` is unspecified. + name-prefix: + # Destination path. Supports basic tilde expansion. # Optional. Defaults is $GITHUB_WORKSPACE path: diff --git a/action.yml b/action.yml index fdae197..4828817 100644 --- a/action.yml +++ b/action.yml @@ -3,7 +3,11 @@ description: 'Download a build artifact that was previously uploaded in the work author: 'GitHub' inputs: name: - description: 'Name of the artifact to download. If unspecified, all artifacts for the run are downloaded' + description: 'Name of the artifact to download. If unspecified, all artifacts for the run are downloaded, + unless filtered out by name-prefix.' + required: false + name-prefix: + description: 'Download all artifacts starting with this prefix.' required: false path: description: 'Destination path. Supports basic tilde expansion. Defaults to $GITHUB_WORKSPACE' diff --git a/src/constants.ts b/src/constants.ts index 440d1dc..6b31376 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,5 +1,6 @@ export enum Inputs { Name = 'name', + NamePrefix = 'name-prefix', Path = 'path', GitHubToken = 'github-token', Repository = 'repository', diff --git a/src/download-artifact.ts b/src/download-artifact.ts index 4055762..a5ad694 100644 --- a/src/download-artifact.ts +++ b/src/download-artifact.ts @@ -17,6 +17,7 @@ export const chunk = (arr: T[], n: number): T[][] => async function run(): Promise { const inputs = { name: core.getInput(Inputs.Name, {required: false}), + namePrefix: core.getInput(Inputs.NamePrefix, {required: false}), path: core.getInput(Inputs.Path, {required: false}), token: core.getInput(Inputs.GitHubToken, {required: false}), repository: core.getInput(Inputs.Repository, {required: false}), @@ -73,7 +74,10 @@ async function run(): Promise { artifacts = [targetArtifact] } else { core.info( - `No input name specified, downloading all artifacts. Extra directory with the artifact name will be created for each download` + `No input name specified, downloading all artifacts ${ + inputs.namePrefix ? `starting with '${inputs.namePrefix}'` : '' + }. + Extra directory with the artifact name will be created for each download` ) const listArtifactResponse = await artifactClient.listArtifacts({ @@ -87,8 +91,20 @@ async function run(): Promise { ) } - core.debug(`Found ${listArtifactResponse.artifacts.length} artifacts`) - artifacts = listArtifactResponse.artifacts + if (inputs.namePrefix) { + artifacts = listArtifactResponse.artifacts.filter(art => + art.name.startsWith(inputs.namePrefix) + ) + + if (artifacts.length === 0) { + throw new Error( + `No artifacts found starting with prefix ${inputs.namePrefix} for run '${inputs.runID}' in '${inputs.repository}'` + ) + } + } else { + artifacts = listArtifactResponse.artifacts + } + core.debug(`Found ${artifacts.length} artifacts`) } const downloadPromises = artifacts.map(artifact =>