feat: add support for multi artifacts

This commit is contained in:
Rafael Abreu 2023-02-16 18:55:01 +00:00
parent e9ef242655
commit e9e49e9bbc
5 changed files with 245 additions and 85 deletions

View file

@ -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:

View file

@ -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

118
dist/index.js vendored
View file

@ -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,44 +9534,94 @@ 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 downloadArtifact(name, path) {
return __awaiter(this, void 0, void 0, function* () {
let resolvedPath;
// resolve tilde expansions, path.replace only replaces the first occurrence of a pattern
if (path.startsWith(`~`)) {
resolvedPath = path_1.resolve(path.replace('~', os.homedir()));
}
else {
resolvedPath = path_1.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 = yield 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 = yield 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.info('Artifact download has finished successfully');
return resolvedPath;
});
}
function run() { function run() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
try { try {
const name = core.getInput(constants_1.Inputs.Name, { required: false }); const names = core.getMultilineInput(constants_1.Inputs.Names, { required: false });
const path = core.getInput(constants_1.Inputs.Path, { required: false }); const paths = core.getMultilineInput(constants_1.Inputs.Paths, { required: false });
let resolvedPath; core.info(`names: '${JSON.stringify(names)}' | length: ${names.length}`);
// resolve tilde expansions, path.replace only replaces the first occurrence of a pattern core.info(`paths: '${JSON.stringify(paths)}' | length: ${paths.length}`);
if (path.startsWith(`~`)) { let downloadPaths = [];
resolvedPath = path_1.resolve(path.replace('~', os.homedir())); // 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 { else {
resolvedPath = path_1.resolve(path); throw Error(`Unhandled scenario. This shouldn't happen. It's very likely a bug. :-()`);
}
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 = yield 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 = yield artifactClient.downloadArtifact(name, resolvedPath, downloadOptions);
core.info(`Artifact ${downloadResponse.artifactName} was downloaded to ${downloadResponse.downloadPath}`);
} }
// 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 // 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(constants_1.Outputs.DownloadPaths, output);
core.setOutput(constants_1.Outputs.DownloadPath, resolvedPath);
core.info('Artifact download has finished successfully');
} }
catch (err) { catch (err) {
core.setFailed(err.message); core.setFailed(err.message);

View file

@ -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'
} }

View file

@ -4,55 +4,118 @@ 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 downloadArtifact(name: string, path: string): Promise<string> {
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.info('Artifact download has finished successfully')
return resolvedPath
}
async function run(): Promise<void> { async function run(): Promise<void> {
try { try {
const name = core.getInput(Inputs.Name, {required: false}) const names = core.getMultilineInput(Inputs.Names, {required: false})
const path = core.getInput(Inputs.Path, {required: false}) const paths = core.getMultilineInput(Inputs.Paths, {required: false})
let resolvedPath core.info(`names: '${JSON.stringify(names)}' | length: ${names.length}`)
// resolve tilde expansions, path.replace only replaces the first occurrence of a pattern core.info(`paths: '${JSON.stringify(paths)}' | length: ${paths.length}`)
if (path.startsWith(`~`)) {
resolvedPath = resolve(path.replace('~', os.homedir()))
} else {
resolvedPath = resolve(path)
}
core.debug(`Resolved path is ${resolvedPath}`)
const artifactClient = artifact.create() let downloadPaths: string[] = []
if (!name) {
// download all artifacts // Names is set and has fewer entries than Paths
core.info('No artifact name specified, downloading all artifacts') if (names.length !== 0 && paths.length > names.length) {
core.info( throw Error(
'Creating an extra directory for each artifact that is being downloaded' `The input 'path' cannot have more entries than 'name', if 'name' is set.`
)
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}`
) )
} }
// 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 // 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.DownloadPaths, output)
core.setOutput(Outputs.DownloadPath, resolvedPath)
core.info('Artifact download has finished successfully')
} catch (err) { } catch (err) {
core.setFailed(err.message) core.setFailed(err.message)
} }