diff --git a/packages/artifact/RELEASES.md b/packages/artifact/RELEASES.md index 6688ad45..d24cdfb5 100644 --- a/packages/artifact/RELEASES.md +++ b/packages/artifact/RELEASES.md @@ -1,5 +1,15 @@ # @actions/artifact Releases +### 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 + +- 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 - 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..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(() => ({ @@ -27,9 +28,25 @@ 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: 'real.txt', + content: 'from a symlink' + }, + { + name: 'relative.txt', + content: 'from a symlink', + symlink: 'real.txt', + relative: true + }, + { + name: 'absolute.txt', + content: 'from a symlink', + symlink: 'real.txt', + relative: false + } ], backendIDs: { workflowRunBackendId: '67dbcc20-e851-4452-a7c3-2cc0d2e0ec67', @@ -50,12 +67,30 @@ 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, content] of fixtures.files) { - fs.writeFileSync(path.join(fixtures.uploadDirectory, file), content) + for (const file of fixtures.files) { + if (file.symlink) { + 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, + path.join(fixtures.uploadDirectory, file.name), + 'file' + ) + } + } else { + fs.writeFileSync( + path.join(fixtures.uploadDirectory, file.name), + file.content + ) + } } }) @@ -71,8 +106,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 +221,10 @@ describe('upload-artifact', () => { }) it('should successfully upload an artifact', async () => { + jest + .spyOn(uploadZipSpecification, 'getUploadZipSpecification') + .mockRestore() + jest .spyOn(ArtifactServiceClientJSON.prototype, 'CreateArtifact') .mockReturnValue( @@ -202,6 +242,12 @@ describe('upload-artifact', () => { }) ) + let loadedBytes = 0 + const uploadedZip = path.join( + fixtures.uploadDirectory, + '..', + 'uploaded.zip' + ) uploadStreamMock.mockImplementation( async ( stream: NodeJS.ReadableStream, @@ -209,31 +255,69 @@ 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) + }) }) } ) 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) - 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/__tests__/upload-zip-specification.test.ts b/packages/artifact/__tests__/upload-zip-specification.test.ts index 0b59bff7..9688aa6f 100644 --- a/packages/artifact/__tests__/upload-zip-specification.test.ts +++ b/packages/artifact/__tests__/upload-zip-specification.test.ts @@ -305,4 +305,22 @@ 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( + path.join('/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..8608ac3d 100644 --- a/packages/artifact/package-lock.json +++ b/packages/artifact/package-lock.json @@ -1,12 +1,12 @@ { "name": "@actions/artifact", - "version": "2.1.9", + "version": "2.1.11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@actions/artifact", - "version": "2.1.9", + "version": "2.1.11", "license": "MIT", "dependencies": { "@actions/core": "^1.10.0", @@ -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", @@ -1315,9 +1308,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..3b3233a1 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.11", "preview": true, "description": "Actions artifact lib", "keywords": [ @@ -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" 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..5ea44034 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 {realpath} 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 realpath(file.sourcePath) + } + + // Add the file to the zip + zip.file(sourcePath, { name: file.destinationPath }) } else { diff --git a/packages/cache/package-lock.json b/packages/cache/package-lock.json index f71c3e1b..6aa58d16 100644 --- a/packages/cache/package-lock.json +++ b/packages/cache/package-lock.json @@ -18,12 +18,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" } }, @@ -578,12 +576,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", @@ -1682,34 +1674,6 @@ "node": ">=14.17" } }, - "node_modules/universal-user-agent": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", - "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==" - }, - "node_modules/unzip-stream": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/unzip-stream/-/unzip-stream-0.3.4.tgz", - "integrity": "sha512-PyofABPVv+d7fL7GOpusx7eRT9YETY2X04PhwbSipdj6bMxVCFJrr+nm0Mxqbf9hUiTin/UsnuFWBXlDZFy0Cw==", - "dependencies": { - "binary": "^0.3.0", - "mkdirp": "^0.5.1" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "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", @@ -2356,12 +2320,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", @@ -3152,30 +3110,6 @@ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true }, - "universal-user-agent": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", - "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==" - }, - "unzip-stream": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/unzip-stream/-/unzip-stream-0.3.4.tgz", - "integrity": "sha512-PyofABPVv+d7fL7GOpusx7eRT9YETY2X04PhwbSipdj6bMxVCFJrr+nm0Mxqbf9hUiTin/UsnuFWBXlDZFy0Cw==", - "requires": { - "binary": "^0.3.0", - "mkdirp": "^0.5.1" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "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", @@ -3291,4 +3225,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/cache/package.json b/packages/cache/package.json index 78f33c14..3e5695fb 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -46,12 +46,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 48a0b354..bd493172 100644 --- a/packages/cache/src/internal/cacheUtils.ts +++ b/packages/cache/src/internal/cacheUtils.ts @@ -2,12 +2,11 @@ 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' import * as util from 'util' -import { v4 as uuidV4 } from 'uuid' -import * as crypto from 'crypto' import { CacheFilename, CompressionMethod, @@ -37,7 +36,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/RELEASES.md b/packages/core/RELEASES.md index 14039b56..69701660 100644 --- a/packages/core/RELEASES.md +++ b/packages/core/RELEASES.md @@ -1,5 +1,12 @@ # @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) + ### 1.10.1 - Fix error message reference in oidc utils [#1511](https://github.com/actions/toolkit/pull/1511) diff --git a/packages/core/__tests__/core.test.ts b/packages/core/__tests__/core.test.ts index 09bc587b..2928788d 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,23 @@ 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', () => { 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)) + } } }) @@ -62,10 +71,6 @@ describe('@actions/core', () => { process.env[key] = testEnvVars[key as keyof typeof testEnvVars] } process.stdout.write = jest.fn() - - jest.spyOn(uuid, 'v4').mockImplementation(() => { - return UUID - }) }) afterEach(() => { @@ -141,7 +146,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 +160,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 +352,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 +366,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 +590,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 +604,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 +646,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 +654,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..95cf58d2 100644 --- a/packages/core/package-lock.json +++ b/packages/core/package-lock.json @@ -1,21 +1,19 @@ { "name": "@actions/core", - "version": "1.10.1", + "version": "1.11.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@actions/core", - "version": "1.10.1", + "version": "1.11.1", "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": "^16.18.112" } }, "node_modules/@actions/exec": { @@ -40,15 +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==", - "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==", + "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": { @@ -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": { @@ -91,26 +75,15 @@ "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==", - "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==", + "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": { "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..6d60010e 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.1", "description": "Actions core lib", "keywords": [ "github", @@ -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": "^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 832c2f0e..30c9519e 100644 --- a/packages/core/src/file-command.ts +++ b/packages/core/src/file-command.ts @@ -3,9 +3,9 @@ // 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 {v4 as uuidv4} from 'uuid' import {toCommandValue} from './utils' export function issueFileCommand(command: string, message: any): void { @@ -25,7 +25,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..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' @@ -10,7 +11,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 +41,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 +651,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