mirror of
https://github.com/actions/download-artifact.git
synced 2025-08-21 23:30:07 +08:00
Compare commits
60 Commits
vmjoseph/t
...
v4.2.0
Author | SHA1 | Date | |
---|---|---|---|
|
b14cf4c926 | ||
|
c5804ef743 | ||
|
956811a503 | ||
|
af3c6d3e5b | ||
|
4dd97f8f21 | ||
|
da9985dde6 | ||
|
81ba80daa4 | ||
|
727afbf2b0 | ||
|
56c2d7ea8c | ||
|
7797bfcd59 | ||
|
9ff67cb2d2 | ||
|
049eba1e9a | ||
|
503e7a18ae | ||
|
a8a786b097 | ||
|
24aef17bbf | ||
|
b81a615862 | ||
|
cc20338598 | ||
|
1fc0fee191 | ||
|
7fba95161a | ||
|
f9ceb7763b | ||
|
533298bc57 | ||
|
d06289e120 | ||
|
d0ce8fd116 | ||
|
1ce0d91ace | ||
|
fa0a91b85d | ||
|
b54d0883e1 | ||
|
65a9edc588 | ||
|
fdd1595981 | ||
|
c13dba102f | ||
|
0daa75ebea | ||
|
9c19ed7fe5 | ||
|
3d3ea8741e | ||
|
89af5db821 | ||
|
b4aefff88e | ||
|
8caf195ad4 | ||
|
d7a2ec411d | ||
|
e56a1d48ef | ||
|
1fcda58b3a | ||
|
325a10d8b7 | ||
|
f8aaee4a21 | ||
|
d98334b11d | ||
|
c850b930e6 | ||
|
6fd111f15a | ||
|
87c55149d9 | ||
|
47f9ce604f | ||
|
127824d34c | ||
|
6dd49bff0a | ||
|
f71c0e3da3 | ||
|
7c63dfde29 | ||
|
67d37cd346 | ||
|
348754975e | ||
|
eaceaf801f | ||
|
81eafdc926 | ||
|
9ac5cad9e2 | ||
|
3ad8411bbd | ||
|
1de464352c | ||
|
bb3fa7fd35 | ||
|
a244de5a62 | ||
|
355659bff2 | ||
|
6b208ae046 |
20
.github/workflows/publish-immutable-actions.yml
vendored
Normal file
20
.github/workflows/publish-immutable-actions.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
name: 'Publish Immutable Action Version'
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
id-token: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checking out
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Publish
|
||||||
|
id: publish
|
||||||
|
uses: actions/publish-immutable-action@0.0.3
|
@@ -21,7 +21,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Update the ${{ env.TAG_NAME }} tag
|
- name: Update the ${{ env.TAG_NAME }} tag
|
||||||
uses: actions/publish-action@v0.2.1
|
uses: actions/publish-action@v0.3.0
|
||||||
with:
|
with:
|
||||||
source-tag: ${{ env.TAG_NAME }}
|
source-tag: ${{ env.TAG_NAME }}
|
||||||
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
||||||
|
6
.licenses/npm/@actions/artifact.dep.yml
generated
6
.licenses/npm/@actions/artifact.dep.yml
generated
@@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
name: "@actions/artifact"
|
name: "@actions/artifact"
|
||||||
version: 2.0.1
|
version: 2.3.2
|
||||||
type: npm
|
type: npm
|
||||||
summary:
|
summary: Actions artifact lib
|
||||||
homepage:
|
homepage: https://github.com/actions/toolkit/tree/main/packages/artifact
|
||||||
license: mit
|
license: mit
|
||||||
licenses:
|
licenses:
|
||||||
- sources: LICENSE.md
|
- sources: LICENSE.md
|
||||||
|
2
.licenses/npm/@actions/core.dep.yml
generated
2
.licenses/npm/@actions/core.dep.yml
generated
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: "@actions/core"
|
name: "@actions/core"
|
||||||
version: 1.10.0
|
version: 1.10.1
|
||||||
type: npm
|
type: npm
|
||||||
summary: Actions core lib
|
summary: Actions core lib
|
||||||
homepage: https://github.com/actions/toolkit/tree/main/packages/core
|
homepage: https://github.com/actions/toolkit/tree/main/packages/core
|
||||||
|
34516
dist/index.js
vendored
34516
dist/index.js
vendored
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
- [Migration](#migration)
|
- [Migration](#migration)
|
||||||
- [Multiple uploads to the same named Artifact](#multiple-uploads-to-the-same-named-artifact)
|
- [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`.
|
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
|
- name: Download All Artifacts
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
|
name: my-artifact
|
||||||
path: my-artifact
|
path: my-artifact
|
||||||
- run: ls -R my-artifact
|
- run: ls -R my-artifact
|
||||||
```
|
```
|
||||||
@@ -71,6 +74,7 @@ jobs:
|
|||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
+ uses: actions/download-artifact@v4
|
+ uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
- name: my-artifact
|
||||||
path: my-artifact
|
path: my-artifact
|
||||||
+ pattern: my-artifact-*
|
+ pattern: my-artifact-*
|
||||||
+ merge-multiple: true
|
+ merge-multiple: true
|
||||||
@@ -78,3 +82,128 @@ 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.
|
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
|
||||||
|
+ uses: actions/upload-artifact@v4
|
||||||
|
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](https://github.com/actions/upload-artifact/blob/main/merge/README.md).
|
||||||
|
1601
package-lock.json
generated
1601
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "download-artifact",
|
"name": "download-artifact",
|
||||||
"version": "4.0.1",
|
"version": "4.2.0",
|
||||||
"description": "Download an Actions Artifact from a workflow run",
|
"description": "Download an Actions Artifact from a workflow run",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -28,8 +28,8 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/actions/download-artifact#readme",
|
"homepage": "https://github.com/actions/download-artifact#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/artifact": "^2.0.1",
|
"@actions/artifact": "^2.3.2",
|
||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.1",
|
||||||
"@actions/github": "^5.1.1",
|
"@actions/github": "^5.1.1",
|
||||||
"minimatch": "^9.0.3"
|
"minimatch": "^9.0.3"
|
||||||
},
|
},
|
||||||
@@ -44,4 +44,4 @@
|
|||||||
"prettier": "^3.1.1",
|
"prettier": "^3.1.1",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -75,10 +75,6 @@ async function run(): Promise<void> {
|
|||||||
|
|
||||||
artifacts = [targetArtifact]
|
artifacts = [targetArtifact]
|
||||||
} else {
|
} 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({
|
const listArtifactResponse = await artifactClient.listArtifacts({
|
||||||
latest: true,
|
latest: true,
|
||||||
...options
|
...options
|
||||||
@@ -94,6 +90,15 @@ async function run(): Promise<void> {
|
|||||||
core.debug(
|
core.debug(
|
||||||
`Filtered from ${listArtifactResponse.artifacts.length} to ${artifacts.length} artifacts`
|
`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'
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,29 +106,43 @@ async function run(): Promise<void> {
|
|||||||
core.info(`Preparing to download the following artifacts:`)
|
core.info(`Preparing to download the following artifacts:`)
|
||||||
artifacts.forEach(artifact => {
|
artifacts.forEach(artifact => {
|
||||||
core.info(
|
core.info(
|
||||||
`- ${artifact.name} (ID: ${artifact.id}, Size: ${artifact.size})`
|
`- ${artifact.name} (ID: ${artifact.id}, Size: ${artifact.size}, Expected Digest: ${artifact.digest})`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const downloadPromises = artifacts.map(artifact =>
|
const downloadPromises = artifacts.map(artifact => ({
|
||||||
artifactClient.downloadArtifact(artifact.id, {
|
name: artifact.name,
|
||||||
|
promise: artifactClient.downloadArtifact(artifact.id, {
|
||||||
...options,
|
...options,
|
||||||
path:
|
path:
|
||||||
isSingleArtifactDownload || inputs.mergeMultiple
|
isSingleArtifactDownload || inputs.mergeMultiple
|
||||||
? resolvedPath
|
? resolvedPath
|
||||||
: path.join(resolvedPath, artifact.name)
|
: path.join(resolvedPath, artifact.name),
|
||||||
|
expectedHash: artifact.digest
|
||||||
})
|
})
|
||||||
)
|
}))
|
||||||
|
|
||||||
const chunkedPromises = chunk(downloadPromises, PARALLEL_DOWNLOADS)
|
const chunkedPromises = chunk(downloadPromises, PARALLEL_DOWNLOADS)
|
||||||
for (const chunk of chunkedPromises) {
|
for (const chunk of chunkedPromises) {
|
||||||
await Promise.all(chunk)
|
const chunkPromises = chunk.map(item => item.promise)
|
||||||
}
|
const results = await Promise.all(chunkPromises)
|
||||||
|
|
||||||
core.info(`Total of ${artifacts.length} artifact(s) downloaded`)
|
for (let i = 0; i < results.length; i++) {
|
||||||
core.setOutput(Outputs.DownloadPath, resolvedPath)
|
const outcome = results[i]
|
||||||
core.info('Download artifact has finished successfully')
|
const artifactName = chunk[i].name
|
||||||
|
|
||||||
|
if (outcome.digestMismatch) {
|
||||||
|
core.warning(
|
||||||
|
`Artifact '${artifactName}' digest validation failed. Please verify the integrity of the artifact.`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
core.info(`Total of ${artifacts.length} artifact(s) downloaded`)
|
||||||
|
core.setOutput(Outputs.DownloadPath, resolvedPath)
|
||||||
|
core.info('Download artifact has finished successfully')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
run().catch(err =>
|
run().catch(err =>
|
||||||
|
Reference in New Issue
Block a user