Compare commits

...

17 Commits

Author SHA1 Message Date
Rob Herley
1de464352c Sync migration docs with upload-artifact
We've updated them quite a bit in upload-artifact so let's make sure we're consistent.
2024-01-31 12:36:02 -05:00
Rob Herley
bb3fa7fd35 Merge pull request #275 from actions/robherley/better-log-msgs
Clarify log messages when using `pattern` or `merge-multiple` params
2024-01-10 16:00:02 -05:00
Rob Herley
a244de5a62 ncc 2024-01-10 15:17:47 -05:00
Rob Herley
355659bff2 clarify log messages when using pattern/merge-multiple params 2024-01-10 15:15:52 -05:00
Vallie Joseph
6b208ae046 Merge pull request #274 from actions/vmjoseph/timeout-patch
Add patch fix for transient timeout issues from new artifact's package
2024-01-10 12:01:10 -05:00
Vallie Joseph
6c5b5806e1 only adding updated license 2024-01-10 16:49:33 +00:00
Vallie Joseph
5f5015dc38 readding index 2024-01-10 16:48:45 +00:00
Vallie Joseph
1fddaaf0f1 Revert "updating licenses"
This reverts commit 657edd9b81.
2024-01-10 16:48:01 +00:00
Vallie Joseph
8aa9e2115b Revert "updating dist"
This reverts commit 555a2fc129.
2024-01-10 16:47:16 +00:00
Vallie Joseph
657edd9b81 updating licenses 2024-01-10 16:44:54 +00:00
Vallie Joseph
555a2fc129 updating dist 2024-01-10 16:18:33 +00:00
Vallie Joseph
4fc4d70d4c updating lock 2024-01-10 16:12:36 +00:00
Vallie Joseph
072ac9dceb updating version no 2024-01-10 16:00:45 +00:00
Vallie Joseph
038dc0329f updating version no 2024-01-10 15:59:40 +00:00
Vallie Joseph
3f40cd641f updating release 2024-01-10 15:58:28 +00:00
Vallie Joseph
82c243c150 updating artifacts package 2024-01-10 15:31:35 +00:00
Rob Herley
f44cd7b40b Merge pull request #259 from actions/robherley/glob-downloads
Support pattern matching to filter artifacts & merge to same directory
2023-12-18 17:22:01 -05:00
6 changed files with 199 additions and 24 deletions

View File

@@ -1,9 +1,9 @@
---
name: "@actions/artifact"
version: 2.0.0
version: 2.0.1
type: npm
summary: Actions artifact lib
homepage: https://github.com/actions/toolkit/tree/main/packages/artifact
summary:
homepage:
license: mit
licenses:
- sources: LICENSE.md

52
dist/index.js vendored
View File

