@ronaldphilipsen/local-action 0.0.0-stage → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.checkov.yml +3 -0
- package/.env.example +379 -0
- package/.github/codeql/codeql-config.yml +7 -0
- package/.github/copilot-instructions.md +79 -0
- package/.github/dependabot.yml +32 -0
- package/.github/workflows/codeql-analysis.yml +53 -0
- package/.github/workflows/continuous-delivery.yml +93 -0
- package/.github/workflows/continuous-integration.yml +382 -0
- package/.github/workflows/linter.yml +47 -0
- package/.github/workflows/release.yaml +100 -0
- package/.github/workflows/version-check.yml +44 -0
- package/.grype.yml +151 -0
- package/.markdown-lint.yml +7 -0
- package/.mega-linter.yml +188 -0
- package/.node-version +1 -0
- package/.prettierignore +4 -0
- package/.prettierrc.yml +14 -0
- package/.vscode/launch.json +15 -0
- package/.vscode/mcp.json +9 -0
- package/.vscode/settings.json +15 -0
- package/.vscode/tasks.json +51 -0
- package/.yaml-lint.yml +10 -0
- package/CHANGELOG.md +75 -0
- package/CODEOWNERS +3 -0
- package/CODE_OF_CONDUCT.md +74 -0
- package/CONTRIBUTING.md +140 -0
- package/LICENSE +21 -0
- package/README.md +277 -2
- package/SECURITY.md +42 -0
- package/SUPPORT.md +19 -0
- package/__fixtures__/@actions/core.ts +14 -0
- package/__fixtures__/@actions/exec.ts +9 -0
- package/__fixtures__/@actions/github.ts +3 -0
- package/__fixtures__/@actions/http-client.ts +9 -0
- package/__fixtures__/@actions/io.ts +9 -0
- package/__fixtures__/@octokit/rest.ts +18 -0
- package/__fixtures__/crypto.ts +7 -0
- package/__fixtures__/fs.ts +27 -0
- package/__fixtures__/javascript/no-export/.env.fixture +2 -0
- package/__fixtures__/javascript/no-export/action.yml +16 -0
- package/__fixtures__/javascript/no-export/node_modules/.gitkeep +0 -0
- package/__fixtures__/javascript/no-export/package.json +12 -0
- package/__fixtures__/javascript/no-export/src/index.js +0 -0
- package/__fixtures__/javascript/no-export/src/main.js +0 -0
- package/__fixtures__/javascript/no-import/.env.fixture +2 -0
- package/__fixtures__/javascript/no-import/action.yml +16 -0
- package/__fixtures__/javascript/no-import/node_modules/.gitkeep +0 -0
- package/__fixtures__/javascript/no-import/package.json +12 -0
- package/__fixtures__/javascript/no-import/src/index.js +3 -0
- package/__fixtures__/javascript/no-import/src/main.js +7 -0
- package/__fixtures__/javascript/success/.env.fixture +2 -0
- package/__fixtures__/javascript/success/action.yml +16 -0
- package/__fixtures__/javascript/success/node_modules/.gitkeep +0 -0
- package/__fixtures__/javascript/success/package.json +12 -0
- package/__fixtures__/javascript/success/post/index.js +3 -0
- package/__fixtures__/javascript/success/post/main.js +13 -0
- package/__fixtures__/javascript/success/pre/index.js +3 -0
- package/__fixtures__/javascript/success/pre/main.js +13 -0
- package/__fixtures__/javascript/success/src/index.js +3 -0
- package/__fixtures__/javascript/success/src/main.js +13 -0
- package/__fixtures__/javascript-esm/no-import/.env.fixture +2 -0
- package/__fixtures__/javascript-esm/no-import/action.yml +16 -0
- package/__fixtures__/javascript-esm/no-import/node_modules/.gitkeep +0 -0
- package/__fixtures__/javascript-esm/no-import/package.json +13 -0
- package/__fixtures__/javascript-esm/no-import/src/index.js +3 -0
- package/__fixtures__/javascript-esm/no-import/src/main.js +7 -0
- package/__fixtures__/javascript-esm/success/.env.fixture +2 -0
- package/__fixtures__/javascript-esm/success/action.yml +16 -0
- package/__fixtures__/javascript-esm/success/node_modules/.gitkeep +0 -0
- package/__fixtures__/javascript-esm/success/package.json +13 -0
- package/__fixtures__/javascript-esm/success/post/index.js +3 -0
- package/__fixtures__/javascript-esm/success/post/main.js +13 -0
- package/__fixtures__/javascript-esm/success/pre/index.js +3 -0
- package/__fixtures__/javascript-esm/success/pre/main.js +13 -0
- package/__fixtures__/javascript-esm/success/src/index.js +3 -0
- package/__fixtures__/javascript-esm/success/src/main.js +13 -0
- package/__fixtures__/path.ts +7 -0
- package/__fixtures__/payloads/issue_opened.json +33 -0
- package/__fixtures__/stream/promises.ts +3 -0
- package/__fixtures__/tsconfig-paths.ts +4 -0
- package/__fixtures__/typescript/no-import/.env.fixture +2 -0
- package/__fixtures__/typescript/no-import/action.yml +16 -0
- package/__fixtures__/typescript/no-import/node_modules/.gitkeep +0 -0
- package/__fixtures__/typescript/no-import/package.json +15 -0
- package/__fixtures__/typescript/no-import/src/index.ts +3 -0
- package/__fixtures__/typescript/no-import/src/main.ts +3 -0
- package/__fixtures__/typescript/no-import/tsconfig.json +20 -0
- package/__fixtures__/typescript/success/.env.fixture +2 -0
- package/__fixtures__/typescript/success/action.yml +16 -0
- package/__fixtures__/typescript/success/node_modules/.gitkeep +0 -0
- package/__fixtures__/typescript/success/package.json +15 -0
- package/__fixtures__/typescript/success/post/index.ts +3 -0
- package/__fixtures__/typescript/success/post/main.ts +9 -0
- package/__fixtures__/typescript/success/pre/index.ts +3 -0
- package/__fixtures__/typescript/success/pre/main.ts +9 -0
- package/__fixtures__/typescript/success/src/index.ts +3 -0
- package/__fixtures__/typescript/success/src/main.ts +9 -0
- package/__fixtures__/typescript/success/tsconfig.json +20 -0
- package/__fixtures__/typescript/success-yaml/.env.fixture +2 -0
- package/__fixtures__/typescript/success-yaml/action.yaml +16 -0
- package/__fixtures__/typescript/success-yaml/node_modules/.gitkeep +0 -0
- package/__fixtures__/typescript/success-yaml/package.json +15 -0
- package/__fixtures__/typescript/success-yaml/post/index.ts +3 -0
- package/__fixtures__/typescript/success-yaml/post/main.ts +9 -0
- package/__fixtures__/typescript/success-yaml/pre/index.ts +3 -0
- package/__fixtures__/typescript/success-yaml/pre/main.ts +9 -0
- package/__fixtures__/typescript/success-yaml/src/index.ts +3 -0
- package/__fixtures__/typescript/success-yaml/src/main.ts +9 -0
- package/__fixtures__/typescript/success-yaml/tsconfig.json +20 -0
- package/__fixtures__/typescript-esm/no-export/.env.fixture +2 -0
- package/__fixtures__/typescript-esm/no-export/action.yml +17 -0
- package/__fixtures__/typescript-esm/no-export/node_modules/.gitkeep +0 -0
- package/__fixtures__/typescript-esm/no-export/package.json +17 -0
- package/__fixtures__/typescript-esm/no-export/src/index.ts +0 -0
- package/__fixtures__/typescript-esm/no-export/src/main.ts +0 -0
- package/__fixtures__/typescript-esm/no-export/tsconfig.json +25 -0
- package/__fixtures__/typescript-esm/no-import/.env.fixture +2 -0
- package/__fixtures__/typescript-esm/no-import/action.yml +17 -0
- package/__fixtures__/typescript-esm/no-import/node_modules/.gitkeep +0 -0
- package/__fixtures__/typescript-esm/no-import/package.json +17 -0
- package/__fixtures__/typescript-esm/no-import/src/index.ts +3 -0
- package/__fixtures__/typescript-esm/no-import/src/main.ts +3 -0
- package/__fixtures__/typescript-esm/no-import/tsconfig.json +25 -0
- package/__fixtures__/typescript-esm/success/.env.fixture +2 -0
- package/__fixtures__/typescript-esm/success/action.yml +17 -0
- package/__fixtures__/typescript-esm/success/node_modules/.gitkeep +0 -0
- package/__fixtures__/typescript-esm/success/package.json +17 -0
- package/__fixtures__/typescript-esm/success/post/index.ts +3 -0
- package/__fixtures__/typescript-esm/success/post/main.ts +9 -0
- package/__fixtures__/typescript-esm/success/pre/index.ts +3 -0
- package/__fixtures__/typescript-esm/success/pre/main.ts +9 -0
- package/__fixtures__/typescript-esm/success/src/index.ts +3 -0
- package/__fixtures__/typescript-esm/success/src/main.ts +9 -0
- package/__fixtures__/typescript-esm/success/tsconfig.json +25 -0
- package/__fixtures__/typescript-esm/tsconfig-comments/.env.fixture +2 -0
- package/__fixtures__/typescript-esm/tsconfig-comments/action.yml +17 -0
- package/__fixtures__/typescript-esm/tsconfig-comments/node_modules/.gitkeep +0 -0
- package/__fixtures__/typescript-esm/tsconfig-comments/package.json +17 -0
- package/__fixtures__/typescript-esm/tsconfig-comments/src/index.ts +3 -0
- package/__fixtures__/typescript-esm/tsconfig-comments/src/main.ts +9 -0
- package/__fixtures__/typescript-esm/tsconfig-comments/tsconfig.json +21 -0
- package/__tests__/command.test.ts +224 -0
- package/__tests__/stubs/artifact/internal/client.test.ts +340 -0
- package/__tests__/stubs/artifact/internal/delete/delete-artifact.test.ts +152 -0
- package/__tests__/stubs/artifact/internal/download/download-artifact.test.ts +119 -0
- package/__tests__/stubs/artifact/internal/find/get-artifact.test.ts +237 -0
- package/__tests__/stubs/artifact/internal/find/list-artifacts.test.ts +218 -0
- package/__tests__/stubs/artifact/internal/find/retry-options.test.ts +54 -0
- package/__tests__/stubs/artifact/internal/shared/config.test.ts +91 -0
- package/__tests__/stubs/artifact/internal/shared/errors.test.ts +38 -0
- package/__tests__/stubs/artifact/internal/shared/user-agent.test.ts +22 -0
- package/__tests__/stubs/artifact/internal/upload/path-and-artifact-name-validation.test.ts +53 -0
- package/__tests__/stubs/artifact/internal/upload/upload-artifact.test.ts +126 -0
- package/__tests__/stubs/artifact/internal/upload/upload-zip-specification.test.ts +49 -0
- package/__tests__/stubs/cache/cache.test.ts +357 -0
- package/__tests__/stubs/cache/errors.test.ts +55 -0
- package/__tests__/stubs/cache/internal/cacheUtils.test.ts +109 -0
- package/__tests__/stubs/cache/internal/constants.test.ts +81 -0
- package/__tests__/stubs/cache/internal/tar.test.ts +129 -0
- package/__tests__/stubs/core/core.test.ts +760 -0
- package/__tests__/stubs/core/path-utils.test.ts +45 -0
- package/__tests__/stubs/core/platform.test.ts +89 -0
- package/__tests__/stubs/core/summary.test.ts +455 -0
- package/__tests__/stubs/env.test.ts +72 -0
- package/__tests__/stubs/github/context.test.ts +73 -0
- package/__tests__/stubs/github/github.test.ts +15 -0
- package/__tests__/stubs/github/internal/utils.test.ts +98 -0
- package/__tests__/stubs/github/utils.test.ts +16 -0
- package/__tests__/utils/config.test.ts +78 -0
- package/__tests__/utils/output.test.ts +32 -0
- package/__tests__/utils/package.test.ts +33 -0
- package/badges/coverage.svg +1 -0
- package/bin/local-action.js +121 -0
- package/docs/create-a-job-summary.md +32 -0
- package/docs/debugging-in-vscode.md +27 -0
- package/docs/img/job-summary.png +0 -0
- package/docs/supported-functionality.md +126 -0
- package/eslint.config.mjs +74 -0
- package/jest.config.ts +41 -0
- package/package.json +93 -4
- package/src/command.ts +171 -0
- package/src/commands/run.ts +616 -0
- package/src/index.ts +21 -0
- package/src/stubs/artifact/artifact.ts +17 -0
- package/src/stubs/artifact/internal/client.ts +400 -0
- package/src/stubs/artifact/internal/delete/delete-artifact.ts +126 -0
- package/src/stubs/artifact/internal/download/download-artifact.ts +309 -0
- package/src/stubs/artifact/internal/find/get-artifact.ts +135 -0
- package/src/stubs/artifact/internal/find/list-artifacts.ts +188 -0
- package/src/stubs/artifact/internal/find/retry-options.ts +57 -0
- package/src/stubs/artifact/internal/shared/config.ts +64 -0
- package/src/stubs/artifact/internal/shared/errors.ts +53 -0
- package/src/stubs/artifact/internal/shared/interfaces.ts +195 -0
- package/src/stubs/artifact/internal/shared/user-agent.ts +13 -0
- package/src/stubs/artifact/internal/upload/path-and-artifact-name-validation.ts +92 -0
- package/src/stubs/artifact/internal/upload/upload-artifact.ts +127 -0
- package/src/stubs/artifact/internal/upload/upload-zip-specification.ts +108 -0
- package/src/stubs/artifact/internal/upload/zip.ts +122 -0
- package/src/stubs/cache/cache.ts +334 -0
- package/src/stubs/cache/errors.ts +31 -0
- package/src/stubs/cache/interfaces.ts +4 -0
- package/src/stubs/cache/internal/cacheUtils.ts +207 -0
- package/src/stubs/cache/internal/constants.ts +45 -0
- package/src/stubs/cache/internal/tar.ts +374 -0
- package/src/stubs/cache/options.ts +91 -0
- package/src/stubs/core/core.ts +743 -0
- package/src/stubs/core/path-utils.ts +39 -0
- package/src/stubs/core/platform.ts +132 -0
- package/src/stubs/core/summary.ts +399 -0
- package/src/stubs/env.ts +40 -0
- package/src/stubs/github/context.ts +94 -0
- package/src/stubs/github/github.ts +29 -0
- package/src/stubs/github/interfaces.ts +52 -0
- package/src/stubs/github/internal/utils.ts +83 -0
- package/src/stubs/github/utils.ts +52 -0
- package/src/types/quibble.d.ts +5 -0
- package/src/types.ts +116 -0
- package/src/utils/config.ts +47 -0
- package/src/utils/output.ts +20 -0
- package/src/utils/package.ts +38 -0
- package/tsconfig.base.json +29 -0
- package/tsconfig.eslint.json +22 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Last Reviewed Commit: b2557ac90ca11aad2f3dfb23565c54e91cef5dfe
|
|
3
|
+
* Last Reviewed Date: 2026-01-16
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export enum CacheFilename {
|
|
7
|
+
Gzip = 'cache.tgz',
|
|
8
|
+
Zstd = 'cache.tzst'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export enum CompressionMethod {
|
|
12
|
+
Gzip = 'gzip',
|
|
13
|
+
// Long range mode was added to zstd in v1.3.2.
|
|
14
|
+
// This enum is for earlier version of zstd that does not have --long support
|
|
15
|
+
ZstdWithoutLong = 'zstd-without-long',
|
|
16
|
+
Zstd = 'zstd'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export enum ArchiveToolType {
|
|
20
|
+
GNU = 'gnu',
|
|
21
|
+
BSD = 'bsd'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// The default number of retry attempts.
|
|
25
|
+
export const DefaultRetryAttempts = 2
|
|
26
|
+
|
|
27
|
+
// The default delay in milliseconds between retry attempts.
|
|
28
|
+
export const DefaultRetryDelay = 5000
|
|
29
|
+
|
|
30
|
+
// Socket timeout in milliseconds during download. If no traffic is received
|
|
31
|
+
// over the socket during this period, the socket is destroyed and the download
|
|
32
|
+
// is aborted.
|
|
33
|
+
export const SocketTimeout = 5000
|
|
34
|
+
|
|
35
|
+
// The default path of GNUtar on hosted Windows runners
|
|
36
|
+
export const GnuTarPathOnWindows = `${process.env['PROGRAMFILES']}\\Git\\usr\\bin\\tar.exe`
|
|
37
|
+
|
|
38
|
+
// The default path of BSDtar on hosted Windows runners
|
|
39
|
+
export const SystemTarPathOnWindows = `${process.env['SYSTEMDRIVE']}\\Windows\\System32\\tar.exe`
|
|
40
|
+
|
|
41
|
+
export const TarFilename = 'cache.tar'
|
|
42
|
+
|
|
43
|
+
export const ManifestFilename = 'manifest.txt'
|
|
44
|
+
|
|
45
|
+
export const CacheFileSizeLimit = 10 * Math.pow(1024, 3) // 10GiB per repository
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Last Reviewed Commit: ea21da69936b05b9a4e65cd3be2b054bf3a6db23
|
|
3
|
+
* Last Reviewed Date: 2025-01-16
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { exec } from '@actions/exec'
|
|
7
|
+
import * as io from '@actions/io'
|
|
8
|
+
import { existsSync, writeFileSync } from 'fs'
|
|
9
|
+
import * as path from 'path'
|
|
10
|
+
import { ArchiveTool } from '../interfaces.js'
|
|
11
|
+
import * as utils from './cacheUtils.js'
|
|
12
|
+
import {
|
|
13
|
+
ArchiveToolType,
|
|
14
|
+
CompressionMethod,
|
|
15
|
+
ManifestFilename,
|
|
16
|
+
SystemTarPathOnWindows,
|
|
17
|
+
TarFilename
|
|
18
|
+
} from './constants.js'
|
|
19
|
+
|
|
20
|
+
const IS_WINDOWS = process.platform === 'win32'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Returns tar path and type: BSD or GNU
|
|
24
|
+
*
|
|
25
|
+
* @returns Path and type of tar
|
|
26
|
+
*/
|
|
27
|
+
/* istanbul ignore next */
|
|
28
|
+
async function getTarPath(): Promise<ArchiveTool> {
|
|
29
|
+
switch (process.platform) {
|
|
30
|
+
case 'win32': {
|
|
31
|
+
const gnuTar = await utils.getGnuTarPathOnWindows()
|
|
32
|
+
const systemTar = SystemTarPathOnWindows
|
|
33
|
+
if (gnuTar) {
|
|
34
|
+
// Use GNUtar as default on windows
|
|
35
|
+
return <ArchiveTool>{ path: gnuTar, type: ArchiveToolType.GNU }
|
|
36
|
+
} else if (existsSync(systemTar)) {
|
|
37
|
+
return <ArchiveTool>{ path: systemTar, type: ArchiveToolType.BSD }
|
|
38
|
+
}
|
|
39
|
+
break
|
|
40
|
+
}
|
|
41
|
+
case 'darwin': {
|
|
42
|
+
const gnuTar = await io.which('gtar', false)
|
|
43
|
+
if (gnuTar) {
|
|
44
|
+
// fix permission denied errors when extracting BSD tar archive with GNU tar - https://github.com/actions/cache/issues/527
|
|
45
|
+
return <ArchiveTool>{ path: gnuTar, type: ArchiveToolType.GNU }
|
|
46
|
+
} else {
|
|
47
|
+
return <ArchiveTool>{
|
|
48
|
+
path: await io.which('tar', true),
|
|
49
|
+
type: ArchiveToolType.BSD
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
default:
|
|
54
|
+
break
|
|
55
|
+
}
|
|
56
|
+
// Default assumption is GNU tar is present in path
|
|
57
|
+
return <ArchiveTool>{
|
|
58
|
+
path: await io.which('tar', true),
|
|
59
|
+
type: ArchiveToolType.GNU
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Return arguments for tar as per tarPath, compressionMethod, method type and os
|
|
65
|
+
*
|
|
66
|
+
* @param tarPath Path and type of tar
|
|
67
|
+
* @param compressionMethod Compression method
|
|
68
|
+
* @param type Type of operation: create, extract, list
|
|
69
|
+
* @param archivePath Archive path for extract and list operations
|
|
70
|
+
* @returns List of arguments for tar command
|
|
71
|
+
*
|
|
72
|
+
* @remarks
|
|
73
|
+
*
|
|
74
|
+
* - Made archivePath required for create operation
|
|
75
|
+
* - Removed exclude statement for creation since it happens in a different path
|
|
76
|
+
*/
|
|
77
|
+
async function getTarArgs(
|
|
78
|
+
tarPath: ArchiveTool,
|
|
79
|
+
compressionMethod: CompressionMethod,
|
|
80
|
+
type: string,
|
|
81
|
+
archivePath: string
|
|
82
|
+
): Promise<string[]> {
|
|
83
|
+
const args = [`"${tarPath.path}"`]
|
|
84
|
+
const cacheFileName = utils.getCacheFileName(compressionMethod)
|
|
85
|
+
const tarFile = 'cache.tar'
|
|
86
|
+
const workingDirectory = getWorkingDirectory()
|
|
87
|
+
|
|
88
|
+
// Speficic args for BSD tar on windows for workaround
|
|
89
|
+
/* istanbul ignore next */
|
|
90
|
+
const BSD_TAR_ZSTD =
|
|
91
|
+
tarPath.type === ArchiveToolType.BSD &&
|
|
92
|
+
compressionMethod !== CompressionMethod.Gzip &&
|
|
93
|
+
IS_WINDOWS
|
|
94
|
+
|
|
95
|
+
// Method specific args
|
|
96
|
+
switch (type) {
|
|
97
|
+
case 'create':
|
|
98
|
+
args.push(
|
|
99
|
+
'--posix',
|
|
100
|
+
'-cf',
|
|
101
|
+
/* istanbul ignore next */
|
|
102
|
+
BSD_TAR_ZSTD
|
|
103
|
+
? tarFile
|
|
104
|
+
: path
|
|
105
|
+
.join(archivePath, cacheFileName)
|
|
106
|
+
.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
|
107
|
+
'-P',
|
|
108
|
+
'-C',
|
|
109
|
+
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
|
110
|
+
'--files-from',
|
|
111
|
+
path.join(process.env.LOCAL_ACTION_WORKSPACE!, ManifestFilename)
|
|
112
|
+
)
|
|
113
|
+
break
|
|
114
|
+
case 'extract':
|
|
115
|
+
args.push(
|
|
116
|
+
'-xf',
|
|
117
|
+
/* istanbul ignore next */
|
|
118
|
+
BSD_TAR_ZSTD
|
|
119
|
+
? tarFile
|
|
120
|
+
: archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
|
121
|
+
'-P',
|
|
122
|
+
'-C',
|
|
123
|
+
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
|
|
124
|
+
)
|
|
125
|
+
break
|
|
126
|
+
case 'list':
|
|
127
|
+
args.push(
|
|
128
|
+
'-tf',
|
|
129
|
+
/* istanbul ignore next */
|
|
130
|
+
BSD_TAR_ZSTD
|
|
131
|
+
? tarFile
|
|
132
|
+
: archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
|
133
|
+
'-P'
|
|
134
|
+
)
|
|
135
|
+
break
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Platform specific args
|
|
139
|
+
/* istanbul ignore next */
|
|
140
|
+
if (tarPath.type === ArchiveToolType.GNU) {
|
|
141
|
+
switch (process.platform) {
|
|
142
|
+
case 'win32':
|
|
143
|
+
args.push('--force-local')
|
|
144
|
+
break
|
|
145
|
+
case 'darwin':
|
|
146
|
+
args.push('--delay-directory-restore')
|
|
147
|
+
break
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return args
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Returns commands to run TAR and compression program
|
|
156
|
+
*
|
|
157
|
+
* @param compressionMethod Compression method
|
|
158
|
+
* @param type Type of operation: create, extract, list
|
|
159
|
+
* @param archivePath Archive path for create, extract, and list operations
|
|
160
|
+
* @returns List of commands to run
|
|
161
|
+
*/
|
|
162
|
+
/* istanbul ignore next */
|
|
163
|
+
async function getCommands(
|
|
164
|
+
compressionMethod: CompressionMethod,
|
|
165
|
+
type: string,
|
|
166
|
+
archivePath = ''
|
|
167
|
+
): Promise<string[]> {
|
|
168
|
+
let args
|
|
169
|
+
|
|
170
|
+
const tarPath = await getTarPath()
|
|
171
|
+
const tarArgs = await getTarArgs(
|
|
172
|
+
tarPath,
|
|
173
|
+
compressionMethod,
|
|
174
|
+
type,
|
|
175
|
+
archivePath
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
const compressionArgs =
|
|
179
|
+
type !== 'create'
|
|
180
|
+
? await getDecompressionProgram(tarPath, compressionMethod, archivePath)
|
|
181
|
+
: await getCompressionProgram(tarPath, compressionMethod)
|
|
182
|
+
|
|
183
|
+
const BSD_TAR_ZSTD =
|
|
184
|
+
tarPath.type === ArchiveToolType.BSD &&
|
|
185
|
+
compressionMethod !== CompressionMethod.Gzip &&
|
|
186
|
+
IS_WINDOWS
|
|
187
|
+
|
|
188
|
+
if (BSD_TAR_ZSTD && type !== 'create')
|
|
189
|
+
args = [[...compressionArgs].join(' '), [...tarArgs].join(' ')]
|
|
190
|
+
else args = [[...tarArgs].join(' '), [...compressionArgs].join(' ')]
|
|
191
|
+
|
|
192
|
+
if (BSD_TAR_ZSTD) return args
|
|
193
|
+
|
|
194
|
+
return [args.join(' ')]
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Gets the working directory (local or GitHub Actions)
|
|
199
|
+
*
|
|
200
|
+
* @returns Working directory
|
|
201
|
+
*/
|
|
202
|
+
/* istanbul ignore next */
|
|
203
|
+
function getWorkingDirectory(): string {
|
|
204
|
+
return process.env.GITHUB_WORKSPACE ?? process.cwd()
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Common function for extractTar and listTar to get the compression method
|
|
209
|
+
*
|
|
210
|
+
* @param tarPath Path and type of tar
|
|
211
|
+
* @param compressionMethod Compression method
|
|
212
|
+
* @param archivePath Archive path for extract and list operations
|
|
213
|
+
* @returns List of arguments for decompression program
|
|
214
|
+
*/
|
|
215
|
+
/* istanbul ignore next */
|
|
216
|
+
async function getDecompressionProgram(
|
|
217
|
+
tarPath: ArchiveTool,
|
|
218
|
+
compressionMethod: CompressionMethod,
|
|
219
|
+
archivePath: string
|
|
220
|
+
): Promise<string[]> {
|
|
221
|
+
// -d: Decompress.
|
|
222
|
+
// unzstd is equivalent to 'zstd -d'
|
|
223
|
+
// --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
|
|
224
|
+
// Using 30 here because we also support 32-bit self-hosted runners.
|
|
225
|
+
const BSD_TAR_ZSTD =
|
|
226
|
+
tarPath.type === ArchiveToolType.BSD &&
|
|
227
|
+
compressionMethod !== CompressionMethod.Gzip &&
|
|
228
|
+
IS_WINDOWS
|
|
229
|
+
switch (compressionMethod) {
|
|
230
|
+
case CompressionMethod.Zstd:
|
|
231
|
+
return BSD_TAR_ZSTD
|
|
232
|
+
? [
|
|
233
|
+
'zstd -d --long=30 --force -o',
|
|
234
|
+
TarFilename,
|
|
235
|
+
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
|
|
236
|
+
]
|
|
237
|
+
: [
|
|
238
|
+
'--use-compress-program',
|
|
239
|
+
IS_WINDOWS ? '"zstd -d --long=30"' : 'unzstd --long=30'
|
|
240
|
+
]
|
|
241
|
+
case CompressionMethod.ZstdWithoutLong:
|
|
242
|
+
return BSD_TAR_ZSTD
|
|
243
|
+
? [
|
|
244
|
+
'zstd -d --force -o',
|
|
245
|
+
TarFilename,
|
|
246
|
+
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
|
|
247
|
+
]
|
|
248
|
+
: ['--use-compress-program', IS_WINDOWS ? '"zstd -d"' : 'unzstd']
|
|
249
|
+
default:
|
|
250
|
+
return ['-z']
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Used for creating the archive
|
|
256
|
+
*
|
|
257
|
+
* -T#: Compress using # working thread. If # is 0, attempt to detect and use the number of physical CPU cores.
|
|
258
|
+
* zstdmt is equivalent to 'zstd -T0'
|
|
259
|
+
* --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
|
|
260
|
+
* Using 30 here because we also support 32-bit self-hosted runners.
|
|
261
|
+
* Long range mode is added to zstd in v1.3.2 release, so we will not use --long in older version of zstd.
|
|
262
|
+
*/
|
|
263
|
+
/* istanbul ignore next */
|
|
264
|
+
async function getCompressionProgram(
|
|
265
|
+
tarPath: ArchiveTool,
|
|
266
|
+
compressionMethod: CompressionMethod
|
|
267
|
+
): Promise<string[]> {
|
|
268
|
+
const cacheFileName = utils.getCacheFileName(compressionMethod)
|
|
269
|
+
const BSD_TAR_ZSTD =
|
|
270
|
+
tarPath.type === ArchiveToolType.BSD &&
|
|
271
|
+
compressionMethod !== CompressionMethod.Gzip &&
|
|
272
|
+
IS_WINDOWS
|
|
273
|
+
switch (compressionMethod) {
|
|
274
|
+
case CompressionMethod.Zstd:
|
|
275
|
+
return BSD_TAR_ZSTD
|
|
276
|
+
? [
|
|
277
|
+
'zstd -T0 --long=30 --force -o',
|
|
278
|
+
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
|
279
|
+
TarFilename
|
|
280
|
+
]
|
|
281
|
+
: [
|
|
282
|
+
'--use-compress-program',
|
|
283
|
+
IS_WINDOWS ? '"zstd -T0 --long=30"' : 'zstdmt --long=30'
|
|
284
|
+
]
|
|
285
|
+
case CompressionMethod.ZstdWithoutLong:
|
|
286
|
+
return BSD_TAR_ZSTD
|
|
287
|
+
? [
|
|
288
|
+
'zstd -T0 --force -o',
|
|
289
|
+
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
|
290
|
+
TarFilename
|
|
291
|
+
]
|
|
292
|
+
: ['--use-compress-program', IS_WINDOWS ? '"zstd -T0"' : 'zstdmt']
|
|
293
|
+
default:
|
|
294
|
+
return ['-z']
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Executes all commands as separate processes
|
|
300
|
+
*
|
|
301
|
+
* @param commands List of commands to execute
|
|
302
|
+
* @param cwd Optional current working directory for the commands
|
|
303
|
+
*/
|
|
304
|
+
/* istanbul ignore next */
|
|
305
|
+
async function execCommands(commands: string[], cwd?: string): Promise<void> {
|
|
306
|
+
for (const command of commands) {
|
|
307
|
+
try {
|
|
308
|
+
await exec(command, undefined, {
|
|
309
|
+
cwd,
|
|
310
|
+
env: { ...(process.env as object), MSYS: 'winsymlinks:nativestrict' }
|
|
311
|
+
})
|
|
312
|
+
} catch (error: any) {
|
|
313
|
+
throw new Error(
|
|
314
|
+
`${command.split(' ')[0]} failed with error: ${error?.message}`,
|
|
315
|
+
{ cause: error }
|
|
316
|
+
)
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* List the contents of a tar
|
|
323
|
+
*
|
|
324
|
+
* @param archivePath Path to the archive to list
|
|
325
|
+
* @param compressionMethod Compression method to use
|
|
326
|
+
*/
|
|
327
|
+
/* istanbul ignore next */
|
|
328
|
+
export async function listTar(
|
|
329
|
+
archivePath: string,
|
|
330
|
+
compressionMethod: CompressionMethod
|
|
331
|
+
): Promise<void> {
|
|
332
|
+
const commands = await getCommands(compressionMethod, 'list', archivePath)
|
|
333
|
+
await execCommands(commands)
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Extracts a TAR
|
|
338
|
+
*
|
|
339
|
+
* @param archivePath Path to the archive to extract
|
|
340
|
+
* @param compressionMethod Compression method to use
|
|
341
|
+
*/
|
|
342
|
+
/* istanbul ignore next */
|
|
343
|
+
export async function extractTar(
|
|
344
|
+
archivePath: string,
|
|
345
|
+
compressionMethod: CompressionMethod
|
|
346
|
+
): Promise<void> {
|
|
347
|
+
// Create directory to extract tar into
|
|
348
|
+
const workingDirectory = getWorkingDirectory()
|
|
349
|
+
await io.mkdirP(workingDirectory)
|
|
350
|
+
const commands = await getCommands(compressionMethod, 'extract', archivePath)
|
|
351
|
+
await execCommands(commands)
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Creates a TAR archive from a list of directories
|
|
356
|
+
*
|
|
357
|
+
* @param archiveFolder The folder where the archive will be created
|
|
358
|
+
* @param sourceDirectories List of directories to include in the archive
|
|
359
|
+
* @param compressionMethod Compression method to use
|
|
360
|
+
*/
|
|
361
|
+
/* istanbul ignore next */
|
|
362
|
+
export async function createTar(
|
|
363
|
+
archiveFolder: string,
|
|
364
|
+
sourceDirectories: string[],
|
|
365
|
+
compressionMethod: CompressionMethod
|
|
366
|
+
): Promise<void> {
|
|
367
|
+
// Write source directories to manifest.txt to avoid command length limits
|
|
368
|
+
writeFileSync(
|
|
369
|
+
path.join(process.env.LOCAL_ACTION_WORKSPACE!, ManifestFilename),
|
|
370
|
+
sourceDirectories.join('\n')
|
|
371
|
+
)
|
|
372
|
+
const commands = await getCommands(compressionMethod, 'create', archiveFolder)
|
|
373
|
+
await execCommands(commands, archiveFolder)
|
|
374
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Last Reviewed Commit: 792ec716de29f031413f3e4f810142cd223f1773
|
|
3
|
+
* Last Reviewed Date: 2026-01-16
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
*
|
|
7
|
+
* - Removed getUploadOptions function
|
|
8
|
+
* - Removed getDownloadOptions function
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Options to control cache upload
|
|
13
|
+
*/
|
|
14
|
+
export interface UploadOptions {
|
|
15
|
+
/**
|
|
16
|
+
* Indicates whether to use the Azure Blob SDK to download caches
|
|
17
|
+
* that are stored on Azure Blob Storage to improve reliability and
|
|
18
|
+
* performance
|
|
19
|
+
*
|
|
20
|
+
* @default false
|
|
21
|
+
*/
|
|
22
|
+
useAzureSdk?: boolean
|
|
23
|
+
/**
|
|
24
|
+
* Number of parallel cache upload
|
|
25
|
+
*
|
|
26
|
+
* @default 4
|
|
27
|
+
*/
|
|
28
|
+
uploadConcurrency?: number
|
|
29
|
+
/**
|
|
30
|
+
* Maximum chunk size in bytes for cache upload
|
|
31
|
+
*
|
|
32
|
+
* @default 32MB
|
|
33
|
+
*/
|
|
34
|
+
uploadChunkSize?: number
|
|
35
|
+
/**
|
|
36
|
+
* Archive size in bytes
|
|
37
|
+
*/
|
|
38
|
+
archiveSizeBytes?: number
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Options to control cache download
|
|
43
|
+
*/
|
|
44
|
+
export interface DownloadOptions {
|
|
45
|
+
/**
|
|
46
|
+
* Indicates whether to use the Azure Blob SDK to download caches
|
|
47
|
+
* that are stored on Azure Blob Storage to improve reliability and
|
|
48
|
+
* performance
|
|
49
|
+
*
|
|
50
|
+
* @default true
|
|
51
|
+
*/
|
|
52
|
+
useAzureSdk?: boolean
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Number of parallel downloads (this option only applies when using
|
|
56
|
+
* the Azure SDK)
|
|
57
|
+
*
|
|
58
|
+
* @default 8
|
|
59
|
+
*/
|
|
60
|
+
downloadConcurrency?: number
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Indicates whether to use Actions HttpClient with concurrency
|
|
64
|
+
* for Azure Blob Storage
|
|
65
|
+
*/
|
|
66
|
+
concurrentBlobDownloads?: boolean
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Maximum time for each download request, in milliseconds (this
|
|
70
|
+
* option only applies when using the Azure SDK)
|
|
71
|
+
*
|
|
72
|
+
* @default 30000
|
|
73
|
+
*/
|
|
74
|
+
timeoutInMs?: number
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Time after which a segment download should be aborted if stuck
|
|
78
|
+
*
|
|
79
|
+
* @default 3600000
|
|
80
|
+
*/
|
|
81
|
+
segmentTimeoutInMs?: number
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Weather to skip downloading the cache entry.
|
|
85
|
+
* If lookupOnly is set to true, the restore function will only check if
|
|
86
|
+
* a matching cache entry exists and return the cache key if it does.
|
|
87
|
+
*
|
|
88
|
+
* @default false
|
|
89
|
+
*/
|
|
90
|
+
lookupOnly?: boolean
|
|
91
|
+
}
|