From 47225c44b359a5155efdbbbc352041b3e249fb1b Mon Sep 17 00:00:00 2001 From: Ben De St Paer-Gotch Date: Mon, 16 Jun 2025 10:11:52 +0100 Subject: [PATCH 1/5] Update README.md --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index aa71e839..ab6b7015 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,24 @@ For more information, see the [`@actions/artifact`](https://github.com/actions/t For assistance with breaking changes, see [MIGRATION.md](docs/MIGRATION.md). +## Note + +Thank you for your interest in this GitHub repo, however, right now we are not taking contributions. + +We continue to focus our resources on strategic areas that help our customers be successful while making developers' lives easier. While GitHub Actions remains a key part of this vision, we are allocating resources towards other areas of Actions and are not taking contributions to this repository at this time. The GitHub public roadmap is the best place to follow along for any updates on features we’re working on and what stage they’re in. + +We are taking the following steps to better direct requests related to GitHub Actions, including: + +1. We will be directing questions and support requests to our [Community Discussions area](https://github.com/orgs/community/discussions/categories/actions) + +2. High Priority bugs can be reported through Community Discussions or you can report these to our support team https://support.github.com/contact/bug-report. + +3. Security Issues should be handled as per our [security.md](SECURITY.md). + +We will still provide security updates for this project and fix major breaking changes during this time. + +You are welcome to still raise bugs in this repo. + ## Usage ### Inputs From fff8c148a8fdd56aa81fcb019f0b5f6c65700c4d Mon Sep 17 00:00:00 2001 From: GrantBirki Date: Tue, 5 Aug 2025 10:56:18 -0700 Subject: [PATCH 2/5] fix download path logic when downloading a single artifact by id --- __tests__/download.test.ts | 33 +++++++++++++++++++++++++++++++++ src/download-artifact.ts | 4 +++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/__tests__/download.test.ts b/__tests__/download.test.ts index 032d857a..8901ac3c 100644 --- a/__tests__/download.test.ts +++ b/__tests__/download.test.ts @@ -371,4 +371,37 @@ 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' + } + + mockInputs({ + [Inputs.Name]: '', + [Inputs.Pattern]: '', + [Inputs.ArtifactIds]: '456', + [Inputs.Path]: '/test/path' + }) + + 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: '/test/path', // Should be the resolved path directly, not /test/path/test-artifact + expectedHash: mockArtifact.digest + }) + ) + }) }) diff --git a/src/download-artifact.ts b/src/download-artifact.ts index 5cc6b170..6f2d7825 100644 --- a/src/download-artifact.ts +++ b/src/download-artifact.ts @@ -174,7 +174,9 @@ export async function run(): Promise { 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 From bff23f9308ceb2f06d673043ea6311519be6a87b Mon Sep 17 00:00:00 2001 From: GrantBirki Date: Tue, 5 Aug 2025 10:59:33 -0700 Subject: [PATCH 3/5] update docs --- README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ab6b7015..3258a0d2 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ See also [upload-artifact](https://github.com/actions/upload-artifact). - [v4 - What's new](#v4---whats-new) - [Improvements](#improvements) - [Breaking Changes](#breaking-changes) + - [Note](#note) - [Usage](#usage) - [Inputs](#inputs) - [Outputs](#outputs) @@ -89,6 +90,7 @@ You are welcome to still raise bugs in this repo. # 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 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: @@ -145,6 +147,8 @@ 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 @@ -154,6 +158,20 @@ steps: run: ls -R ``` +Download a single artifact by ID to a specific directory: + +```yaml +steps: +- uses: actions/download-artifact@v4 + 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 @@ -166,7 +184,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 From e262cbee4ab8c473c61c59a81ad8e9dc760e90db Mon Sep 17 00:00:00 2001 From: GrantBirki Date: Tue, 5 Aug 2025 11:00:44 -0700 Subject: [PATCH 4/5] bundle dist --- dist/index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index 374211f8..f9d5a305 100644 --- a/dist/index.js +++ b/dist/index.js @@ -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__; /******/ /******/ })() -; +; \ No newline at end of file From b19ff4302770b82aa4694b63703b547756dacce6 Mon Sep 17 00:00:00 2001 From: GrantBirki Date: Tue, 5 Aug 2025 11:26:03 -0700 Subject: [PATCH 5/5] refactor: resolve download path correctly in artifact download tests (mainly for windows unit tests) --- __tests__/download.test.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/__tests__/download.test.ts b/__tests__/download.test.ts index 8901ac3c..0709fbee 100644 --- a/__tests__/download.test.ts +++ b/__tests__/download.test.ts @@ -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' @@ -380,11 +381,12 @@ describe('download', () => { digest: 'def456' } + const testPath = '/test/path' mockInputs({ [Inputs.Name]: '', [Inputs.Pattern]: '', [Inputs.ArtifactIds]: '456', - [Inputs.Path]: '/test/path' + [Inputs.Path]: testPath }) jest.spyOn(artifact, 'listArtifacts').mockImplementation(() => @@ -399,7 +401,7 @@ describe('download', () => { expect(artifact.downloadArtifact).toHaveBeenCalledWith( 456, expect.objectContaining({ - path: '/test/path', // Should be the resolved path directly, not /test/path/test-artifact + path: path.resolve(testPath), // Should be the resolved path directly, not nested expectedHash: mockArtifact.digest }) )