@@ -2005,7 +2005,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.downloadArtifactInternal = exports.downloadArtifactPublic = void 0;
exports.downloadArtifactInternal = exports.downloadArtifactPublic = exports.streamExtractExternal = void 0;
const promises_1 = __importDefault(__nccwpck_require__(73292));
const github = __importStar(__nccwpck_require__(95438));
const core = __importStar(__nccwpck_require__(42186));
@@ -2039,20 +2039,57 @@ function exists(path) {
});
}
function streamExtract(url, directory) {
return __awaiter(this, void 0, void 0, function* () {
let retryCount = 0;
while (retryCount < 5) {
try {
yield streamExtractExternal(url, directory);
return;
}
catch (error) {
retryCount++;
core.debug(`Failed to download artifact after ${retryCount} retries due to ${error.message}. Retrying in 5 seconds...`);
// wait 5 seconds before retrying
yield new Promise(resolve => setTimeout(resolve, 5000));
}
}
throw new Error(`Artifact download failed after ${retryCount} retries.`);
});
}
function streamExtractExternal(url, directory) {
return __awaiter(this, void 0, void 0, function* () {
const client = new httpClient.HttpClient((0, user_agent_1.getUserAgentString)());
const response = yield client.get(url);
if (response.message.statusCode !== 200) {
throw new Error(`Unexpected HTTP response from blob storage: ${response.message.statusCode} ${response.message.statusMessage}`);
}
const timeout = 30 * 1000; // 30 seconds
return new Promise((resolve, reject) => {
const timerFn = () => {
response.message.destroy(new Error(`Blob storage chunk did not respond in ${timeout}ms`));
};
const timer = setTimeout(timerFn, timeout);
response.message
.on('data', () => {
timer.refresh();
})
.on('error', (error) => {
core.debug(`response.message: Artifact download failed: ${error.message}`);
clearTimeout(timer);
reject(error);
})
.pipe(unzip_stream_1.default.Extract({ path: directory }))
.on('close', resolve)
.on('error', reject);
.on('close', () => {
clearTimeout(timer);
resolve();
})
.on('error', (error) => {
reject(error);
});
});
});
}
exports.streamExtractExternal = streamExtractExternal;
function downloadArtifactPublic(artifactId, repositoryOwner, repositoryName, token, options) {
return __awaiter(this, void 0, void 0, function* () {
const downloadPath = yield resolveOrCreateDirectory(options === null || options === void 0 ? void 0 : options.path);
@@ -121076,7 +121113,6 @@ function run() {
artifacts = [targetArtifact];
}
else {
core.info(`No input name specified, downloading all artifacts. Extra directory with the artifact name will be created for each download`);
const listArtifactResponse = yield artifact_1.default.listArtifacts(Object.assign({ latest: true }, options));
artifacts = listArtifactResponse.artifacts;
core.debug(`Found ${artifacts.length} artifacts in run`);
@@ -121086,6 +121122,12 @@ function run() {
artifacts = artifacts.filter(artifact => matcher.match(artifact.name));
core.debug(`Filtered from ${listArtifactResponse.artifacts.length} to ${artifacts.length} artifacts`);
}
else {
core.info('No input name or pattern filtered specified, downloading all artifacts');
if (!inputs.mergeMultiple) {
core.info('An extra directory with the artifact name will be created for each download');
}
}
}
if (artifacts.length) {
core.info(`Preparing to download the following artifacts:`);
@@ -124851,7 +124893,7 @@ exports.unescape = unescape;
/***/ ((module) => {
"use strict";
module.exports = JSON.parse('{"name":"@actions/artifact","version":"2.0.0","preview":true,"description":"Actions artifact lib","keywords":["github","actions","artifact"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/artifact","license":"MIT","main":"lib/artifact.js","types":"lib/artifact.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/artifact"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"cd ../../ && npm run test ./packages/artifact","bootstrap":"cd ../../ && npm run bootstrap","tsc-run":"tsc","tsc":"npm run bootstrap && npm run tsc-run","gen:docs":"typedoc --plugin typedoc-plugin-markdown --out docs/generated src/artifact.ts --githubPages false --readme none"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^1.10.0","@actions/github":"^5.1.1","@actions/http-client":"^2.1.0","@azure/storage-blob":"^12.15.0","@octokit/core":"^3.5.1","@octokit/plugin-request-log":"^1.0.4","@octokit/plugin-retry":"^3.0.9","@octokit/request-error":"^5.0.0","@protobuf-ts/plugin":"^2.2.3-alpha.1","archiver":"^5.3.1","crypto":"^1.0.1","jwt-decode":"^3.1.2","twirp-ts":"^2.5.0","unzip-stream":"^0.3.1"},"devDependencies":{"@types/archiver":"^5.3.2","@types/unzip-stream":"^0.3.4","typedoc":"^0.25.4","typedoc-plugin-markdown":"^3.17.1","typescript":"^5.2.2"}}');
module.exports = JSON.parse('{"name":"@actions/artifact","version":"2.0.1","preview":true,"description":"Actions artifact lib","keywords":["github","actions","artifact"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/artifact","license":"MIT","main":"lib/artifact.js","types":"lib/artifact.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/artifact"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"cd ../../ && npm run test ./packages/artifact","bootstrap":"cd ../../ && npm run bootstrap","tsc-run":"tsc","tsc":"npm run bootstrap && npm run tsc-run","gen:docs":"typedoc --plugin typedoc-plugin-markdown --out docs/generated src/artifact.ts --githubPages false --readme none"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^1.10.0","@actions/github":"^5.1.1","@actions/http-client":"^2.1.0","@azure/storage-blob":"^12.15.0","@octokit/core":"^3.5.1","@octokit/plugin-request-log":"^1.0.4","@octokit/plugin-retry":"^3.0.9","@octokit/request-error":"^5.0.0","@protobuf-ts/plugin":"^2.2.3-alpha.1","archiver":"^5.3.1","crypto":"^1.0.1","jwt-decode":"^3.1.2","twirp-ts":"^2.5.0","unzip-stream":"^0.3.1"},"devDependencies":{"@types/archiver":"^5.3.2","@types/unzip-stream":"^0.3.4","typedoc":"^0.25.4","typedoc-plugin-markdown":"^3.17.1","typescript":"^5.2.2"}}');
/***/ }),

View File

@@ -2,6 +2,8 @@
- [Migration](#migration)
- [Multiple uploads to the same named Artifact](#multiple-uploads-to-the-same-named-artifact)
- [Overwriting an Artifact](#overwriting-an-artifact)
- [Merging multiple artifacts](#merging-multiple-artifacts)
Several behavioral differences exist between Artifact actions `v3` and below vs `v4`. This document outlines common scenarios in `v3`, and how they would be handled in `v4`.
@@ -31,6 +33,7 @@ jobs:
- name: Download All Artifacts
uses: actions/download-artifact@v3
with:
name: my-artifact
path: my-artifact
- run: ls -R my-artifact
```
@@ -71,6 +74,7 @@ jobs:
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
- name: my-artifact
path: my-artifact
+ pattern: my-artifact-*
+ merge-multiple: true
@@ -78,3 +82,127 @@ jobs:
```
In `v4`, the new `pattern:` input will filter the downloaded Artifacts to match the name specified. The new `merge-multiple:` input will support downloading multiple Artifacts to the same directory. If the files within the Artifacts have the same name, the last writer wins.
## Overwriting an Artifact
In `v3`, the contents of an Artifact were mutable so something like the following was possible:
```yaml
jobs:
upload:
runs-on: ubuntu-latest
steps:
- name: Create a file
run: echo "hello world" > my-file.txt
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: my-artifact # NOTE: same artifact name
path: my-file.txt
upload-again:
needs: upload
runs-on: ubuntu-latest
steps:
- name: Create a different file
run: echo "goodbye world" > my-file.txt
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: my-artifact # NOTE: same artifact name
path: my-file.txt
```
The resulting `my-file.txt` in `my-artifact` will have "goodbye world" as the content.
In `v4`, Artifacts are immutable unless deleted. To achieve this same behavior, you can use `overwrite: true` to delete the Artifact before a new one is created:
```diff
jobs:
upload:
runs-on: ubuntu-latest
steps:
- name: Create a file
run: echo "hello world" > my-file.txt
- name: Upload Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: my-artifact # NOTE: same artifact name
path: my-file.txt
upload-again:
needs: upload
runs-on: ubuntu-latest
steps:
- name: Create a different file
run: echo "goodbye world" > my-file.txt
- name: Upload Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: my-artifact # NOTE: same artifact name
path: my-file.txt
+ overwrite: true
```
Note that this will create an _entirely_ new Artifact, with a different ID from the previous.
## Merging multiple artifacts
In `v3`, multiple uploads from multiple jobs could be done to the same Artifact. This would result in a single archive, which could be useful for sending to upstream systems outside of Actions via API or UI downloads.
```yaml
jobs:
upload:
strategy:
matrix:
runs-on: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.runs-on }}
steps:
- name: Create a File
run: echo "hello from ${{ matrix.runs-on }}" > file-${{ matrix.runs-on }}.txt
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: all-my-files # NOTE: same artifact name
path: file-${{ matrix.runs-on }}.txt
```
The single `all-my-files` artifact would contain the following:
```
.
∟ file-ubuntu-latest.txt
∟ file-macos-latest.txt
∟ file-windows-latest.txt
```
To achieve the same in `v4` you can change it like so:
```diff
jobs:
upload:
strategy:
matrix:
runs-on: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.runs-on }}
steps:
- name: Create a File
run: echo "hello from ${{ matrix.runs-on }}" > file-${{ matrix.runs-on }}.txt
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
- name: all-my-files
+ name: my-artifact-${{ matrix.runs-on }}
path: file-${{ matrix.runs-on }}.txt
+ merge:
+ runs-on: ubuntu-latest
+ needs: upload
+ steps:
+ - name: Merge Artifacts
+ uses: actions/upload-artifact/merge@v4
+ with:
+ name: all-my-files
+ pattern: my-artifact-*
```
Note that this will download all artifacts to a temporary directory and reupload them as a single artifact. For more information on inputs and other use cases for `actions/upload-artifact/merge@v4`, see [the action documentation](../merge/README.md).

18
package-lock.json generated
View File

@@ -1,15 +1,15 @@
{
"name": "download-artifact",
"version": "4.0.0",
"version": "4.0.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "download-artifact",
"version": "4.0.0",
"version": "4.0.1",
"license": "MIT",
"dependencies": {
"@actions/artifact": "^2.0.0",
"@actions/artifact": "^2.0.1",
"@actions/core": "^1.10.0",
"@actions/github": "^5.1.1",
"minimatch": "^9.0.3"
@@ -36,9 +36,9 @@
}
},
"node_modules/@actions/artifact": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-2.0.0.tgz",
"integrity": "sha512-rr1yJ7/2c4i/OdQ9G0MXJfV4svPgqe+UfNWOK2+jZghTVJatJJAlJskJFK+RqzTyX8qn6CWgG/w7tJRNDzNnhQ==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-2.0.1.tgz",
"integrity": "sha512-MGgWRU4n4yoGQ5NbfwKWl3whSuFG/ll2FZ1au+jAiOIykKk+dnTFMuiklomsD6yx56ZnkQTVa/0Se5N0T0f6Nw==",
"dependencies": {
"@actions/core": "^1.10.0",
"@actions/github": "^5.1.1",
@@ -5862,9 +5862,9 @@
"dev": true
},
"@actions/artifact": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-2.0.0.tgz",
"integrity": "sha512-rr1yJ7/2c4i/OdQ9G0MXJfV4svPgqe+UfNWOK2+jZghTVJatJJAlJskJFK+RqzTyX8qn6CWgG/w7tJRNDzNnhQ==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-2.0.1.tgz",
"integrity": "sha512-MGgWRU4n4yoGQ5NbfwKWl3whSuFG/ll2FZ1au+jAiOIykKk+dnTFMuiklomsD6yx56ZnkQTVa/0Se5N0T0f6Nw==",
"requires": {
"@actions/core": "^1.10.0",
"@actions/github": "^5.1.1",

View File

@@ -1,6 +1,6 @@
{
"name": "download-artifact",
"version": "4.0.0",
"version": "4.0.1",
"description": "Download an Actions Artifact from a workflow run",
"main": "dist/index.js",
"scripts": {
@@ -28,7 +28,7 @@
},
"homepage": "https://github.com/actions/download-artifact#readme",
"dependencies": {
"@actions/artifact": "^2.0.0",
"@actions/artifact": "^2.0.1",
"@actions/core": "^1.10.0",
"@actions/github": "^5.1.1",
"minimatch": "^9.0.3"
@@ -44,4 +44,4 @@
"prettier": "^3.1.1",
"typescript": "^5.3.3"
}
}
}

View File

@@ -75,10 +75,6 @@ async function run(): Promise<void> {
artifacts = [targetArtifact]
} else {
core.info(
`No input name specified, downloading all artifacts. Extra directory with the artifact name will be created for each download`
)
const listArtifactResponse = await artifactClient.listArtifacts({
latest: true,
...options
@@ -94,6 +90,15 @@ async function run(): Promise<void> {
core.debug(
`Filtered from ${listArtifactResponse.artifacts.length} to ${artifacts.length} artifacts`
)
} else {
core.info(
'No input name or pattern filtered specified, downloading all artifacts'
)
if (!inputs.mergeMultiple) {
core.info(
'An extra directory with the artifact name will be created for each download'
)
}
}
}