mirror of
https://github.com/actions/download-artifact.git
synced 2024-11-22 13:45:28 +00:00
feat: add support for multi artifacts
This commit is contained in:
parent
e9ef242655
commit
e9e49e9bbc
2
.github/workflows/check-dist.yml
vendored
2
.github/workflows/check-dist.yml
vendored
@ -4,7 +4,7 @@
|
|||||||
# For our project, we generate this file through a build process
|
# For our project, we generate this file through a build process
|
||||||
# from other source files.
|
# from other source files.
|
||||||
# We need to make sure the checked-in `index.js` actually matches what we expect it to be.
|
# We need to make sure the checked-in `index.js` actually matches what we expect it to be.
|
||||||
name: Check dist/
|
name: Check dist
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
53
.github/workflows/test.yml
vendored
53
.github/workflows/test.yml
vendored
@ -91,7 +91,56 @@ jobs:
|
|||||||
}
|
}
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|
||||||
# Test downloading both artifacts at once
|
# Test downloading multiple artifacts to the same path
|
||||||
|
- name: Download artifacts A and B to the same path
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
name: |
|
||||||
|
Artifact-A
|
||||||
|
Artifact-B
|
||||||
|
path: some/path/for/multiple/files
|
||||||
|
|
||||||
|
- name: Verify successful download
|
||||||
|
run: |
|
||||||
|
$fileA = "some/path/for/multiple/files/file-A.txt"
|
||||||
|
$fileB = "some/path/for/multiple/files/file-B.txt"
|
||||||
|
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
|
||||||
|
{
|
||||||
|
Write-Error "Expected files do not exist"
|
||||||
|
}
|
||||||
|
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
|
||||||
|
{
|
||||||
|
Write-Error "File contents of downloaded artifacts are incorrect"
|
||||||
|
}
|
||||||
|
shell: pwsh
|
||||||
|
|
||||||
|
# Test downloading multiple artifacts to different paths
|
||||||
|
- name: Download artifacts A and B to different paths
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
name: |
|
||||||
|
Artifact-A
|
||||||
|
Artifact-B
|
||||||
|
path: |
|
||||||
|
some/path/for/a
|
||||||
|
some/path/for/b
|
||||||
|
|
||||||
|
|
||||||
|
- name: Verify successful download
|
||||||
|
run: |
|
||||||
|
$fileA = "some/path/for/a/file-A.txt"
|
||||||
|
$fileB = "some/path/for/b/file-B.txt"
|
||||||
|
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
|
||||||
|
{
|
||||||
|
Write-Error "Expected files do not exist"
|
||||||
|
}
|
||||||
|
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
|
||||||
|
{
|
||||||
|
Write-Error "File contents of downloaded artifacts are incorrect"
|
||||||
|
}
|
||||||
|
shell: pwsh
|
||||||
|
|
||||||
|
# Test downloading all artifacts
|
||||||
- name: Download all Artifacts
|
- name: Download all Artifacts
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
@ -110,5 +159,3 @@ jobs:
|
|||||||
Write-Error "File contents of downloaded artifacts are incorrect"
|
Write-Error "File contents of downloaded artifacts are incorrect"
|
||||||
}
|
}
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|
||||||
|
|
66
dist/index.js
vendored
66
dist/index.js
vendored
@ -9496,12 +9496,12 @@ function wrappy (fn, cb) {
|
|||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
var Inputs;
|
var Inputs;
|
||||||
(function (Inputs) {
|
(function (Inputs) {
|
||||||
Inputs["Name"] = "name";
|
Inputs["Names"] = "name";
|
||||||
Inputs["Path"] = "path";
|
Inputs["Paths"] = "path";
|
||||||
})(Inputs = exports.Inputs || (exports.Inputs = {}));
|
})(Inputs = exports.Inputs || (exports.Inputs = {}));
|
||||||
var Outputs;
|
var Outputs;
|
||||||
(function (Outputs) {
|
(function (Outputs) {
|
||||||
Outputs["DownloadPath"] = "download-path";
|
Outputs["DownloadPaths"] = "download-path";
|
||||||
})(Outputs = exports.Outputs || (exports.Outputs = {}));
|
})(Outputs = exports.Outputs || (exports.Outputs = {}));
|
||||||
|
|
||||||
|
|
||||||
@ -9534,11 +9534,8 @@ const artifact = __importStar(__nccwpck_require__(2605));
|
|||||||
const os = __importStar(__nccwpck_require__(2037));
|
const os = __importStar(__nccwpck_require__(2037));
|
||||||
const path_1 = __nccwpck_require__(1017);
|
const path_1 = __nccwpck_require__(1017);
|
||||||
const constants_1 = __nccwpck_require__(9042);
|
const constants_1 = __nccwpck_require__(9042);
|
||||||
function run() {
|
function downloadArtifact(name, path) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
|
||||||
const name = core.getInput(constants_1.Inputs.Name, { required: false });
|
|
||||||
const path = core.getInput(constants_1.Inputs.Path, { required: false });
|
|
||||||
let resolvedPath;
|
let resolvedPath;
|
||||||
// resolve tilde expansions, path.replace only replaces the first occurrence of a pattern
|
// resolve tilde expansions, path.replace only replaces the first occurrence of a pattern
|
||||||
if (path.startsWith(`~`)) {
|
if (path.startsWith(`~`)) {
|
||||||
@ -9570,8 +9567,61 @@ function run() {
|
|||||||
}
|
}
|
||||||
// output the directory that the artifact(s) was/were downloaded to
|
// 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
|
// if no path is provided, an empty string resolves to the current working directory
|
||||||
core.setOutput(constants_1.Outputs.DownloadPath, resolvedPath);
|
|
||||||
core.info('Artifact download has finished successfully');
|
core.info('Artifact download has finished successfully');
|
||||||
|
return resolvedPath;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function run() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
try {
|
||||||
|
const names = core.getMultilineInput(constants_1.Inputs.Names, { required: false });
|
||||||
|
const paths = core.getMultilineInput(constants_1.Inputs.Paths, { required: false });
|
||||||
|
core.info(`names: '${JSON.stringify(names)}' | length: ${names.length}`);
|
||||||
|
core.info(`paths: '${JSON.stringify(paths)}' | length: ${paths.length}`);
|
||||||
|
let downloadPaths = [];
|
||||||
|
// Names is set and has fewer entries than Paths
|
||||||
|
if (names.length !== 0 && paths.length > names.length) {
|
||||||
|
throw Error(`The input 'path' cannot have more entries than 'name', if 'name' is set.`);
|
||||||
|
}
|
||||||
|
// Names is NOT set and Paths has more than 1 entry
|
||||||
|
else if (names.length === 0 && paths.length > 1) {
|
||||||
|
throw Error(`The input 'path' cannot have more than one entry, if 'name' is not set.`);
|
||||||
|
}
|
||||||
|
// Names is NOT set and path has at max 1 entry: download all artifacts
|
||||||
|
else if (names.length === 0 && paths.length <= 1) {
|
||||||
|
const name = names.toString(); // ''
|
||||||
|
const path = paths.toString(); // '' or 'some/path'
|
||||||
|
const downloadPath = yield downloadArtifact(name, path);
|
||||||
|
downloadPaths.push(downloadPath);
|
||||||
|
}
|
||||||
|
// Names has one or more entries and Paths has at max 1 entry
|
||||||
|
else if (names.length >= 1 && paths.length <= 1) {
|
||||||
|
const path = paths.toString(); // '' or 'some/path'
|
||||||
|
names.forEach((name) => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const downloadPath = yield downloadArtifact(name, path);
|
||||||
|
downloadPaths.push(downloadPath);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
// Names and Paths have the same numbers of entries (more than 1)
|
||||||
|
else if (names.length > 1 &&
|
||||||
|
paths.length > 1 &&
|
||||||
|
names.length === paths.length) {
|
||||||
|
names.forEach((name, index) => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const path = paths[index];
|
||||||
|
const downloadPath = yield downloadArtifact(name, path);
|
||||||
|
downloadPaths.push(downloadPath);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
// Unhandled exception
|
||||||
|
else {
|
||||||
|
throw Error(`Unhandled scenario. This shouldn't happen. It's very likely a bug. :-()`);
|
||||||
|
}
|
||||||
|
// Remove duplicates and empty strings
|
||||||
|
downloadPaths = [...new Set(downloadPaths.filter(path => path !== ''))];
|
||||||
|
// Returns a newline-separated list of paths
|
||||||
|
const output = downloadPaths.join('\n');
|
||||||
|
// output the directory that the artifact(s) was/were downloaded to
|
||||||
|
core.setOutput(constants_1.Outputs.DownloadPaths, output);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
core.setFailed(err.message);
|
core.setFailed(err.message);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export enum Inputs {
|
export enum Inputs {
|
||||||
Name = 'name',
|
Names = 'name',
|
||||||
Path = 'path'
|
Paths = 'path'
|
||||||
}
|
}
|
||||||
export enum Outputs {
|
export enum Outputs {
|
||||||
DownloadPath = 'download-path'
|
DownloadPaths = 'download-path'
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,7 @@ import * as os from 'os'
|
|||||||
import {resolve} from 'path'
|
import {resolve} from 'path'
|
||||||
import {Inputs, Outputs} from './constants'
|
import {Inputs, Outputs} from './constants'
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
async function downloadArtifact(name: string, path: string): Promise<string> {
|
||||||
try {
|
|
||||||
const name = core.getInput(Inputs.Name, {required: false})
|
|
||||||
const path = core.getInput(Inputs.Path, {required: false})
|
|
||||||
|
|
||||||
let resolvedPath
|
let resolvedPath
|
||||||
// resolve tilde expansions, path.replace only replaces the first occurrence of a pattern
|
// resolve tilde expansions, path.replace only replaces the first occurrence of a pattern
|
||||||
if (path.startsWith(`~`)) {
|
if (path.startsWith(`~`)) {
|
||||||
@ -51,8 +47,75 @@ async function run(): Promise<void> {
|
|||||||
}
|
}
|
||||||
// output the directory that the artifact(s) was/were downloaded to
|
// 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
|
// 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')
|
core.info('Artifact download has finished successfully')
|
||||||
|
|
||||||
|
return resolvedPath
|
||||||
|
}
|
||||||
|
|
||||||
|
async function run(): Promise<void> {
|
||||||
|
try {
|
||||||
|
const names = core.getMultilineInput(Inputs.Names, {required: false})
|
||||||
|
const paths = core.getMultilineInput(Inputs.Paths, {required: false})
|
||||||
|
|
||||||
|
core.info(`names: '${JSON.stringify(names)}' | length: ${names.length}`)
|
||||||
|
core.info(`paths: '${JSON.stringify(paths)}' | length: ${paths.length}`)
|
||||||
|
|
||||||
|
let downloadPaths: string[] = []
|
||||||
|
|
||||||
|
// Names is set and has fewer entries than Paths
|
||||||
|
if (names.length !== 0 && paths.length > names.length) {
|
||||||
|
throw Error(
|
||||||
|
`The input 'path' cannot have more entries than 'name', if 'name' is set.`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// Names is NOT set and Paths has more than 1 entry
|
||||||
|
else if (names.length === 0 && paths.length > 1) {
|
||||||
|
throw Error(
|
||||||
|
`The input 'path' cannot have more than one entry, if 'name' is not set.`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// Names is NOT set and path has at max 1 entry: download all artifacts
|
||||||
|
else if (names.length === 0 && paths.length <= 1) {
|
||||||
|
const name = names.toString() // ''
|
||||||
|
const path = paths.toString() // '' or 'some/path'
|
||||||
|
const downloadPath = await downloadArtifact(name, path)
|
||||||
|
downloadPaths.push(downloadPath)
|
||||||
|
}
|
||||||
|
// Names has one or more entries and Paths has at max 1 entry
|
||||||
|
else if (names.length >= 1 && paths.length <= 1) {
|
||||||
|
const path = paths.toString() // '' or 'some/path'
|
||||||
|
names.forEach(async name => {
|
||||||
|
const downloadPath = await downloadArtifact(name, path)
|
||||||
|
downloadPaths.push(downloadPath)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// Names and Paths have the same numbers of entries (more than 1)
|
||||||
|
else if (
|
||||||
|
names.length > 1 &&
|
||||||
|
paths.length > 1 &&
|
||||||
|
names.length === paths.length
|
||||||
|
) {
|
||||||
|
names.forEach(async (name, index) => {
|
||||||
|
const path = paths[index]
|
||||||
|
const downloadPath = await downloadArtifact(name, path)
|
||||||
|
downloadPaths.push(downloadPath)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// Unhandled exception
|
||||||
|
else {
|
||||||
|
throw Error(
|
||||||
|
`Unhandled scenario. This shouldn't happen. It's very likely a bug. :-()`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove duplicates and empty strings
|
||||||
|
downloadPaths = [...new Set(downloadPaths.filter(path => path !== ''))]
|
||||||
|
|
||||||
|
// Returns a newline-separated list of paths
|
||||||
|
const output = downloadPaths.join('\n')
|
||||||
|
|
||||||
|
// output the directory that the artifact(s) was/were downloaded to
|
||||||
|
core.setOutput(Outputs.DownloadPaths, output)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
core.setFailed(err.message)
|
core.setFailed(err.message)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user