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.
This commit is contained in:
Matthias Valvekens 2023-12-18 00:06:54 +01:00
parent 1bd0606e08
commit 15051941e0
No known key found for this signature in database
GPG key ID: 15F42BEFA159BA54
4 changed files with 32 additions and 5 deletions

View file

@ -46,9 +46,15 @@ For more information, see the [`@actions/artifact`](https://github.com/actions/t
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
# Name of the artifact to download. # 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:
# 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. # Destination path. Supports basic tilde expansion.
# Optional. Defaults is $GITHUB_WORKSPACE # Optional. Defaults is $GITHUB_WORKSPACE
path: path:

View file

@ -3,7 +3,11 @@ description: 'Download a build artifact that was previously uploaded in the work
author: 'GitHub' author: 'GitHub'
inputs: inputs:
name: 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 required: false
path: path:
description: 'Destination path. Supports basic tilde expansion. Defaults to $GITHUB_WORKSPACE' description: 'Destination path. Supports basic tilde expansion. Defaults to $GITHUB_WORKSPACE'

View file

@ -1,5 +1,6 @@
export enum Inputs { export enum Inputs {
Name = 'name', Name = 'name',
NamePrefix = 'name-prefix',
Path = 'path', Path = 'path',
GitHubToken = 'github-token', GitHubToken = 'github-token',
Repository = 'repository', Repository = 'repository',

View file

@ -17,6 +17,7 @@ export const chunk = <T>(arr: T[], n: number): T[][] =>
async function run(): Promise<void> { async function run(): Promise<void> {
const inputs = { const inputs = {
name: core.getInput(Inputs.Name, {required: false}), name: core.getInput(Inputs.Name, {required: false}),
namePrefix: core.getInput(Inputs.NamePrefix, {required: false}),
path: core.getInput(Inputs.Path, {required: false}), path: core.getInput(Inputs.Path, {required: false}),
token: core.getInput(Inputs.GitHubToken, {required: false}), token: core.getInput(Inputs.GitHubToken, {required: false}),
repository: core.getInput(Inputs.Repository, {required: false}), repository: core.getInput(Inputs.Repository, {required: false}),
@ -73,7 +74,10 @@ async function run(): Promise<void> {
artifacts = [targetArtifact] artifacts = [targetArtifact]
} else { } else {
core.info( 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({ const listArtifactResponse = await artifactClient.listArtifacts({
@ -87,8 +91,20 @@ async function run(): Promise<void> {
) )
} }
core.debug(`Found ${listArtifactResponse.artifacts.length} artifacts`) if (inputs.namePrefix) {
artifacts = listArtifactResponse.artifacts 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 => const downloadPromises = artifacts.map(artifact =>