Compare commits

..

8 Commits

Author SHA1 Message Date
Rob Herley
9140050fd5 consume latest @actions/artifact from toolkit 2023-11-20 20:57:50 -05:00
Rob Herley
896d1bb258 Merge pull request #232 from robherley/v4-beta
[v4-beta] Bump linked artifact toolkit pkg
2023-10-16 14:56:31 -04:00
Rob Herley
57685c7c71 bump linked artifact toolkit pkg 2023-10-16 14:40:44 -04:00
Rob Herley
8c323b340c Merge pull request #226 from robherley/main
Create v4-beta
2023-08-24 12:15:14 -04:00
Rob Herley
727cfbe442 better fallback for path and append aritfact name for mutli-download 2023-08-24 12:05:05 -04:00
Rob Herley
24b1443a07 use new @actions/artifact version & update download logic 2023-08-24 11:57:52 -04:00
Brian Flad
e9ef242655 Add download-path output to action.yml (#194)
Reference: https://github.com/actions/download-artifact/issues/153
Reference: https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#outputs-for-docker-container-and-javascript-actions

Prevents false positives from tooling, such as `actionlint`, that depends on the metadata for static analysis.

Co-authored-by: Konrad Pabjan <konradpabjan@github.com>
2023-01-05 17:35:52 -05:00
dependabot[bot]
adf9559c4f Bump json5 from 1.0.1 to 1.0.2 (#198)
Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 17:24:04 -05:00
6 changed files with 117139 additions and 4175 deletions

View File

@@ -1,13 +1,29 @@
name: 'Download a Build Artifact'
description: 'Download a build artifact that was previously uploaded in the workflow by the upload-artifact action'
author: 'GitHub'
inputs:
inputs:
name:
description: 'Artifact name'
required: false
path:
description: 'Destination path'
required: false
github-token:
description: The GitHub token used to download the artifact
default: ${{ github.token }}
required: false
repository:
description: 'The repository owner and the repository name joined together by "/".
This specifies the repository that artifacts will be downloaded from. If downloading artifacts from external workflow runs or repositories then the above download-token must be permissions to this repository.'
required: false
default: ${{ github.repository }}
run-id:
description: 'The id of the workflow run where the desired download artifact was uploaded from. If downloading artifacts from anything other than the current workflow run then this needs to be overwritten.'
required: false
default: ${{ github.run_id }}
outputs:
download-path:
description: 'Path of artifact download'
runs:
using: 'node20'
using: 'node16'
main: 'dist/index.js'

119556
dist/index.js vendored

File diff suppressed because one or more lines are too long

1578
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "download-artifact",
"version": "3.1.0",
"version": "3.0.0",
"description": "Download a build artifact that was previously uploaded in the workflow by the upload-artifact action",
"main": "dist/index.js",
"scripts": {
@@ -28,8 +28,9 @@
},
"homepage": "https://github.com/actions/download-artifact#readme",
"dependencies": {
"@actions/artifact": "^1.1.3",
"@actions/core": "^1.10.0"
"@actions/artifact": "^2.0.0",
"@actions/core": "^1.10.0",
"@actions/github": "^5.1.1"
},
"devDependencies": {
"@types/node": "^12.12.6",
@@ -41,4 +42,4 @@
"prettier": "^2.0.5",
"typescript": "^3.8.3"
}
}
}

View File

@@ -1,7 +1,11 @@
export enum Inputs {
Name = 'name',
Path = 'path'
Path = 'path',
GitHubToken = 'github-token',
Repository = 'repository',
RunID = 'run-id'
}
export enum Outputs {
DownloadPath = 'download-path'
}

View File

