mirror of
https://github.com/actions/download-artifact
synced 2025-09-22 03:38:09 +00:00
Compare commits
11 commits
b7ab51ecd1
...
4f0a1fb65f
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4f0a1fb65f | ||
![]() |
de96f4613b | ||
![]() |
7993cb44e9 | ||
![]() |
2653c123b8 | ||
![]() |
7d782037f3 | ||
![]() |
634f93cb29 | ||
![]() |
b19ff43027 | ||
![]() |
e262cbee4a | ||
![]() |
bff23f9308 | ||
![]() |
fff8c148a8 | ||
![]() |
ef3d263efa |
4 changed files with 85 additions and 15 deletions
55
README.md
55
README.md
|
@ -5,9 +5,11 @@ Download [Actions Artifacts](https://docs.github.com/en/actions/using-workflows/
|
|||
See also [upload-artifact](https://github.com/actions/upload-artifact).
|
||||
|
||||
- [`@actions/download-artifact`](#actionsdownload-artifact)
|
||||
- [v5 - What's new](#v5---whats-new)
|
||||
- [v4 - What's new](#v4---whats-new)
|
||||
- [Improvements](#improvements)
|
||||
- [Breaking Changes](#breaking-changes)
|
||||
- [Note](#note)
|
||||
- [Usage](#usage)
|
||||
- [Inputs](#inputs)
|
||||
- [Outputs](#outputs)
|
||||
|
@ -20,6 +22,17 @@ See also [upload-artifact](https://github.com/actions/upload-artifact).
|
|||
- [Limitations](#limitations)
|
||||
- [Permission Loss](#permission-loss)
|
||||
|
||||
## v5 - What's new
|
||||
|
||||
Previously, **single artifact downloads** behaved differently depending on how you specified the artifact:
|
||||
|
||||
- **By name**: `name: my-artifact` → extracted to `path/` (direct)
|
||||
- **By ID**: `artifact-ids: 12345` → extracted to `path/my-artifact/` (nested)
|
||||
|
||||
Now both methods are consistent:
|
||||
|
||||
- **By name**: `name: my-artifact` → extracted to `path/` (unchanged)
|
||||
- **By ID**: `artifact-ids: 12345` → extracted to `path/` (updated - now direct)
|
||||
|
||||
## v4 - What's new
|
||||
|
||||
|
@ -65,7 +78,7 @@ You are welcome to still raise bugs in this repo.
|
|||
### Inputs
|
||||
|
||||
```yaml
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
# Name of the artifact to download.
|
||||
# If unspecified, all artifacts for the run are downloaded.
|
||||
|
@ -87,8 +100,10 @@ You are welcome to still raise bugs in this repo.
|
|||
pattern:
|
||||
|
||||
# When multiple artifacts are matched, this changes the behavior of the destination directories.
|
||||
# If true, the downloaded artifacts will be in the same directory specified by path.
|
||||
# If true, the downloaded artifacts will be in the same directory specified by path. There is no check for file name
|
||||
# collisions. If multiple artifacts have files with the same name, only one will end up in path.
|
||||
# If false, the downloaded artifacts will be extracted into individual named directories within the specified path.
|
||||
# Note: When downloading a single artifact (by name or ID), it will always be extracted directly to the specified path.
|
||||
# Optional. Default is 'false'
|
||||
merge-multiple:
|
||||
|
||||
|
@ -122,7 +137,7 @@ Download to current working directory (`$GITHUB_WORKSPACE`):
|
|||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: my-artifact
|
||||
- name: Display structure of downloaded files
|
||||
|
@ -133,7 +148,7 @@ Download to a specific directory (also supports `~` expansion):
|
|||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: my-artifact
|
||||
path: your/destination/dir
|
||||
|
@ -145,20 +160,36 @@ steps:
|
|||
|
||||
The `artifact-ids` input allows downloading artifacts using their unique ID rather than name. This is particularly useful when working with immutable artifacts from `actions/upload-artifact@v4` which assigns a unique ID to each artifact.
|
||||
|
||||
Download a single artifact by ID to the current working directory (`$GITHUB_WORKSPACE`):
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
artifact-ids: 12345
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R
|
||||
```
|
||||
|
||||
Download a single artifact by ID to a specific directory:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
artifact-ids: 12345
|
||||
path: your/destination/dir
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R your/destination/dir
|
||||
```
|
||||
|
||||
When downloading a single artifact by ID, the behavior is identical to downloading by name - the artifact contents are extracted directly to the specified path without creating a subdirectory.
|
||||
|
||||
Multiple artifacts can be downloaded by providing a comma-separated list of IDs:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
artifact-ids: 12345,67890
|
||||
path: path/to/artifacts
|
||||
|
@ -166,7 +197,7 @@ steps:
|
|||
run: ls -R path/to/artifacts
|
||||
```
|
||||
|
||||
This will download multiple artifacts to separate directories (similar to downloading multiple artifacts by name).
|
||||
When downloading multiple artifacts by ID, each artifact will be extracted into its own subdirectory named after the artifact (similar to downloading multiple artifacts by name).
|
||||
|
||||
### Download All Artifacts
|
||||
|
||||
|
@ -186,7 +217,7 @@ Download all artifacts to the current working directory:
|
|||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v5
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R
|
||||
```
|
||||
|
@ -195,7 +226,7 @@ Download all artifacts to a specific directory:
|
|||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
path: path/to/artifacts
|
||||
- name: Display structure of downloaded files
|
||||
|
@ -206,7 +237,7 @@ To download them to the _same_ directory:
|
|||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
path: path/to/artifacts
|
||||
merge-multiple: true
|
||||
|
@ -246,7 +277,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download All Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
path: my-artifact
|
||||
pattern: my-artifact-*
|
||||
|
@ -269,7 +300,7 @@ It may be useful to download Artifacts from other workflow runs, or even other r
|
|||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: my-other-artifact
|
||||
github-token: ${{ secrets.GH_PAT }} # token with actions:read permissions on target repo
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import * as core from '@actions/core'
|
||||
import * as path from 'path'
|
||||
import artifact, {ArtifactNotFoundError} from '@actions/artifact'
|
||||
import {run} from '../src/download-artifact'
|
||||
import {Inputs} from '../src/constants'
|
||||
|
@ -371,4 +372,38 @@ describe('download', () => {
|
|||
"Inputs 'name' and 'artifact-ids' cannot be used together. Please specify only one."
|
||||
)
|
||||
})
|
||||
|
||||
test('downloads single artifact by ID to same path as by name', async () => {
|
||||
const mockArtifact = {
|
||||
id: 456,
|
||||
name: 'test-artifact',
|
||||
size: 1024,
|
||||
digest: 'def456'
|
||||
}
|
||||
|
||||
const testPath = '/test/path'
|
||||
mockInputs({
|
||||
[Inputs.Name]: '',
|
||||
[Inputs.Pattern]: '',
|
||||
[Inputs.ArtifactIds]: '456',
|
||||
[Inputs.Path]: testPath
|
||||
})
|
||||
|
||||
jest.spyOn(artifact, 'listArtifacts').mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
artifacts: [mockArtifact]
|
||||
})
|
||||
)
|
||||
|
||||
await run()
|
||||
|
||||
// Verify it downloads directly to the specified path (not nested in artifact name subdirectory)
|
||||
expect(artifact.downloadArtifact).toHaveBeenCalledWith(
|
||||
456,
|
||||
expect.objectContaining({
|
||||
path: path.resolve(testPath), // Should be the resolved path directly, not nested
|
||||
expectedHash: mockArtifact.digest
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
6
dist/index.js
vendored
6
dist/index.js
vendored
|
@ -118883,7 +118883,9 @@ function run() {
|
|||
}
|
||||
const downloadPromises = artifacts.map(artifact => ({
|
||||
name: artifact.name,
|
||||
promise: artifact_1.default.downloadArtifact(artifact.id, Object.assign(Object.assign({}, options), { path: isSingleArtifactDownload || inputs.mergeMultiple
|
||||
promise: artifact_1.default.downloadArtifact(artifact.id, Object.assign(Object.assign({}, options), { path: isSingleArtifactDownload ||
|
||||
inputs.mergeMultiple ||
|
||||
artifacts.length === 1
|
||||
? resolvedPath
|
||||
: path.join(resolvedPath, artifact.name), expectedHash: artifact.digest }))
|
||||
}));
|
||||
|
@ -128958,4 +128960,4 @@ module.exports = JSON.parse('[[[0,44],"disallowed_STD3_valid"],[[45,46],"valid"]
|
|||
/******/ module.exports = __webpack_exports__;
|
||||
/******/
|
||||
/******/ })()
|
||||
;
|
||||
;
|
|
@ -174,7 +174,9 @@ export async function run(): Promise<void> {
|
|||
promise: artifactClient.downloadArtifact(artifact.id, {
|
||||
...options,
|
||||
path:
|
||||
isSingleArtifactDownload || inputs.mergeMultiple
|
||||
isSingleArtifactDownload ||
|
||||
inputs.mergeMultiple ||
|
||||
artifacts.length === 1
|
||||
? resolvedPath
|
||||
: path.join(resolvedPath, artifact.name),
|
||||
expectedHash: artifact.digest
|
||||
|
|
Loading…
Reference in a new issue