Add extra option to create a folder during download

This commit is contained in:
Konrad Pabjan 2020-04-30 16:00:01 +02:00
parent 1de1dea89c
commit 731ed00a75
8 changed files with 133 additions and 65 deletions

View file

@ -42,12 +42,17 @@ jobs:
# Test end-to-end by uploading two artifacts and then downloading them # Test end-to-end by uploading two artifacts and then downloading them
# Once upload-artifact v2 is out of preview, switch over # Once upload-artifact v2 is out of preview, switch over
- name: Set artifact file contents
run: |
echo "::set-env name=non-gzip-artifact-content::hello"
echo "::set-env name=gzip-artifact-content::Some large amount of text that has a compression ratio that is greater than 100%. If greater than 100%, gzip is used to upload the file"
- name: Create artifacts - name: Create artifacts
run: | run: |
mkdir -p path/to/artifact-A mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt echo ${{ env.non-gzip-artifact-content }} > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt echo ${{ env.gzip-artifact-content }} > path/to/artifact-B/file-B.txt
- name: Upload artifact A - name: Upload artifact A
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v1
@ -61,25 +66,28 @@ jobs:
name: 'Artifact-B' name: 'Artifact-B'
path: path/to/artifact-B path: path/to/artifact-B
# Test downloading a single artifact - name: Download artifact A with no extra folder (default)
- name: Download artifact A
uses: ./ uses: ./
with: with:
name: 'Artifact-A' name: 'Artifact-A'
path: some/new/path path: download/with/artifact-folder/false
- name: Verify successful download - name: Verify successful download with no extra folder
shell: bash
run: | run: |
$file = "some/new/path/file-A.txt" scripts/test-artifact-file.sh "download/with/artifact-folder/false/file-A.txt" "${{ env.non-gzip-artifact-content }}"
if(!(Test-Path -path $file))
{ - name: Download artifact A with create-folder set to true
Write-Error "Expected file does not exist" uses: ./
} with:
if(!((Get-Content $file) -ceq "Lorem ipsum dolor sit amet")) name: 'Artifact-A'
{ path: download/with/artifact-folder/true
Write-Error "File contents of downloaded artifact are incorrect" artifact-folder: true
}
shell: pwsh - name: Verify successful download with an extra folder
shell: bash
run: |
scripts/test-artifact-file.sh "download/with/artifact-folder/true/Artifact-A/file-A.txt" "${{ env.non-gzip-artifact-content }}"
# Test downloading both artifacts at once # Test downloading both artifacts at once
- name: Download all Artifacts - name: Download all Artifacts
@ -87,18 +95,8 @@ jobs:
with: with:
path: some/other/path path: some/other/path
- name: Verify successful download - name: Verify downloadAllArtifacts()
shell: bash
run: | run: |
$fileA = "some/other/path/Artifact-A/file-A.txt" scripts/test-artifact-file.sh "some/other/path/Artifact-A/file-A.txt" "${{ env.non-gzip-artifact-content }}"
$fileB = "some/other/path/Artifact-B/file-B.txt" scripts/test-artifact-file.sh "some/other/path/Artifact-B/file-B.txt" "${{ env.gzip-artifact-content }}"
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

View file