@@ -1,61 +1,100 @@
import * as os from 'os'
import * as path from 'path'
import * as core from '@actions/core'
import * as artifact from '@actions/artifact'
import * as os from 'os'
import {resolve} from 'path'
import {Inputs, Outputs} from './constants'
const PARALLEL_DOWNLOADS = 5
export const chunk = <T>(arr: T[], n: number): T[][] =>
arr.reduce((acc, cur, i) => {
const index = Math.floor(i / n)
acc[index] = [...(acc[index] || []), cur]
return acc
}, [] as T[][])
async function run(): Promise<void> {
try {
const name = core.getInput(Inputs.Name, {required: false})
const path = core.getInput(Inputs.Path, {required: false})
let resolvedPath
// resolve tilde expansions, path.replace only replaces the first occurrence of a pattern
if (path.startsWith(`~`)) {
resolvedPath = resolve(path.replace('~', os.homedir()))
} else {
resolvedPath = resolve(path)
}
core.debug(`Resolved path is ${resolvedPath}`)
const artifactClient = artifact.create()
if (!name) {
// download all artifacts
core.info('No artifact name specified, downloading all artifacts')
core.info(
'Creating an extra directory for each artifact that is being downloaded'
)
const downloadResponse = await artifactClient.downloadAllArtifacts(
resolvedPath
)
core.info(`There were ${downloadResponse.length} artifacts downloaded`)
for (const artifact of downloadResponse) {
core.info(
`Artifact ${artifact.artifactName} was downloaded to ${artifact.downloadPath}`
)
}
} else {
// download a single artifact
core.info(`Starting download for ${name}`)
const downloadOptions = {
createArtifactFolder: false
}
const downloadResponse = await artifactClient.downloadArtifact(
name,
resolvedPath,
downloadOptions
)
core.info(
`Artifact ${downloadResponse.artifactName} was downloaded to ${downloadResponse.downloadPath}`
)
}
// output the directory that the artifact(s) was/were downloaded to
// if no path is provided, an empty string resolves to the current working directory
core.setOutput(Outputs.DownloadPath, resolvedPath)
core.info('Artifact download has finished successfully')
} catch (err) {
core.setFailed(err.message)
const inputs = {
name: core.getInput(Inputs.Name, {required: false}),
path: core.getInput(Inputs.Path, {required: false}),
token: core.getInput(Inputs.GitHubToken, {required: true}),
repository: core.getInput(Inputs.Repository, {required: true}),
runID: parseInt(core.getInput(Inputs.RunID, {required: true}))
}
if (!inputs.path) {
inputs.path = process.env['GITHUB_WORKSPACE'] || process.cwd()
}
if (inputs.path.startsWith(`~`)) {
inputs.path = inputs.path.replace('~', os.homedir())
}
const resolvedPath = path.resolve(inputs.path)
core.debug(`Resolved path is ${resolvedPath}`)
const [owner, repo] = inputs.repository.split('/')
if (!owner || !repo) {
throw new Error(
`Invalid repository: '${inputs.repository}'. Must be in format owner/repo`
)
}
const artifactClient = artifact.create()
let artifacts: artifact.Artifact[] = []
if (inputs.name) {
const {artifact: targetArtifact} = await artifactClient.getArtifact(
inputs.name,
inputs.runID,
owner,
repo,
inputs.token
)
if (!targetArtifact) {
throw new Error(`Artifact '${inputs.name}' not found`)
}
core.debug(
`Found named artifact '${inputs.name}' (ID: ${targetArtifact.id}, Size: ${targetArtifact.size})`
)
artifacts = [targetArtifact]
} else {
const listArtifactResponse = await artifactClient.listArtifacts(
inputs.runID,
owner,
repo,
inputs.token
)
if (listArtifactResponse.artifacts.length === 0) {
throw new Error(
`No artifacts found for run '${inputs.runID}' in '${inputs.repository}'`
)
}
core.debug(`Found ${listArtifactResponse.artifacts.length} artifacts`)
artifacts = listArtifactResponse.artifacts
}
const downloadPromises = artifacts.map(artifact =>
artifactClient.downloadArtifact(artifact.id, owner, repo, inputs.token, {
path: path.join(resolvedPath, artifact.name)
})
)
const chunkedPromises = chunk(downloadPromises, PARALLEL_DOWNLOADS)
for (const chunk of chunkedPromises) {
await Promise.all(chunk)
}
core.info(`Total of ${artifacts.length} artifact(s) downloaded`)
core.setOutput(Outputs.DownloadPath, resolvedPath)
core.info('Download artifact has finished successfully')
}
run()
run().catch(err =>
core.setFailed(`Unable to download artifact(s): ${err.message}`)
)