From b7a914b73beba59c0ae9bc54be2d1b8e1cb2bff7 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Fri, 30 Aug 2024 09:30:02 +0200 Subject: [PATCH 01/14] Use native `crypto` package from node --- packages/artifact/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/artifact/package.json b/packages/artifact/package.json index fefa6abe..61b25f6b 100644 --- a/packages/artifact/package.json +++ b/packages/artifact/package.json @@ -50,7 +50,6 @@ "@octokit/request-error": "^5.0.0", "@protobuf-ts/plugin": "^2.2.3-alpha.1", "archiver": "^7.0.1", - "crypto": "^1.0.1", "jwt-decode": "^3.1.2", "twirp-ts": "^2.5.0", "unzip-stream": "^0.3.1" From 2e1998fc4227c81d7ab8e491ef7126cd6ad3c17e Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Fri, 30 Aug 2024 09:41:33 +0200 Subject: [PATCH 02/14] update lockfile --- packages/artifact/package-lock.json | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/artifact/package-lock.json b/packages/artifact/package-lock.json index 809562ab..f2449372 100644 --- a/packages/artifact/package-lock.json +++ b/packages/artifact/package-lock.json @@ -19,7 +19,6 @@ "@octokit/request-error": "^5.0.0", "@protobuf-ts/plugin": "^2.2.3-alpha.1", "archiver": "^7.0.1", - "crypto": "^1.0.1", "jwt-decode": "^3.1.2", "twirp-ts": "^2.5.0", "unzip-stream": "^0.3.1" @@ -852,12 +851,6 @@ "node": ">= 8" } }, - "node_modules/crypto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", - "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", - "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in." - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", From 7f19a7886a8b3b16c971a89cb787b850cb6a7980 Mon Sep 17 00:00:00 2001 From: Rob Herley Date: Fri, 20 Sep 2024 17:23:43 -0400 Subject: [PATCH 03/14] fix regression, auto readlink on symlinks again --- packages/artifact/RELEASES.md | 4 ++ .../__tests__/upload-artifact.test.ts | 45 +++++++++++++++---- .../upload-zip-specification.test.ts | 16 +++++++ packages/artifact/package-lock.json | 8 ++-- packages/artifact/package.json | 2 +- .../upload/upload-zip-specification.ts | 17 +++++-- packages/artifact/src/internal/upload/zip.ts | 11 ++++- 7 files changed, 83 insertions(+), 20 deletions(-) diff --git a/packages/artifact/RELEASES.md b/packages/artifact/RELEASES.md index 6688ad45..70351075 100644 --- a/packages/artifact/RELEASES.md +++ b/packages/artifact/RELEASES.md @@ -1,5 +1,9 @@ # @actions/artifact Releases +### 2.1.10 + +- Fixed a bug with symlinks not being automatically resolved. + ### 2.1.9 - Fixed artifact upload chunk timeout logic [#1774](https://github.com/actions/toolkit/pull/1774) diff --git a/packages/artifact/__tests__/upload-artifact.test.ts b/packages/artifact/__tests__/upload-artifact.test.ts index cd383db9..c92abfd6 100644 --- a/packages/artifact/__tests__/upload-artifact.test.ts +++ b/packages/artifact/__tests__/upload-artifact.test.ts @@ -27,9 +27,14 @@ jest.mock('@azure/storage-blob', () => ({ const fixtures = { uploadDirectory: path.join(__dirname, '_temp', 'plz-upload'), files: [ - ['file1.txt', 'test 1 file content'], - ['file2.txt', 'test 2 file content'], - ['file3.txt', 'test 3 file content'] + {name: 'file1.txt', content: 'test 1 file content'}, + {name: 'file2.txt', content: 'test 2 file content'}, + {name: 'file3.txt', content: 'test 3 file content'}, + { + name: 'from_symlink.txt', + content: 'from a symlink', + symlink: '../symlinked.txt' + } ], backendIDs: { workflowRunBackendId: '67dbcc20-e851-4452-a7c3-2cc0d2e0ec67', @@ -54,8 +59,23 @@ describe('upload-artifact', () => { fs.mkdirSync(fixtures.uploadDirectory, {recursive: true}) } - for (const [file, content] of fixtures.files) { - fs.writeFileSync(path.join(fixtures.uploadDirectory, file), content) + for (const file of fixtures.files) { + if (file.symlink) { + const symlinkPath = path.join(fixtures.uploadDirectory, file.symlink) + fs.writeFileSync(symlinkPath, file.content) + if (!fs.existsSync(path.join(fixtures.uploadDirectory, file.name))) { + fs.symlinkSync( + symlinkPath, + path.join(fixtures.uploadDirectory, file.name), + 'file' + ) + } + } else { + fs.writeFileSync( + path.join(fixtures.uploadDirectory, file.name), + file.content + ) + } } }) @@ -71,8 +91,9 @@ describe('upload-artifact', () => { .spyOn(uploadZipSpecification, 'getUploadZipSpecification') .mockReturnValue( fixtures.files.map(file => ({ - sourcePath: path.join(fixtures.uploadDirectory, file[0]), - destinationPath: file[0] + sourcePath: path.join(fixtures.uploadDirectory, file.name), + destinationPath: file.name, + stats: new fs.Stats() })) ) jest.spyOn(config, 'getRuntimeToken').mockReturnValue(fixtures.runtimeToken) @@ -185,6 +206,10 @@ describe('upload-artifact', () => { }) it('should successfully upload an artifact', async () => { + jest + .spyOn(uploadZipSpecification, 'getUploadZipSpecification') + .mockRestore() + jest .spyOn(ArtifactServiceClientJSON.prototype, 'CreateArtifact') .mockReturnValue( @@ -228,8 +253,10 @@ describe('upload-artifact', () => { const {id, size} = await uploadArtifact( fixtures.inputs.artifactName, - fixtures.inputs.files, - fixtures.inputs.rootDirectory + fixtures.files.map(file => + path.join(fixtures.uploadDirectory, file.name) + ), + fixtures.uploadDirectory ) expect(id).toBe(1) diff --git a/packages/artifact/__tests__/upload-zip-specification.test.ts b/packages/artifact/__tests__/upload-zip-specification.test.ts index 0b59bff7..3c6bbfb0 100644 --- a/packages/artifact/__tests__/upload-zip-specification.test.ts +++ b/packages/artifact/__tests__/upload-zip-specification.test.ts @@ -305,4 +305,20 @@ describe('Search', () => { } } }) + + it('Upload Specification - Includes symlinks', async () => { + const targetPath = path.join(root, 'link-dir', 'symlink-me.txt') + await fs.mkdir(path.dirname(targetPath), {recursive: true}) + await fs.writeFile(targetPath, 'symlink file content') + + const uploadPath = path.join(root, 'upload-dir', 'symlink.txt') + await fs.mkdir(path.dirname(uploadPath), {recursive: true}) + await fs.symlink(targetPath, uploadPath, 'file') + + const specifications = getUploadZipSpecification([uploadPath], root) + expect(specifications.length).toEqual(1) + expect(specifications[0].sourcePath).toEqual(uploadPath) + expect(specifications[0].destinationPath).toEqual('/upload-dir/symlink.txt') + expect(specifications[0].stats.isSymbolicLink()).toBe(true) + }) }) diff --git a/packages/artifact/package-lock.json b/packages/artifact/package-lock.json index 809562ab..d3318a97 100644 --- a/packages/artifact/package-lock.json +++ b/packages/artifact/package-lock.json @@ -1,6 +1,6 @@ { "name": "@actions/artifact", - "version": "2.1.9", + "version": "2.1.10", "lockfileVersion": 3, "requires": true, "packages": { @@ -1315,9 +1315,9 @@ } }, "node_modules/path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==" }, "node_modules/prettier": { "version": "2.8.8", diff --git a/packages/artifact/package.json b/packages/artifact/package.json index fefa6abe..1f678e41 100644 --- a/packages/artifact/package.json +++ b/packages/artifact/package.json @@ -1,6 +1,6 @@ { "name": "@actions/artifact", - "version": "2.1.9", + "version": "2.1.10", "preview": true, "description": "Actions artifact lib", "keywords": [ diff --git a/packages/artifact/src/internal/upload/upload-zip-specification.ts b/packages/artifact/src/internal/upload/upload-zip-specification.ts index c6e807e6..54f34799 100644 --- a/packages/artifact/src/internal/upload/upload-zip-specification.ts +++ b/packages/artifact/src/internal/upload/upload-zip-specification.ts @@ -13,6 +13,12 @@ export interface UploadZipSpecification { * The destination path in a zip for a file */ destinationPath: string + + /** + * Information about the file + * https://nodejs.org/api/fs.html#class-fsstats + */ + stats: fs.Stats } /** @@ -75,10 +81,11 @@ export function getUploadZipSpecification( - file3.txt */ for (let file of filesToZip) { - if (!fs.existsSync(file)) { + const stats = fs.lstatSync(file, {throwIfNoEntry: false}) + if (!stats) { throw new Error(`File ${file} does not exist`) } - if (!fs.statSync(file).isDirectory()) { + if (!stats.isDirectory()) { // Normalize and resolve, this allows for either absolute or relative paths to be used file = normalize(file) file = resolve(file) @@ -94,7 +101,8 @@ export function getUploadZipSpecification( specification.push({ sourcePath: file, - destinationPath: uploadPath + destinationPath: uploadPath, + stats }) } else { // Empty directory @@ -103,7 +111,8 @@ export function getUploadZipSpecification( specification.push({ sourcePath: null, - destinationPath: directoryPath + destinationPath: directoryPath, + stats }) } } diff --git a/packages/artifact/src/internal/upload/zip.ts b/packages/artifact/src/internal/upload/zip.ts index 10433fb8..8cc3fd0c 100644 --- a/packages/artifact/src/internal/upload/zip.ts +++ b/packages/artifact/src/internal/upload/zip.ts @@ -1,4 +1,5 @@ import * as stream from 'stream' +import {readlink} from 'fs/promises' import * as archiver from 'archiver' import * as core from '@actions/core' import {UploadZipSpecification} from './upload-zip-specification' @@ -42,8 +43,14 @@ export async function createZipUploadStream( for (const file of uploadSpecification) { if (file.sourcePath !== null) { - // Add a normal file to the zip - zip.file(file.sourcePath, { + // Check if symlink and resolve the source path + let sourcePath = file.sourcePath + if (file.stats.isSymbolicLink()) { + sourcePath = await readlink(file.sourcePath) + } + + // Add the file to the zip + zip.file(sourcePath, { name: file.destinationPath }) } else { From d6694e491d778c715963d2e0050edc5fa88c1c43 Mon Sep 17 00:00:00 2001 From: Rob Herley Date: Fri, 20 Sep 2024 17:31:40 -0400 Subject: [PATCH 04/14] update release notes --- packages/artifact/RELEASES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/artifact/RELEASES.md b/packages/artifact/RELEASES.md index 70351075..219f8764 100644 --- a/packages/artifact/RELEASES.md +++ b/packages/artifact/RELEASES.md @@ -2,7 +2,8 @@ ### 2.1.10 -- Fixed a bug with symlinks not being automatically resolved. +- Fixed a regression with symlinks not being automatically resolved [#1830](https://github.com/actions/toolkit/pull/1830) +- Fixed a regression with chunk timeout [#1786](https://github.com/actions/toolkit/pull/1786) ### 2.1.9 From 8551843690e2650a845c7e7294b2a128aaf6c222 Mon Sep 17 00:00:00 2001 From: Rob Herley Date: Fri, 20 Sep 2024 17:45:55 -0400 Subject: [PATCH 05/14] fix assertion --- packages/artifact/__tests__/upload-zip-specification.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/artifact/__tests__/upload-zip-specification.test.ts b/packages/artifact/__tests__/upload-zip-specification.test.ts index 3c6bbfb0..e30b5a16 100644 --- a/packages/artifact/__tests__/upload-zip-specification.test.ts +++ b/packages/artifact/__tests__/upload-zip-specification.test.ts @@ -318,7 +318,9 @@ describe('Search', () => { const specifications = getUploadZipSpecification([uploadPath], root) expect(specifications.length).toEqual(1) expect(specifications[0].sourcePath).toEqual(uploadPath) - expect(specifications[0].destinationPath).toEqual('/upload-dir/symlink.txt') + expect(specifications[0].destinationPath).toEqual( + path.join('upload-dir', 'symlink.txt') + ) expect(specifications[0].stats.isSymbolicLink()).toBe(true) }) }) From 5a62022195adf3ff6ac6a2eb7162e2c4e4942e10 Mon Sep 17 00:00:00 2001 From: Rob Herley Date: Fri, 20 Sep 2024 17:52:14 -0400 Subject: [PATCH 06/14] / --- packages/artifact/__tests__/upload-zip-specification.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/artifact/__tests__/upload-zip-specification.test.ts b/packages/artifact/__tests__/upload-zip-specification.test.ts index e30b5a16..9688aa6f 100644 --- a/packages/artifact/__tests__/upload-zip-specification.test.ts +++ b/packages/artifact/__tests__/upload-zip-specification.test.ts @@ -319,7 +319,7 @@ describe('Search', () => { expect(specifications.length).toEqual(1) expect(specifications[0].sourcePath).toEqual(uploadPath) expect(specifications[0].destinationPath).toEqual( - path.join('upload-dir', 'symlink.txt') + path.join('/upload-dir', 'symlink.txt') ) expect(specifications[0].stats.isSymbolicLink()).toBe(true) }) From 2a8f1c5ddd92081dc1524a3d1308763b31742724 Mon Sep 17 00:00:00 2001 From: Rob Herley Date: Tue, 1 Oct 2024 16:43:30 -0400 Subject: [PATCH 07/14] bump package lock version --- packages/artifact/package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/artifact/package-lock.json b/packages/artifact/package-lock.json index d3318a97..2e94dfb7 100644 --- a/packages/artifact/package-lock.json +++ b/packages/artifact/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "@actions/artifact", - "version": "2.1.9", + "version": "2.1.10", "license": "MIT", "dependencies": { "@actions/core": "^1.10.0", From 78af634e7e4db76a06450480bbef63d9899229f1 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Wed, 2 Oct 2024 12:28:06 -0400 Subject: [PATCH 08/14] Remove dependency on `uuid` package (#1824) --- packages/cache/package-lock.json | 30 +------------- packages/cache/package.json | 4 +- packages/cache/src/internal/cacheUtils.ts | 3 +- packages/core/__tests__/core.test.ts | 30 ++++++++------ packages/core/package-lock.json | 31 +-------------- packages/core/package.json | 6 +-- packages/core/src/file-command.ts | 3 +- packages/tool-cache/package-lock.json | 48 +---------------------- packages/tool-cache/package.json | 4 +- packages/tool-cache/src/tool-cache.ts | 5 +-- 10 files changed, 29 insertions(+), 135 deletions(-) diff --git a/packages/cache/package-lock.json b/packages/cache/package-lock.json index 422f2264..346c2c2a 100644 --- a/packages/cache/package-lock.json +++ b/packages/cache/package-lock.json @@ -17,12 +17,10 @@ "@azure/abort-controller": "^1.1.0", "@azure/ms-rest-js": "^2.6.0", "@azure/storage-blob": "^12.13.0", - "semver": "^6.3.1", - "uuid": "^3.3.3" + "semver": "^6.3.1" }, "devDependencies": { "@types/semver": "^6.0.0", - "@types/uuid": "^3.4.5", "typescript": "^5.2.2" } }, @@ -296,12 +294,6 @@ "@types/node": "*" } }, - "node_modules/@types/uuid": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.10.tgz", - "integrity": "sha512-BgeaZuElf7DEYZhWYDTc/XcLZXdVgFkVSTa13BqKvbnmUrxr3TJFKofUxCtDO9UQOdhnV+HPOESdHiHKZOJV1A==", - "dev": true - }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -486,15 +478,6 @@ "node": ">=14.17" } }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -764,12 +747,6 @@ "@types/node": "*" } }, - "@types/uuid": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.10.tgz", - "integrity": "sha512-BgeaZuElf7DEYZhWYDTc/XcLZXdVgFkVSTa13BqKvbnmUrxr3TJFKofUxCtDO9UQOdhnV+HPOESdHiHKZOJV1A==", - "dev": true - }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -900,11 +877,6 @@ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/packages/cache/package.json b/packages/cache/package.json index d3251083..6af620f2 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -45,12 +45,10 @@ "@azure/abort-controller": "^1.1.0", "@azure/ms-rest-js": "^2.6.0", "@azure/storage-blob": "^12.13.0", - "semver": "^6.3.1", - "uuid": "^3.3.3" + "semver": "^6.3.1" }, "devDependencies": { "@types/semver": "^6.0.0", - "@types/uuid": "^3.4.5", "typescript": "^5.2.2" } } diff --git a/packages/cache/src/internal/cacheUtils.ts b/packages/cache/src/internal/cacheUtils.ts index 91bae9a8..d8b7f3e0 100644 --- a/packages/cache/src/internal/cacheUtils.ts +++ b/packages/cache/src/internal/cacheUtils.ts @@ -6,7 +6,6 @@ import * as fs from 'fs' import * as path from 'path' import * as semver from 'semver' import * as util from 'util' -import {v4 as uuidV4} from 'uuid' import { CacheFilename, CompressionMethod, @@ -34,7 +33,7 @@ export async function createTempDirectory(): Promise { tempDirectory = path.join(baseLocation, 'actions', 'temp') } - const dest = path.join(tempDirectory, uuidV4()) + const dest = path.join(tempDirectory, crypto.randomUUID()) await io.mkdirP(dest) return dest } diff --git a/packages/core/__tests__/core.test.ts b/packages/core/__tests__/core.test.ts index 09bc587b..7fcb3759 100644 --- a/packages/core/__tests__/core.test.ts +++ b/packages/core/__tests__/core.test.ts @@ -4,9 +4,6 @@ import * as path from 'path' import * as core from '../src/core' import {HttpClient} from '@actions/http-client' import {toCommandProperties} from '../src/utils' -import * as uuid from 'uuid' - -jest.mock('uuid') /* eslint-disable @typescript-eslint/unbound-method */ @@ -49,11 +46,18 @@ const testEnvVars = { const UUID = '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d' const DELIMITER = `ghadelimiter_${UUID}` +const TEMP_DIR = path.join(__dirname, '_temp') + describe('@actions/core', () => { beforeAll(() => { - const filePath = path.join(__dirname, `test`) + const filePath = TEMP_DIR if (!fs.existsSync(filePath)) { fs.mkdirSync(filePath) + } else { + // Clear out the temp directory + for (const file of fs.readdirSync(filePath)) { + fs.unlinkSync(path.join(filePath, file)) + } } }) @@ -63,7 +67,7 @@ describe('@actions/core', () => { } process.stdout.write = jest.fn() - jest.spyOn(uuid, 'v4').mockImplementation(() => { + jest.spyOn(crypto, 'randomUUID').mockImplementation(() => { return UUID }) }) @@ -141,7 +145,7 @@ describe('@actions/core', () => { `Unexpected input: value should not contain the delimiter "${DELIMITER}"` ) - const filePath = path.join(__dirname, `test/${command}`) + const filePath = path.join(TEMP_DIR, command) fs.unlinkSync(filePath) }) @@ -155,7 +159,7 @@ describe('@actions/core', () => { `Unexpected input: name should not contain the delimiter "${DELIMITER}"` ) - const filePath = path.join(__dirname, `test/${command}`) + const filePath = path.join(TEMP_DIR, command) fs.unlinkSync(filePath) }) @@ -347,7 +351,7 @@ describe('@actions/core', () => { `Unexpected input: value should not contain the delimiter "${DELIMITER}"` ) - const filePath = path.join(__dirname, `test/${command}`) + const filePath = path.join(TEMP_DIR, command) fs.unlinkSync(filePath) }) @@ -361,7 +365,7 @@ describe('@actions/core', () => { `Unexpected input: name should not contain the delimiter "${DELIMITER}"` ) - const filePath = path.join(__dirname, `test/${command}`) + const filePath = path.join(TEMP_DIR, command) fs.unlinkSync(filePath) }) @@ -585,7 +589,7 @@ describe('@actions/core', () => { `Unexpected input: value should not contain the delimiter "${DELIMITER}"` ) - const filePath = path.join(__dirname, `test/${command}`) + const filePath = path.join(TEMP_DIR, command) fs.unlinkSync(filePath) }) @@ -599,7 +603,7 @@ describe('@actions/core', () => { `Unexpected input: name should not contain the delimiter "${DELIMITER}"` ) - const filePath = path.join(__dirname, `test/${command}`) + const filePath = path.join(TEMP_DIR, command) fs.unlinkSync(filePath) }) @@ -641,7 +645,7 @@ function assertWriteCalls(calls: string[]): void { } function createFileCommandFile(command: string): void { - const filePath = path.join(__dirname, `test/${command}`) + const filePath = path.join(__dirname, `_temp/${command}`) process.env[`GITHUB_${command}`] = filePath fs.appendFileSync(filePath, '', { encoding: 'utf8' @@ -649,7 +653,7 @@ function createFileCommandFile(command: string): void { } function verifyFileCommand(command: string, expectedContents: string): void { - const filePath = path.join(__dirname, `test/${command}`) + const filePath = path.join(__dirname, `_temp/${command}`) const contents = fs.readFileSync(filePath, 'utf8') try { expect(contents).toEqual(expectedContents) diff --git a/packages/core/package-lock.json b/packages/core/package-lock.json index 7b1cf7bb..a1515d81 100644 --- a/packages/core/package-lock.json +++ b/packages/core/package-lock.json @@ -10,12 +10,10 @@ "license": "MIT", "dependencies": { "@actions/exec": "^1.1.1", - "@actions/http-client": "^2.0.1", - "uuid": "^8.3.2" + "@actions/http-client": "^2.0.1" }, "devDependencies": { - "@types/node": "^12.0.2", - "@types/uuid": "^8.3.4" + "@types/node": "^12.0.2" } }, "node_modules/@actions/exec": { @@ -45,12 +43,6 @@ "integrity": "sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA==", "dev": true }, - "node_modules/@types/uuid": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", - "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", - "dev": true - }, "node_modules/tunnel": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", @@ -58,14 +50,6 @@ "engines": { "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } } }, "dependencies": { @@ -96,21 +80,10 @@ "integrity": "sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA==", "dev": true }, - "@types/uuid": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", - "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", - "dev": true - }, "tunnel": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" } } } diff --git a/packages/core/package.json b/packages/core/package.json index 2eda27b5..36fe624c 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -37,11 +37,9 @@ }, "dependencies": { "@actions/exec": "^1.1.1", - "@actions/http-client": "^2.0.1", - "uuid": "^8.3.2" + "@actions/http-client": "^2.0.1" }, "devDependencies": { - "@types/node": "^12.0.2", - "@types/uuid": "^8.3.4" + "@types/node": "^12.0.2" } } \ No newline at end of file diff --git a/packages/core/src/file-command.ts b/packages/core/src/file-command.ts index 832c2f0e..6750e857 100644 --- a/packages/core/src/file-command.ts +++ b/packages/core/src/file-command.ts @@ -5,7 +5,6 @@ import * as fs from 'fs' import * as os from 'os' -import {v4 as uuidv4} from 'uuid' import {toCommandValue} from './utils' export function issueFileCommand(command: string, message: any): void { @@ -25,7 +24,7 @@ export function issueFileCommand(command: string, message: any): void { } export function prepareKeyValueMessage(key: string, value: any): string { - const delimiter = `ghadelimiter_${uuidv4()}` + const delimiter = `ghadelimiter_${crypto.randomUUID()}` const convertedValue = toCommandValue(value) // These should realistically never happen, but just in case someone finds a diff --git a/packages/tool-cache/package-lock.json b/packages/tool-cache/package-lock.json index d431aa44..028842a0 100644 --- a/packages/tool-cache/package-lock.json +++ b/packages/tool-cache/package-lock.json @@ -13,13 +13,11 @@ "@actions/exec": "^1.0.0", "@actions/http-client": "^2.0.1", "@actions/io": "^1.1.1", - "semver": "^6.1.0", - "uuid": "^3.3.2" + "semver": "^6.1.0" }, "devDependencies": { "@types/nock": "^11.1.0", "@types/semver": "^6.0.0", - "@types/uuid": "^3.4.4", "nock": "^13.2.9" } }, @@ -71,27 +69,12 @@ "nock": "*" } }, - "node_modules/@types/node": { - "version": "12.7.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.0.tgz", - "integrity": "sha512-vqcj1MVm2Sla4PpMfYKh1MyDN4D2f/mPIZD7RdAGqEsbE+JxfeqQHHVbRDQ0Nqn8i73gJa1HQ1Pu3+nH4Q0Yiw==", - "dev": true - }, "node_modules/@types/semver": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.0.1.tgz", "integrity": "sha512-ffCdcrEE5h8DqVxinQjo+2d1q+FV5z7iNtPofw3JsrltSoSVlOGaW0rY8XxtO9XukdTn8TaCGWmk2VFGhI70mg==", "dev": true }, - "node_modules/@types/uuid": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.5.tgz", - "integrity": "sha512-MNL15wC3EKyw1VLF+RoVO4hJJdk9t/Hlv3rt1OL65Qvuadm4BYo6g9ZJQqoq7X8NBFSsQXgAujWciovh2lpVjA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -166,15 +149,6 @@ "engines": { "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } - }, - "node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } } }, "dependencies": { @@ -224,27 +198,12 @@ "nock": "*" } }, - "@types/node": { - "version": "12.7.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.0.tgz", - "integrity": "sha512-vqcj1MVm2Sla4PpMfYKh1MyDN4D2f/mPIZD7RdAGqEsbE+JxfeqQHHVbRDQ0Nqn8i73gJa1HQ1Pu3+nH4Q0Yiw==", - "dev": true - }, "@types/semver": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.0.1.tgz", "integrity": "sha512-ffCdcrEE5h8DqVxinQjo+2d1q+FV5z7iNtPofw3JsrltSoSVlOGaW0rY8XxtO9XukdTn8TaCGWmk2VFGhI70mg==", "dev": true }, - "@types/uuid": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.5.tgz", - "integrity": "sha512-MNL15wC3EKyw1VLF+RoVO4hJJdk9t/Hlv3rt1OL65Qvuadm4BYo6g9ZJQqoq7X8NBFSsQXgAujWciovh2lpVjA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -299,11 +258,6 @@ "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" } } } diff --git a/packages/tool-cache/package.json b/packages/tool-cache/package.json index 7a05399a..a1ff04b3 100644 --- a/packages/tool-cache/package.json +++ b/packages/tool-cache/package.json @@ -40,13 +40,11 @@ "@actions/exec": "^1.0.0", "@actions/http-client": "^2.0.1", "@actions/io": "^1.1.1", - "semver": "^6.1.0", - "uuid": "^3.3.2" + "semver": "^6.1.0" }, "devDependencies": { "@types/nock": "^11.1.0", "@types/semver": "^6.0.0", - "@types/uuid": "^3.4.4", "nock": "^13.2.9" } } diff --git a/packages/tool-cache/src/tool-cache.ts b/packages/tool-cache/src/tool-cache.ts index 694d1252..f7a7545b 100644 --- a/packages/tool-cache/src/tool-cache.ts +++ b/packages/tool-cache/src/tool-cache.ts @@ -10,7 +10,6 @@ import * as stream from 'stream' import * as util from 'util' import {ok} from 'assert' import {OutgoingHttpHeaders} from 'http' -import uuidV4 from 'uuid/v4' import {exec} from '@actions/exec/lib/exec' import {ExecOptions} from '@actions/exec/lib/interfaces' import {RetryHelper} from './retry-helper' @@ -41,7 +40,7 @@ export async function downloadTool( auth?: string, headers?: OutgoingHttpHeaders ): Promise { - dest = dest || path.join(_getTempDirectory(), uuidV4()) + dest = dest || path.join(_getTempDirectory(), crypto.randomUUID()) await io.mkdirP(path.dirname(dest)) core.debug(`Downloading ${url}`) core.debug(`Destination ${dest}`) @@ -651,7 +650,7 @@ export async function findFromManifest( async function _createExtractFolder(dest?: string): Promise { if (!dest) { // create a temp dir - dest = path.join(_getTempDirectory(), uuidV4()) + dest = path.join(_getTempDirectory(), crypto.randomUUID()) } await io.mkdirP(dest) return dest From 6ca0d9b6375c091baad03e317c1e8c4372a46cdc Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Wed, 2 Oct 2024 13:49:03 -0400 Subject: [PATCH 09/14] Release `@actions/core v1.11.0` (#1839) --- packages/core/RELEASES.md | 3 +++ packages/core/package-lock.json | 4 ++-- packages/core/package.json | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/core/RELEASES.md b/packages/core/RELEASES.md index 14039b56..7eeb4414 100644 --- a/packages/core/RELEASES.md +++ b/packages/core/RELEASES.md @@ -1,5 +1,8 @@ # @actions/core Releases +### 1.11.0 +- Remove dependency on `uuid` package [#1824](https://github.com/actions/toolkit/pull/1824) + ### 1.10.1 - Fix error message reference in oidc utils [#1511](https://github.com/actions/toolkit/pull/1511) diff --git a/packages/core/package-lock.json b/packages/core/package-lock.json index a1515d81..fb11ec9e 100644 --- a/packages/core/package-lock.json +++ b/packages/core/package-lock.json @@ -1,12 +1,12 @@ { "name": "@actions/core", - "version": "1.10.1", + "version": "1.11.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@actions/core", - "version": "1.10.1", + "version": "1.11.0", "license": "MIT", "dependencies": { "@actions/exec": "^1.1.1", diff --git a/packages/core/package.json b/packages/core/package.json index 36fe624c..6bc7f70b 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@actions/core", - "version": "1.10.1", + "version": "1.11.0", "description": "Actions core lib", "keywords": [ "github", From 22a72ac3d71a4666e99b2bb6eb7ef9c7f20369de Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Wed, 2 Oct 2024 14:30:25 -0400 Subject: [PATCH 10/14] Include #1551 in `@actions/core` 1.11.0 release notes (#1840) --- packages/core/RELEASES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/RELEASES.md b/packages/core/RELEASES.md index 7eeb4414..5bc0e31e 100644 --- a/packages/core/RELEASES.md +++ b/packages/core/RELEASES.md @@ -1,6 +1,7 @@ # @actions/core Releases ### 1.11.0 +- Add platform info utilities [#1551](https://github.com/actions/toolkit/pull/1551) - Remove dependency on `uuid` package [#1824](https://github.com/actions/toolkit/pull/1824) ### 1.10.1 From d14afd7973c037fa9f72882decd1eb3befa36135 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Fri, 4 Oct 2024 17:23:42 -0400 Subject: [PATCH 11/14] Explicitly import `crypto` (#1842) * Explicitly import `crypto` * Add release notes for 1.11.1 * Fix crypto mock in test * Fix `crypto` mock * Lint --- packages/cache/src/internal/cacheUtils.ts | 1 + packages/core/RELEASES.md | 3 +++ packages/core/__tests__/core.test.ts | 9 +++++---- packages/core/package-lock.json | 18 +++++++++--------- packages/core/package.json | 4 ++-- packages/core/src/file-command.ts | 1 + packages/tool-cache/src/tool-cache.ts | 1 + 7 files changed, 22 insertions(+), 15 deletions(-) diff --git a/packages/cache/src/internal/cacheUtils.ts b/packages/cache/src/internal/cacheUtils.ts index d8b7f3e0..4c2a16f3 100644 --- a/packages/cache/src/internal/cacheUtils.ts +++ b/packages/cache/src/internal/cacheUtils.ts @@ -2,6 +2,7 @@ import * as core from '@actions/core' import * as exec from '@actions/exec' import * as glob from '@actions/glob' import * as io from '@actions/io' +import * as crypto from 'crypto' import * as fs from 'fs' import * as path from 'path' import * as semver from 'semver' diff --git a/packages/core/RELEASES.md b/packages/core/RELEASES.md index 5bc0e31e..69701660 100644 --- a/packages/core/RELEASES.md +++ b/packages/core/RELEASES.md @@ -1,5 +1,8 @@ # @actions/core Releases +### 1.11.1 +- Fix uses of `crypto.randomUUID` on Node 18 and earlier [#1842](https://github.com/actions/toolkit/pull/1842) + ### 1.11.0 - Add platform info utilities [#1551](https://github.com/actions/toolkit/pull/1551) - Remove dependency on `uuid` package [#1824](https://github.com/actions/toolkit/pull/1824) diff --git a/packages/core/__tests__/core.test.ts b/packages/core/__tests__/core.test.ts index 7fcb3759..2928788d 100644 --- a/packages/core/__tests__/core.test.ts +++ b/packages/core/__tests__/core.test.ts @@ -46,6 +46,11 @@ const testEnvVars = { const UUID = '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d' const DELIMITER = `ghadelimiter_${UUID}` +jest.mock('crypto', () => ({ + ...jest.requireActual('crypto'), + randomUUID: jest.fn(() => UUID) +})) + const TEMP_DIR = path.join(__dirname, '_temp') describe('@actions/core', () => { @@ -66,10 +71,6 @@ describe('@actions/core', () => { process.env[key] = testEnvVars[key as keyof typeof testEnvVars] } process.stdout.write = jest.fn() - - jest.spyOn(crypto, 'randomUUID').mockImplementation(() => { - return UUID - }) }) afterEach(() => { diff --git a/packages/core/package-lock.json b/packages/core/package-lock.json index fb11ec9e..95cf58d2 100644 --- a/packages/core/package-lock.json +++ b/packages/core/package-lock.json @@ -1,19 +1,19 @@ { "name": "@actions/core", - "version": "1.11.0", + "version": "1.11.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@actions/core", - "version": "1.11.0", + "version": "1.11.1", "license": "MIT", "dependencies": { "@actions/exec": "^1.1.1", "@actions/http-client": "^2.0.1" }, "devDependencies": { - "@types/node": "^12.0.2" + "@types/node": "^16.18.112" } }, "node_modules/@actions/exec": { @@ -38,9 +38,9 @@ "integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==" }, "node_modules/@types/node": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.2.tgz", - "integrity": "sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA==", + "version": "16.18.112", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.112.tgz", + "integrity": "sha512-EKrbKUGJROm17+dY/gMi31aJlGLJ75e1IkTojt9n6u+hnaTBDs+M1bIdOawpk2m6YUAXq/R2W0SxCng1tndHCg==", "dev": true }, "node_modules/tunnel": { @@ -75,9 +75,9 @@ "integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==" }, "@types/node": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.2.tgz", - "integrity": "sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA==", + "version": "16.18.112", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.112.tgz", + "integrity": "sha512-EKrbKUGJROm17+dY/gMi31aJlGLJ75e1IkTojt9n6u+hnaTBDs+M1bIdOawpk2m6YUAXq/R2W0SxCng1tndHCg==", "dev": true }, "tunnel": { diff --git a/packages/core/package.json b/packages/core/package.json index 6bc7f70b..6d60010e 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@actions/core", - "version": "1.11.0", + "version": "1.11.1", "description": "Actions core lib", "keywords": [ "github", @@ -40,6 +40,6 @@ "@actions/http-client": "^2.0.1" }, "devDependencies": { - "@types/node": "^12.0.2" + "@types/node": "^16.18.112" } } \ No newline at end of file diff --git a/packages/core/src/file-command.ts b/packages/core/src/file-command.ts index 6750e857..30c9519e 100644 --- a/packages/core/src/file-command.ts +++ b/packages/core/src/file-command.ts @@ -3,6 +3,7 @@ // We use any as a valid input type /* eslint-disable @typescript-eslint/no-explicit-any */ +import * as crypto from 'crypto' import * as fs from 'fs' import * as os from 'os' import {toCommandValue} from './utils' diff --git a/packages/tool-cache/src/tool-cache.ts b/packages/tool-cache/src/tool-cache.ts index f7a7545b..961c26b8 100644 --- a/packages/tool-cache/src/tool-cache.ts +++ b/packages/tool-cache/src/tool-cache.ts @@ -1,5 +1,6 @@ import * as core from '@actions/core' import * as io from '@actions/io' +import * as crypto from 'crypto' import * as fs from 'fs' import * as mm from './manifest' import * as os from 'os' From 545e0e6b95228a9f24e3fc38caa5ebf822688003 Mon Sep 17 00:00:00 2001 From: Rob Herley Date: Tue, 8 Oct 2024 12:35:48 -0400 Subject: [PATCH 12/14] properly resolve relative symlinks --- packages/artifact/RELEASES.md | 4 + .../__tests__/upload-artifact.test.ts | 91 +++++++++++++++---- packages/artifact/package-lock.json | 4 +- packages/artifact/package.json | 2 +- packages/artifact/src/internal/upload/zip.ts | 4 +- 5 files changed, 83 insertions(+), 22 deletions(-) diff --git a/packages/artifact/RELEASES.md b/packages/artifact/RELEASES.md index 219f8764..b91fe895 100644 --- a/packages/artifact/RELEASES.md +++ b/packages/artifact/RELEASES.md @@ -1,5 +1,9 @@ # @actions/artifact Releases +### 2.1.11 + +- Fixed a bug with relative symlinks resolution [#????](https://github.com/actions/toolkit/pull/????) + ### 2.1.10 - Fixed a regression with symlinks not being automatically resolved [#1830](https://github.com/actions/toolkit/pull/1830) diff --git a/packages/artifact/__tests__/upload-artifact.test.ts b/packages/artifact/__tests__/upload-artifact.test.ts index c92abfd6..7c7d8e2e 100644 --- a/packages/artifact/__tests__/upload-artifact.test.ts +++ b/packages/artifact/__tests__/upload-artifact.test.ts @@ -10,6 +10,7 @@ import {FilesNotFoundError} from '../src/internal/shared/errors' import {BlockBlobUploadStreamOptions} from '@azure/storage-blob' import * as fs from 'fs' import * as path from 'path' +import unzip from 'unzip-stream' const uploadStreamMock = jest.fn() const blockBlobClientMock = jest.fn().mockImplementation(() => ({ @@ -31,9 +32,20 @@ const fixtures = { {name: 'file2.txt', content: 'test 2 file content'}, {name: 'file3.txt', content: 'test 3 file content'}, { - name: 'from_symlink.txt', + name: 'real.txt', + content: 'from a symlink' + }, + { + name: 'relative.txt', content: 'from a symlink', - symlink: '../symlinked.txt' + symlink: 'real.txt', + relative: true + }, + { + name: 'absolute.txt', + content: 'from a symlink', + symlink: 'real.txt', + relative: false } ], backendIDs: { @@ -55,14 +67,17 @@ const fixtures = { describe('upload-artifact', () => { beforeAll(() => { - if (!fs.existsSync(fixtures.uploadDirectory)) { - fs.mkdirSync(fixtures.uploadDirectory, {recursive: true}) - } + fs.mkdirSync(fixtures.uploadDirectory, { + recursive: true + }) for (const file of fixtures.files) { if (file.symlink) { - const symlinkPath = path.join(fixtures.uploadDirectory, file.symlink) - fs.writeFileSync(symlinkPath, file.content) + let symlinkPath = file.symlink + if (!file.relative) { + symlinkPath = path.join(fixtures.uploadDirectory, file.symlink) + } + if (!fs.existsSync(path.join(fixtures.uploadDirectory, file.name))) { fs.symlinkSync( symlinkPath, @@ -227,6 +242,12 @@ describe('upload-artifact', () => { }) ) + let loadedBytes = 0 + const uploadedZip = path.join( + fixtures.uploadDirectory, + '..', + 'uploaded.zip' + ) uploadStreamMock.mockImplementation( async ( stream: NodeJS.ReadableStream, @@ -234,19 +255,28 @@ describe('upload-artifact', () => { maxConcurrency?: number, options?: BlockBlobUploadStreamOptions ) => { - const {onProgress, abortSignal} = options || {} + const {onProgress} = options || {} + + if (fs.existsSync(uploadedZip)) { + fs.unlinkSync(uploadedZip) + } + const uploadedZipStream = fs.createWriteStream(uploadedZip) onProgress?.({loadedBytes: 0}) - - return new Promise(resolve => { - const timerId = setTimeout(() => { - onProgress?.({loadedBytes: 256}) - resolve({}) - }, 1_000) - abortSignal?.addEventListener('abort', () => { - clearTimeout(timerId) + return new Promise((resolve, reject) => { + stream.on('data', chunk => { + loadedBytes += chunk.length + uploadedZipStream.write(chunk) + onProgress?.({loadedBytes}) + }) + stream.on('end', () => { + onProgress?.({loadedBytes}) + uploadedZipStream.end() resolve({}) }) + stream.on('error', err => { + reject(err) + }) }) } ) @@ -260,7 +290,34 @@ describe('upload-artifact', () => { ) expect(id).toBe(1) - expect(size).toBe(256) + expect(size).toBe(loadedBytes) + + const extractedDirectory = path.join( + fixtures.uploadDirectory, + '..', + 'extracted' + ) + if (fs.existsSync(extractedDirectory)) { + fs.rmdirSync(extractedDirectory, {recursive: true}) + } + + const extract = new Promise((resolve, reject) => { + fs.createReadStream(uploadedZip) + .pipe(unzip.Extract({path: extractedDirectory})) + .on('close', () => { + resolve(true) + }) + .on('error', err => { + reject(err) + }) + }) + + await expect(extract).resolves.toBe(true) + for (const file of fixtures.files) { + const filePath = path.join(extractedDirectory, file.name) + expect(fs.existsSync(filePath)).toBe(true) + expect(fs.readFileSync(filePath, 'utf8')).toBe(file.content) + } }) it('should throw an error uploading blob chunks get delayed', async () => { diff --git a/packages/artifact/package-lock.json b/packages/artifact/package-lock.json index 778ea790..8608ac3d 100644 --- a/packages/artifact/package-lock.json +++ b/packages/artifact/package-lock.json @@ -1,12 +1,12 @@ { "name": "@actions/artifact", - "version": "2.1.10", + "version": "2.1.11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@actions/artifact", - "version": "2.1.10", + "version": "2.1.11", "license": "MIT", "dependencies": { "@actions/core": "^1.10.0", diff --git a/packages/artifact/package.json b/packages/artifact/package.json index 7d0467f6..3b3233a1 100644 --- a/packages/artifact/package.json +++ b/packages/artifact/package.json @@ -1,6 +1,6 @@ { "name": "@actions/artifact", - "version": "2.1.10", + "version": "2.1.11", "preview": true, "description": "Actions artifact lib", "keywords": [ diff --git a/packages/artifact/src/internal/upload/zip.ts b/packages/artifact/src/internal/upload/zip.ts index 8cc3fd0c..5ea44034 100644 --- a/packages/artifact/src/internal/upload/zip.ts +++ b/packages/artifact/src/internal/upload/zip.ts @@ -1,5 +1,5 @@ import * as stream from 'stream' -import {readlink} from 'fs/promises' +import {realpath} from 'fs/promises' import * as archiver from 'archiver' import * as core from '@actions/core' import {UploadZipSpecification} from './upload-zip-specification' @@ -46,7 +46,7 @@ export async function createZipUploadStream( // Check if symlink and resolve the source path let sourcePath = file.sourcePath if (file.stats.isSymbolicLink()) { - sourcePath = await readlink(file.sourcePath) + sourcePath = await realpath(file.sourcePath) } // Add the file to the zip From 49cbbbcd99a54e01f9358f1b2fbc813383fbd6e3 Mon Sep 17 00:00:00 2001 From: Rob Herley Date: Tue, 8 Oct 2024 13:02:06 -0400 Subject: [PATCH 13/14] Update symlink bug fix reference number --- packages/artifact/RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/artifact/RELEASES.md b/packages/artifact/RELEASES.md index b91fe895..5108614b 100644 --- a/packages/artifact/RELEASES.md +++ b/packages/artifact/RELEASES.md @@ -2,7 +2,7 @@ ### 2.1.11 -- Fixed a bug with relative symlinks resolution [#????](https://github.com/actions/toolkit/pull/????) +- Fixed a bug with relative symlinks resolution [#1844](https://github.com/actions/toolkit/pull/1844) ### 2.1.10 From 799f8f5f3d010445cb560c9786a0d4616d1f15f9 Mon Sep 17 00:00:00 2001 From: Rob Herley Date: Tue, 8 Oct 2024 14:06:04 -0400 Subject: [PATCH 14/14] Update artifact release notes Includes: - #1815 --- packages/artifact/RELEASES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/artifact/RELEASES.md b/packages/artifact/RELEASES.md index 5108614b..d24cdfb5 100644 --- a/packages/artifact/RELEASES.md +++ b/packages/artifact/RELEASES.md @@ -3,6 +3,7 @@ ### 2.1.11 - Fixed a bug with relative symlinks resolution [#1844](https://github.com/actions/toolkit/pull/1844) +- Use native `crypto` [#1815](https://github.com/actions/toolkit/pull/1815) ### 2.1.10