@ -44,9 +44,39 @@ steps:
run: ls -R run: ls -R
working-directory: path/to/artifact working-directory: path/to/artifact
``` ```
Download an artifact and create an extra directory
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/download-artifact@v2
with:
name: my-artifact
path: path/to/artifact
artifact-folder: true
- name: Display structure of downloaded files
run: ls -R
working-directory: path/to/artifact
```
If `artifact-folder` is set to `true`. An extra directory denoted by the name of the artifact will be created
```
path/to/artifact/
my-artifact/
... contents of my-artifact
```
If `artifact-folder` is set to `false` (the default), there will be no extra folder created
```
path/to/artifact/
... contents of my-artifact
```
# Download All Artifacts # Download All Artifacts
If the `name` input parameter is not provided, all artifacts will be downloaded. To differentiate between downloaded artifacts, a directory denoted by the artifacts name will be created for each individual artifact. If the `name` input parameter is not provided, all artifacts will be downloaded. To differentiate between downloaded artifacts, a directory denoted by the artifacts name will be created for each individual artifact. Currently the `artifact-folder` input-parameter is not respected when downloading all artifacts.
Example, if there are two artifacts `Artifact-A` and `Artifact-B`, and the directory is `etc/usr/artifacts/`, the directory structure will look like this: Example, if there are two artifacts `Artifact-A` and `Artifact-B`, and the directory is `etc/usr/artifacts/`, the directory structure will look like this:
``` ```

View file

@ -8,6 +8,9 @@ inputs:
path: path:
description: 'Destination path' description: 'Destination path'
required: false required: false
artifact-folder:
description: 'Denotes if an extra directory is created for any artifacts that are downloaded'
default: 'false'
runs: runs:
using: 'node12' using: 'node12'
main: 'dist/index.js' main: 'dist/index.js'

56
package-lock.json generated
View file

@ -223,33 +223,33 @@
} }
}, },
"@typescript-eslint/parser": { "@typescript-eslint/parser": {
"version": "2.27.0", "version": "2.30.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.27.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.30.0.tgz",
"integrity": "sha512-HFUXZY+EdwrJXZo31DW4IS1ujQW3krzlRjBrFRrJcMDh0zCu107/nRfhk/uBasO8m0NVDbBF5WZKcIUMRO7vPg==", "integrity": "sha512-9kDOxzp0K85UnpmPJqUzdWaCNorYYgk1yZmf4IKzpeTlSAclnFsrLjfwD9mQExctLoLoGAUXq1co+fbr+3HeFw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/eslint-visitor-keys": "^1.0.0", "@types/eslint-visitor-keys": "^1.0.0",
"@typescript-eslint/experimental-utils": "2.27.0", "@typescript-eslint/experimental-utils": "2.30.0",
"@typescript-eslint/typescript-estree": "2.27.0", "@typescript-eslint/typescript-estree": "2.30.0",
"eslint-visitor-keys": "^1.1.0" "eslint-visitor-keys": "^1.1.0"
}, },
"dependencies": { "dependencies": {
"@typescript-eslint/experimental-utils": { "@typescript-eslint/experimental-utils": {
"version": "2.27.0", "version": "2.30.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.27.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.30.0.tgz",
"integrity": "sha512-vOsYzjwJlY6E0NJRXPTeCGqjv5OHgRU1kzxHKWJVPjDYGbPgLudBXjIlc+OD1hDBZ4l1DLbOc5VjofKahsu9Jw==", "integrity": "sha512-L3/tS9t+hAHksy8xuorhOzhdefN0ERPDWmR9CclsIGOUqGKy6tqc/P+SoXeJRye5gazkuPO0cK9MQRnolykzkA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/json-schema": "^7.0.3", "@types/json-schema": "^7.0.3",
"@typescript-eslint/typescript-estree": "2.27.0", "@typescript-eslint/typescript-estree": "2.30.0",
"eslint-scope": "^5.0.0", "eslint-scope": "^5.0.0",
"eslint-utils": "^2.0.0" "eslint-utils": "^2.0.0"
} }
}, },
"@typescript-eslint/typescript-estree": { "@typescript-eslint/typescript-estree": {
"version": "2.27.0", "version": "2.30.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.27.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.30.0.tgz",
"integrity": "sha512-t2miCCJIb/FU8yArjAvxllxbTiyNqaXJag7UOpB5DVoM3+xnjeOngtqlJkLRnMtzaRcJhe3CIR9RmL40omubhg==", "integrity": "sha512-nI5WOechrA0qAhnr+DzqwmqHsx7Ulr/+0H7bWCcClDhhWkSyZR5BmTvnBEyONwJCTWHfc5PAQExX24VD26IAVw==",
"dev": true, "dev": true,
"requires": { "requires": {
"debug": "^4.1.1", "debug": "^4.1.1",
@ -543,9 +543,9 @@
"dev": true "dev": true
}, },
"concurrently": { "concurrently": {
"version": "5.1.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.1.0.tgz", "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.2.0.tgz",
"integrity": "sha512-9ViZMu3OOCID3rBgU31mjBftro2chOop0G2u1olq1OuwRBVRw/GxHTg80TVJBUTJfoswMmEUeuOg1g1yu1X2dA==", "integrity": "sha512-XxcDbQ4/43d6CxR7+iV8IZXhur4KbmEJk1CetVMUqCy34z9l0DkszbY+/9wvmSnToTej0SYomc2WSRH+L0zVJw==",
"dev": true, "dev": true,
"requires": { "requires": {
"chalk": "^2.4.2", "chalk": "^2.4.2",
@ -614,9 +614,9 @@
"dev": true "dev": true
}, },
"date-fns": { "date-fns": {
"version": "2.9.0", "version": "2.12.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.9.0.tgz", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.12.0.tgz",
"integrity": "sha512-khbFLu/MlzLjEzy9Gh8oY1hNt/Dvxw3J6Rbc28cVoYWQaC1S3YI4xwkF9ZWcjDLscbZlY9hISMr66RFzZagLsA==", "integrity": "sha512-qJgn99xxKnFgB1qL4jpxU7Q2t0LOn1p8KMIveef3UZD7kqjT3tpFNNdXJelEHhE+rUgffriXriw/sOSU+cS1Hw==",
"dev": true "dev": true
}, },
"debug": { "debug": {
@ -2007,9 +2007,9 @@
"dev": true "dev": true
}, },
"prettier": { "prettier": {
"version": "2.0.4", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.4.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz",
"integrity": "sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w==", "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==",
"dev": true "dev": true
}, },
"prettier-linter-helpers": { "prettier-linter-helpers": {
@ -2692,9 +2692,9 @@
"dev": true "dev": true
}, },
"yargs": { "yargs": {
"version": "13.3.0", "version": "13.3.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
"integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
"dev": true, "dev": true,
"requires": { "requires": {
"cliui": "^5.0.0", "cliui": "^5.0.0",
@ -2706,7 +2706,7 @@
"string-width": "^3.0.0", "string-width": "^3.0.0",
"which-module": "^2.0.0", "which-module": "^2.0.0",
"y18n": "^4.0.0", "y18n": "^4.0.0",
"yargs-parser": "^13.1.1" "yargs-parser": "^13.1.2"
}, },
"dependencies": { "dependencies": {
"emoji-regex": { "emoji-regex": {
@ -2735,9 +2735,9 @@
} }
}, },
"yargs-parser": { "yargs-parser": {
"version": "13.1.1", "version": "13.1.2",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
"integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
"dev": true, "dev": true,
"requires": { "requires": {
"camelcase": "^5.0.0", "camelcase": "^5.0.0",

View file

@ -30,12 +30,12 @@
"devDependencies": { "devDependencies": {
"@actions/artifact": "^0.3.1", "@actions/artifact": "^0.3.1",
"@actions/core": "^1.2.3", "@actions/core": "^1.2.3",
"@typescript-eslint/parser": "^2.27.0", "@typescript-eslint/parser": "^2.30.0",
"@zeit/ncc": "^0.22.1", "@zeit/ncc": "^0.22.1",
"concurrently": "^5.1.0", "concurrently": "^5.2.0",
"eslint": "^6.8.0", "eslint": "^6.8.0",
"eslint-plugin-github": "^3.4.1", "eslint-plugin-github": "^3.4.1",
"prettier": "^2.0.4", "prettier": "^2.0.5",
"typescript": "^3.8.3" "typescript": "^3.8.3"
} }
} }

View file

@ -0,0 +1,25 @@
#!/bin/bash
path="$1"
expectedContent="$2"
if [ "$path" == "" ]; then
echo "File path not provided"
exit 1
fi
if [ "$expectedContent" == "" ]; then
echo "Expected file contents not provided"
exit 1
fi
if [ ! -f "$path" ]; then
echo "Expected file $path does not exist"
exit 1
fi
actualContent=$(cat $path)
if [ "$actualContent" != "$expectedContent" ];then
echo "File contents are not correct, expected $expectedContent, recieved $actualContent"
exit 1
fi

View file

@ -1,4 +1,5 @@
export enum Inputs { export enum Inputs {
Name = 'name', Name = 'name',
Path = 'path' Path = 'path',
ArtifactFolder = 'artifact-folder'
} }

View file

@ -6,10 +6,21 @@ async function run(): Promise<void> {
try { try {
const name = core.getInput(Inputs.Name, {required: false}) const name = core.getInput(Inputs.Name, {required: false})
const path = core.getInput(Inputs.Path, {required: false}) const path = core.getInput(Inputs.Path, {required: false})
const artifactFolder = core.getInput(Inputs.ArtifactFolder, {
required: false
})
// parse string input to a boolean
const isFolderCreated = artifactFolder.toLocaleLowerCase() === 'true'
const artifactClient = artifact.create() const artifactClient = artifact.create()
if (!name) { if (!name) {
// download all artifacts /** Download all artifacts at once
*
* When downloading all artifacts at once, a separate folder gets created for each artifact. There is currently no option to use
* the artifactFolder input to specify if a folder should or should not be created for each artifact. Some extra work will have to be done
* in the @actions/artifact package
*/
const downloadResponse = await artifactClient.downloadAllArtifacts(path) const downloadResponse = await artifactClient.downloadAllArtifacts(path)
core.info(`There were ${downloadResponse.length} artifacts downloaded`) core.info(`There were ${downloadResponse.length} artifacts downloaded`)
for (const artifact of downloadResponse) { for (const artifact of downloadResponse) {
@ -20,7 +31,7 @@ async function run(): Promise<void> {
} else { } else {
// download a single artifact // download a single artifact
const downloadOptions = { const downloadOptions = {
createArtifactFolder: false createArtifactFolder: isFolderCreated
} }
const downloadResponse = await artifactClient.downloadArtifact( const downloadResponse = await artifactClient.downloadArtifact(
name, name,