Compare commits

..

2 Commits

7 changed files with 58 additions and 277 deletions
-47
View File
@@ -1,47 +0,0 @@
name: "Code scanning - action"
on:
push:
paths-ignore:
- '**.md'
schedule:
- cron: '0 11 * * 5'
jobs:
CodeQL-Build:
strategy:
fail-fast: false
# CodeQL runs on ubuntu-latest and windows-latest
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
-112
View File
@@ -1,112 +0,0 @@
name: Test
on:
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build
strategy:
matrix:
runs-on: [ubuntu-latest, macos-latest, windows-latest]
fail-fast: false
runs-on: ${{ matrix.runs-on }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set Node.js 12.x
uses: actions/setup-node@v1
with:
node-version: 12.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
# Test end-to-end by uploading two artifacts and then downloading them
# Once upload-artifact v2 is out of preview, switch over
- 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
- name: Upload artifact A
uses: actions/upload-artifact@v1
with:
name: 'Artifact-A'
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v1
with:
name: 'Artifact-B'
path: path/to/artifact-B
# Test downloading a single artifact
- name: Download artifact A
uses: ./
with:
name: 'Artifact-A'
path: some/new/path
# Test downloading an artifact using tilde expansion
- name: Download artifact A
uses: ./
with:
name: 'Artifact-A'
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
# Test downloading both artifacts at once
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
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
+2 -34
View File
@@ -46,14 +46,6 @@ steps:
working-directory: path/to/artifact
```
Basic tilde expansion is supported for the `path` input:
```yaml
- uses: actions/download-artifact@v2
with:
name: my-artifact
path: ~/download/path
```
## Compatibility between `v1` and `v2`
When using `download-artifact@v1`, a directory denoted by the name of the artifact would be created if the `path` input was not provided. All of the contents would be downloaded to this directory.
@@ -135,34 +127,10 @@ steps:
> Note: The `id` defined in the `download/artifact` step must match the `id` defined in the `echo` step (i.e `steps.[ID].outputs.download-path`)
# Limitations
### Permission Loss
:exclamation: File permissions are not maintained during artifact upload :exclamation: For example, if you make a file executable using `chmod` and then upload that file, post-download the file is no longer guaranteed to be set as an executable.
### Case Insensitive Uploads
:exclamation: File uploads are case insensitive :exclamation: If you upload `A.txt` and `a.txt` with the same root path, only a single file will be saved and available during download.
### Maintaining file permissions and case sensitive files
If file permissions and case sensitivity are required, you can `tar` all of your files together before artifact upload. Post download, the `tar` file will maintain file permissions and case sensitivity.
```yaml
- name: 'Tar files'
run: tar -cvf my_files.tar /path/to/my/directory
- name: 'Upload Artifact'
uses: actions/upload-artifact@v2
with:
name: my-artifact
path: my_files.tar
```
# @actions/artifact package
Internally the [@actions/artifact](https://github.com/actions/toolkit/tree/main/packages/artifact) NPM package is used to interact with artifacts. You can find additional documentation there along with all the source code related to artifact download.
Internally the [@actions/artifact](https://github.com/actions/toolkit/tree/master/packages/artifact) NPM package is used to interact with artifacts. You can find additional documentation there along with all the source code related to artifact download.
# License
+43 -59
View File
@@ -3509,6 +3509,7 @@ class DefaultArtifactClient {
});
}
downloadArtifact(name, path, options) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
const downloadHttpClient = new download_http_client_1.DownloadHttpClient();
const artifacts = yield downloadHttpClient.listArtifacts();
@@ -3528,7 +3529,7 @@ class DefaultArtifactClient {
path = path_1.normalize(path);
path = path_1.resolve(path);
// During upload, empty directories are rejected by the remote server so there should be no artifacts that consist of only empty directories
const downloadSpecification = download_specification_1.getDownloadSpecification(name, items.value, path, (options === null || options === void 0 ? void 0 : options.createArtifactFolder) || false);
const downloadSpecification = download_specification_1.getDownloadSpecification(name, items.value, path, ((_a = options) === null || _a === void 0 ? void 0 : _a.createArtifactFolder) || false);
if (downloadSpecification.filesToDownload.length === 0) {
core.info(`No downloadable files were found for the artifact: ${artifactToDownload.name}`);
}
@@ -3602,7 +3603,7 @@ exports.getUploadFileConcurrency = getUploadFileConcurrency;
// When uploading large files that can't be uploaded with a single http call, this controls
// the chunk size that is used during upload
function getUploadChunkSize() {
return 8 * 1024 * 1024; // 8 MB Chunks
return 4 * 1024 * 1024; // 4 MB Chunks
}
exports.getUploadChunkSize = getUploadChunkSize;
// The maximum number of retries that can be attempted before an upload or download fails
@@ -4556,12 +4557,11 @@ const utils_1 = __webpack_require__(870);
* Used for managing http clients during either upload or download
*/
class HttpManager {
constructor(clientCount, userAgent) {
constructor(clientCount) {
if (clientCount < 1) {
throw new Error('There must be at least one client');
}
this.userAgent = userAgent;
this.clients = new Array(clientCount).fill(utils_1.createHttpClient(userAgent));
this.clients = new Array(clientCount).fill(utils_1.createHttpClient());
}
getClient(index) {
return this.clients[index];
@@ -4570,7 +4570,7 @@ class HttpManager {
// for more information see: https://github.com/actions/http-client/blob/04e5ad73cd3fd1f5610a32116b0759eddf6570d2/index.ts#L292
disposeAndReplaceClient(index) {
this.clients[index].dispose();
this.clients[index] = utils_1.createHttpClient(this.userAgent);
this.clients[index] = utils_1.createHttpClient();
}
disposeAndReplaceAllClients() {
for (const [index] of this.clients.entries()) {
@@ -5929,7 +5929,7 @@ const upload_gzip_1 = __webpack_require__(647);
const stat = util_1.promisify(fs.stat);
class UploadHttpClient {
constructor() {
this.uploadHttpManager = new http_manager_1.HttpManager(config_variables_1.getUploadFileConcurrency(), '@actions/artifact-upload');
this.uploadHttpManager = new http_manager_1.HttpManager(config_variables_1.getUploadFileConcurrency());
this.statusReporter = new status_reporter_1.StatusReporter(10000);
}
/**
@@ -5947,8 +5947,8 @@ class UploadHttpClient {
const artifactUrl = utils_1.getArtifactUrl();
// use the first client from the httpManager, `keep-alive` is not used so the connection will close immediately
const client = this.uploadHttpManager.getClient(0);
const headers = utils_1.getUploadHeaders('application/json', false);
const rawResponse = yield client.post(artifactUrl, data, headers);
const requestOptions = utils_1.getUploadRequestOptions('application/json', false);
const rawResponse = yield client.post(artifactUrl, data, requestOptions);
const body = yield rawResponse.readBody();
if (utils_1.isSuccessStatusCode(rawResponse.message.statusCode) && body) {
return JSON.parse(body);
@@ -6060,25 +6060,21 @@ class UploadHttpClient {
// for creating a new GZip file, an in-memory buffer is used for compression
if (totalFileSize < 65536) {
const buffer = yield upload_gzip_1.createGZipFileInBuffer(parameters.file);
//An open stream is needed in the event of a failure and we need to retry. If a NodeJS.ReadableStream is directly passed in,
// it will not properly get reset to the start of the stream if a chunk upload needs to be retried
let openUploadStream;
let uploadStream;
if (totalFileSize < buffer.byteLength) {
// compression did not help with reducing the size, use a readable stream from the original file for upload
openUploadStream = () => fs.createReadStream(parameters.file);
uploadStream = fs.createReadStream(parameters.file);
isGzip = false;
uploadFileSize = totalFileSize;
}
else {
// create a readable stream using a PassThrough stream that is both readable and writable
openUploadStream = () => {
const passThrough = new stream.PassThrough();
passThrough.end(buffer);
return passThrough;
};
const passThrough = new stream.PassThrough();
passThrough.end(buffer);
uploadStream = passThrough;
uploadFileSize = buffer.byteLength;
}
const result = yield this.uploadChunk(httpClientIndex, parameters.resourceUrl, openUploadStream, 0, uploadFileSize - 1, uploadFileSize, isGzip, totalFileSize);
const result = yield this.uploadChunk(httpClientIndex, parameters.resourceUrl, uploadStream, 0, uploadFileSize - 1, uploadFileSize, isGzip, totalFileSize);
if (!result) {
// chunk failed to upload
isUploadSuccessful = false;
@@ -6120,7 +6116,7 @@ class UploadHttpClient {
failedChunkSizes += chunkSize;
continue;
}
const result = yield this.uploadChunk(httpClientIndex, parameters.resourceUrl, () => fs.createReadStream(uploadFilePath, {
const result = yield this.uploadChunk(httpClientIndex, parameters.resourceUrl, fs.createReadStream(uploadFilePath, {
start,
end,
autoClose: false
@@ -6150,7 +6146,7 @@ class UploadHttpClient {
* indicates a retryable status, we try to upload the chunk as well
* @param {number} httpClientIndex The index of the httpClient being used to make all the necessary calls
* @param {string} resourceUrl Url of the resource that the chunk will be uploaded to
* @param {NodeJS.ReadableStream} openStream Stream of the file that will be uploaded
* @param {NodeJS.ReadableStream} data Stream of the file that will be uploaded
* @param {number} start Starting byte index of file that the chunk belongs to
* @param {number} end Ending byte index of file that the chunk belongs to
* @param {number} uploadFileSize Total size of the file in bytes that is being uploaded
@@ -6158,13 +6154,13 @@ class UploadHttpClient {
* @param {number} totalFileSize Original total size of the file that is being uploaded
* @returns if the chunk was successfully uploaded
*/
uploadChunk(httpClientIndex, resourceUrl, openStream, start, end, uploadFileSize, isGzip, totalFileSize) {
uploadChunk(httpClientIndex, resourceUrl, data, start, end, uploadFileSize, isGzip, totalFileSize) {
return __awaiter(this, void 0, void 0, function* () {
// prepare all the necessary headers before making any http call
const headers = utils_1.getUploadHeaders('application/octet-stream', true, isGzip, totalFileSize, end - start + 1, utils_1.getContentRange(start, end, uploadFileSize));
const requestOptions = utils_1.getUploadRequestOptions('application/octet-stream', true, isGzip, totalFileSize, end - start + 1, utils_1.getContentRange(start, end, uploadFileSize));
const uploadChunkRequest = () => __awaiter(this, void 0, void 0, function* () {
const client = this.uploadHttpManager.getClient(httpClientIndex);
return yield client.sendStream('PUT', resourceUrl, openStream(), headers);
return yield client.sendStream('PUT', resourceUrl, data, requestOptions);
});
let retryCount = 0;
const retryLimit = config_variables_1.getRetryLimit();
@@ -6242,7 +6238,7 @@ class UploadHttpClient {
*/
patchArtifactSize(size, artifactName) {
return __awaiter(this, void 0, void 0, function* () {
const headers = utils_1.getUploadHeaders('application/json', false);
const requestOptions = utils_1.getUploadRequestOptions('application/json', false);
const resourceUrl = new url_1.URL(utils_1.getArtifactUrl());
resourceUrl.searchParams.append('artifactName', artifactName);
const parameters = { Size: size };
@@ -6250,7 +6246,7 @@ class UploadHttpClient {
core.debug(`URL is ${resourceUrl.toString()}`);
// use the first client from the httpManager, `keep-alive` is not used so the connection will close immediately
const client = this.uploadHttpManager.getClient(0);
const response = yield client.patch(resourceUrl.toString(), data, headers);
const response = yield client.patch(resourceUrl.toString(), data, requestOptions);
const body = yield response.readBody();
if (utils_1.isSuccessStatusCode(response.message.statusCode)) {
core.debug(`Artifact ${artifactName} has been successfully uploaded, total size in bytes: ${size}`);
@@ -6638,7 +6634,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(__webpack_require__(470));
const artifact = __importStar(__webpack_require__(214));
const os = __importStar(__webpack_require__(87));
const path_1 = __webpack_require__(622);
const constants_1 = __webpack_require__(694);
function run() {
@@ -6646,21 +6641,12 @@ function run() {
try {
const name = core.getInput(constants_1.Inputs.Name, { required: false });
const path = core.getInput(constants_1.Inputs.Path, { required: false });
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);
const downloadResponse = yield artifactClient.downloadAllArtifacts(path);
core.info(`There were ${downloadResponse.length} artifacts downloaded`);
for (const artifact of downloadResponse) {
core.info(`Artifact ${artifact.artifactName} was downloaded to ${artifact.downloadPath}`);
@@ -6672,12 +6658,12 @@ function run() {
const downloadOptions = {
createArtifactFolder: false
};
const downloadResponse = yield artifactClient.downloadArtifact(name, resolvedPath, downloadOptions);
const downloadResponse = yield artifactClient.downloadArtifact(name, path, 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(constants_1.Outputs.DownloadPath, resolvedPath);
core.setOutput(constants_1.Outputs.DownloadPath, path_1.resolve(path));
core.info('Artifact download has finished successfully');
}
catch (err) {
@@ -6730,7 +6716,7 @@ const http_manager_1 = __webpack_require__(452);
const config_variables_1 = __webpack_require__(401);
class DownloadHttpClient {
constructor() {
this.downloadHttpManager = new http_manager_1.HttpManager(config_variables_1.getDownloadFileConcurrency(), '@actions/artifact-download');
this.downloadHttpManager = new http_manager_1.HttpManager(config_variables_1.getDownloadFileConcurrency());
// downloads are usually significantly faster than uploads so display status information every second
this.statusReporter = new status_reporter_1.StatusReporter(1000);
}
@@ -6742,8 +6728,8 @@ class DownloadHttpClient {
const artifactUrl = utils_1.getArtifactUrl();
// use the first client from the httpManager, `keep-alive` is not used so the connection will close immediately
const client = this.downloadHttpManager.getClient(0);
const headers = utils_1.getDownloadHeaders('application/json');
const response = yield client.get(artifactUrl, headers);
const requestOptions = utils_1.getDownloadRequestOptions('application/json');
const response = yield client.get(artifactUrl, requestOptions);
const body = yield response.readBody();
if (utils_1.isSuccessStatusCode(response.message.statusCode) && body) {
return JSON.parse(body);
@@ -6764,8 +6750,8 @@ class DownloadHttpClient {
resourceUrl.searchParams.append('itemPath', artifactName);
// use the first client from the httpManager, `keep-alive` is not used so the connection will close immediately
const client = this.downloadHttpManager.getClient(0);
const headers = utils_1.getDownloadHeaders('application/json');
const response = yield client.get(resourceUrl.toString(), headers);
const requestOptions = utils_1.getDownloadRequestOptions('application/json');
const response = yield client.get(resourceUrl.toString(), requestOptions);
const body = yield response.readBody();
if (utils_1.isSuccessStatusCode(response.message.statusCode) && body) {
return JSON.parse(body);
@@ -6822,16 +6808,15 @@ class DownloadHttpClient {
let retryCount = 0;
const retryLimit = config_variables_1.getRetryLimit();
const destinationStream = fs.createWriteStream(downloadPath);
const headers = utils_1.getDownloadHeaders('application/json', true, true);
const requestOptions = utils_1.getDownloadRequestOptions('application/json', true, true);
// a single GET request is used to download a file
const makeDownloadRequest = () => __awaiter(this, void 0, void 0, function* () {
const client = this.downloadHttpManager.getClient(httpClientIndex);
return yield client.get(artifactLocation, headers);
return yield client.get(artifactLocation, requestOptions);
});
// check the response headers to determine if the file was compressed using gzip
const isGzip = (incomingHeaders) => {
return ('content-encoding' in incomingHeaders &&
incomingHeaders['content-encoding'] === 'gzip');
const isGzip = (headers) => {
return ('content-encoding' in headers && headers['content-encoding'] === 'gzip');
};
// Increments the current retry count and then checks if the retry limit has been reached
// If there have been too many retries, fail so the download stops. If there is a retryAfterValue value provided,
@@ -7260,8 +7245,7 @@ function isRetryableStatusCode(statusCode) {
http_client_1.HttpCodes.BadGateway,
http_client_1.HttpCodes.ServiceUnavailable,
http_client_1.HttpCodes.GatewayTimeout,
http_client_1.HttpCodes.TooManyRequests,
413 // Payload Too Large
http_client_1.HttpCodes.TooManyRequests
];
return retryableStatusCodes.includes(statusCode);
}
@@ -7308,9 +7292,9 @@ exports.getContentRange = getContentRange;
* @param {boolean} isKeepAlive is the same connection being used to make multiple calls
* @param {boolean} acceptGzip can we accept a gzip encoded response
* @param {string} acceptType the type of content that we can accept
* @returns appropriate headers to make a specific http call during artifact download
* @returns appropriate request options to make a specific http call during artifact download
*/
function getDownloadHeaders(contentType, isKeepAlive, acceptGzip) {
function getDownloadRequestOptions(contentType, isKeepAlive, acceptGzip) {
const requestOptions = {};
if (contentType) {
requestOptions['Content-Type'] = contentType;
@@ -7331,7 +7315,7 @@ function getDownloadHeaders(contentType, isKeepAlive, acceptGzip) {
}
return requestOptions;
}
exports.getDownloadHeaders = getDownloadHeaders;
exports.getDownloadRequestOptions = getDownloadRequestOptions;
/**
* Sets all the necessary headers when uploading an artifact
* @param {string} contentType the type of content being uploaded
@@ -7340,9 +7324,9 @@ exports.getDownloadHeaders = getDownloadHeaders;
* @param {number} uncompressedLength the original size of the content if something is being uploaded that has been compressed
* @param {number} contentLength the length of the content that is being uploaded
* @param {string} contentRange the range of the content that is being uploaded
* @returns appropriate headers to make a specific http call during artifact upload
* @returns appropriate request options to make a specific http call during artifact upload
*/
function getUploadHeaders(contentType, isKeepAlive, isGzip, uncompressedLength, contentLength, contentRange) {
function getUploadRequestOptions(contentType, isKeepAlive, isGzip, uncompressedLength, contentLength, contentRange) {
const requestOptions = {};
requestOptions['Accept'] = `application/json;api-version=${getApiVersion()}`;
if (contentType) {
@@ -7365,9 +7349,9 @@ function getUploadHeaders(contentType, isKeepAlive, isGzip, uncompressedLength,
}
return requestOptions;
}
exports.getUploadHeaders = getUploadHeaders;
function createHttpClient(userAgent) {
return new http_client_1.HttpClient(userAgent, [
exports.getUploadRequestOptions = getUploadRequestOptions;
function createHttpClient() {
return new http_client_1.HttpClient('action/artifact', [
new auth_1.BearerCredentialHandler(config_variables_1.getRuntimeToken())
]);
}
+9 -9
View File
@@ -5,9 +5,9 @@
"requires": true,
"dependencies": {
"@actions/artifact": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-0.3.5.tgz",
"integrity": "sha512-y27pBEnUjOqCP2zUf86YkiqGOp1r0C9zUOmGmcxizsHMls0wvk+FJwd+l8JIoukvj1BeBHYP+c+9AEqOt5AqMA==",
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-0.3.1.tgz",
"integrity": "sha512-czRvOioOpuvmF/qDevfVVpZeBt7pjYlrnmM1+tRuCpKJxjWFYgi5MIW7TfscyupXPvtJz9jIxMjvxy9Eug1QEA==",
"dev": true,
"requires": {
"@actions/core": "^1.2.1",
@@ -1782,9 +1782,9 @@
}
},
"lodash": {
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
},
"loose-envify": {
@@ -2627,9 +2627,9 @@
}
},
"tmp-promise": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-2.1.1.tgz",
"integrity": "sha512-Z048AOz/w9b6lCbJUpevIJpRpUztENl8zdv1bmAKVHimfqRFl92ROkmT9rp7TVBnrEw2gtMTol/2Cp2S2kJa4Q==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-2.0.2.tgz",
"integrity": "sha512-zl71nFWjPKW2KXs+73gEk8RmqvtAeXPxhWDkTUoa3MSMkjq3I+9OeknjF178MQoMYsdqL730hfzvNfEkePxq9Q==",
"dev": true,
"requires": {
"tmp": "0.1.0"
+1 -1
View File
@@ -28,7 +28,7 @@
},
"homepage": "https://github.com/actions/download-artifact#readme",
"devDependencies": {
"@actions/artifact": "^0.3.5",
"@actions/artifact": "^0.3.1",
"@actions/core": "^1.2.4",
"@types/node": "^12.12.6",
"@typescript-eslint/parser": "^2.30.0",
+3 -15
View File
@@ -1,6 +1,5 @@
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'
@@ -9,15 +8,6 @@ async function run(): Promise<void> {
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
@@ -25,9 +15,7 @@ async function run(): Promise<void> {
core.info(
'Creating an extra directory for each artifact that is being downloaded'
)
const downloadResponse = await artifactClient.downloadAllArtifacts(
resolvedPath
)
const downloadResponse = await artifactClient.downloadAllArtifacts(path)
core.info(`There were ${downloadResponse.length} artifacts downloaded`)
for (const artifact of downloadResponse) {
core.info(
@@ -42,7 +30,7 @@ async function run(): Promise<void> {
}
const downloadResponse = await artifactClient.downloadArtifact(
name,
resolvedPath,
path,
downloadOptions
)
core.info(
@@ -51,7 +39,7 @@ async function run(): Promise<void> {
}
// 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.setOutput(Outputs.DownloadPath, resolve(path))
core.info('Artifact download has finished successfully')
} catch (err) {
core.setFailed(err.message)