From 731ed00a7565285908f731fc137825de5eabd3db Mon Sep 17 00:00:00 2001 From: Konrad Pabjan Date: Thu, 30 Apr 2020 16:00:01 +0200 Subject: [PATCH] Add extra option to create a folder during download --- .github/workflows/test.yml | 58 +++++++++++++++++------------------ README.md | 32 ++++++++++++++++++- action.yml | 3 ++ package-lock.json | 56 ++++++++++++++++----------------- package.json | 6 ++-- scripts/test-artifact-file.sh | 25 +++++++++++++++ src/constants.ts | 3 +- src/download-artifact.ts | 15 +++++++-- 8 files changed, 133 insertions(+), 65 deletions(-) create mode 100644 scripts/test-artifact-file.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 18d9fb9..b43b09b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -42,12 +42,17 @@ jobs: # Test end-to-end by uploading two artifacts and then downloading them # 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 run: | mkdir -p path/to/artifact-A mkdir -p path/to/artifact-B - echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt - echo "Hello world from file B" > path/to/artifact-B/file-B.txt + echo ${{ env.non-gzip-artifact-content }} > path/to/artifact-A/file-A.txt + echo ${{ env.gzip-artifact-content }} > path/to/artifact-B/file-B.txt - name: Upload artifact A uses: actions/upload-artifact@v1 @@ -61,25 +66,28 @@ jobs: name: 'Artifact-B' path: path/to/artifact-B - # Test downloading a single artifact - - name: Download artifact A + - name: Download artifact A with no extra folder (default) uses: ./ with: 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: | - $file = "some/new/path/file-A.txt" - if(!(Test-Path -path $file)) - { - Write-Error "Expected file does not exist" - } - if(!((Get-Content $file) -ceq "Lorem ipsum dolor sit amet")) - { - Write-Error "File contents of downloaded artifact are incorrect" - } - shell: pwsh + scripts/test-artifact-file.sh "download/with/artifact-folder/false/file-A.txt" "${{ env.non-gzip-artifact-content }}" + + - name: Download artifact A with create-folder set to true + uses: ./ + with: + name: 'Artifact-A' + path: download/with/artifact-folder/true + artifact-folder: true + + - 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 - name: Download all Artifacts @@ -87,18 +95,8 @@ jobs: with: path: some/other/path - - name: Verify successful download + - name: Verify downloadAllArtifacts() + shell: bash run: | - $fileA = "some/other/path/Artifact-A/file-A.txt" - $fileB = "some/other/path/Artifact-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 - - \ No newline at end of file + scripts/test-artifact-file.sh "some/other/path/Artifact-A/file-A.txt" "${{ env.non-gzip-artifact-content }}" + scripts/test-artifact-file.sh "some/other/path/Artifact-B/file-B.txt" "${{ env.gzip-artifact-content }}" \ No newline at end of file diff --git a/README.md b/README.md index 2015d45..8092f64 100644 --- a/README.md +++ b/README.md @@ -44,9 +44,39 @@ steps: run: ls -R 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 -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: ``` diff --git a/action.yml b/action.yml index ac7205a..b040c9e 100644 --- a/action.yml +++ b/action.yml @@ -8,6 +8,9 @@ inputs: path: description: 'Destination path' required: false + artifact-folder: + description: 'Denotes if an extra directory is created for any artifacts that are downloaded' + default: 'false' runs: using: 'node12' main: 'dist/index.js' \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6aaf493..655370f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -223,33 +223,33 @@ } }, "@typescript-eslint/parser": { - "version": "2.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.27.0.tgz", - "integrity": "sha512-HFUXZY+EdwrJXZo31DW4IS1ujQW3krzlRjBrFRrJcMDh0zCu107/nRfhk/uBasO8m0NVDbBF5WZKcIUMRO7vPg==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.30.0.tgz", + "integrity": "sha512-9kDOxzp0K85UnpmPJqUzdWaCNorYYgk1yZmf4IKzpeTlSAclnFsrLjfwD9mQExctLoLoGAUXq1co+fbr+3HeFw==", "dev": true, "requires": { "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "2.27.0", - "@typescript-eslint/typescript-estree": "2.27.0", + "@typescript-eslint/experimental-utils": "2.30.0", + "@typescript-eslint/typescript-estree": "2.30.0", "eslint-visitor-keys": "^1.1.0" }, "dependencies": { "@typescript-eslint/experimental-utils": { - "version": "2.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.27.0.tgz", - "integrity": "sha512-vOsYzjwJlY6E0NJRXPTeCGqjv5OHgRU1kzxHKWJVPjDYGbPgLudBXjIlc+OD1hDBZ4l1DLbOc5VjofKahsu9Jw==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.30.0.tgz", + "integrity": "sha512-L3/tS9t+hAHksy8xuorhOzhdefN0ERPDWmR9CclsIGOUqGKy6tqc/P+SoXeJRye5gazkuPO0cK9MQRnolykzkA==", "dev": true, "requires": { "@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-utils": "^2.0.0" } }, "@typescript-eslint/typescript-estree": { - "version": "2.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.27.0.tgz", - "integrity": "sha512-t2miCCJIb/FU8yArjAvxllxbTiyNqaXJag7UOpB5DVoM3+xnjeOngtqlJkLRnMtzaRcJhe3CIR9RmL40omubhg==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.30.0.tgz", + "integrity": "sha512-nI5WOechrA0qAhnr+DzqwmqHsx7Ulr/+0H7bWCcClDhhWkSyZR5BmTvnBEyONwJCTWHfc5PAQExX24VD26IAVw==", "dev": true, "requires": { "debug": "^4.1.1", @@ -543,9 +543,9 @@ "dev": true }, "concurrently": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.1.0.tgz", - "integrity": "sha512-9ViZMu3OOCID3rBgU31mjBftro2chOop0G2u1olq1OuwRBVRw/GxHTg80TVJBUTJfoswMmEUeuOg1g1yu1X2dA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.2.0.tgz", + "integrity": "sha512-XxcDbQ4/43d6CxR7+iV8IZXhur4KbmEJk1CetVMUqCy34z9l0DkszbY+/9wvmSnToTej0SYomc2WSRH+L0zVJw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -614,9 +614,9 @@ "dev": true }, "date-fns": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.9.0.tgz", - "integrity": "sha512-khbFLu/MlzLjEzy9Gh8oY1hNt/Dvxw3J6Rbc28cVoYWQaC1S3YI4xwkF9ZWcjDLscbZlY9hISMr66RFzZagLsA==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.12.0.tgz", + "integrity": "sha512-qJgn99xxKnFgB1qL4jpxU7Q2t0LOn1p8KMIveef3UZD7kqjT3tpFNNdXJelEHhE+rUgffriXriw/sOSU+cS1Hw==", "dev": true }, "debug": { @@ -2007,9 +2007,9 @@ "dev": true }, "prettier": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.4.tgz", - "integrity": "sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", "dev": true }, "prettier-linter-helpers": { @@ -2692,9 +2692,9 @@ "dev": true }, "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", @@ -2706,7 +2706,7 @@ "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" + "yargs-parser": "^13.1.2" }, "dependencies": { "emoji-regex": { @@ -2735,9 +2735,9 @@ } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/package.json b/package.json index 0388caf..c42c037 100644 --- a/package.json +++ b/package.json @@ -30,12 +30,12 @@ "devDependencies": { "@actions/artifact": "^0.3.1", "@actions/core": "^1.2.3", - "@typescript-eslint/parser": "^2.27.0", + "@typescript-eslint/parser": "^2.30.0", "@zeit/ncc": "^0.22.1", - "concurrently": "^5.1.0", + "concurrently": "^5.2.0", "eslint": "^6.8.0", "eslint-plugin-github": "^3.4.1", - "prettier": "^2.0.4", + "prettier": "^2.0.5", "typescript": "^3.8.3" } } diff --git a/scripts/test-artifact-file.sh b/scripts/test-artifact-file.sh new file mode 100644 index 0000000..83c9ac5 --- /dev/null +++ b/scripts/test-artifact-file.sh @@ -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 \ No newline at end of file diff --git a/src/constants.ts b/src/constants.ts index e40cfda..5be0983 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,4 +1,5 @@ export enum Inputs { Name = 'name', - Path = 'path' + Path = 'path', + ArtifactFolder = 'artifact-folder' } diff --git a/src/download-artifact.ts b/src/download-artifact.ts index 1721d2f..96389f9 100644 --- a/src/download-artifact.ts +++ b/src/download-artifact.ts @@ -6,10 +6,21 @@ async function run(): Promise { try { const name = core.getInput(Inputs.Name, {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() 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) core.info(`There were ${downloadResponse.length} artifacts downloaded`) for (const artifact of downloadResponse) { @@ -20,7 +31,7 @@ async function run(): Promise { } else { // download a single artifact const downloadOptions = { - createArtifactFolder: false + createArtifactFolder: isFolderCreated } const downloadResponse = await artifactClient.downloadArtifact( name,