@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.
Files changed (223) hide show
  1. package/.checkov.yml +3 -0
  2. package/.env.example +379 -0
  3. package/.github/codeql/codeql-config.yml +7 -0
  4. package/.github/copilot-instructions.md +79 -0
  5. package/.github/dependabot.yml +32 -0
  6. package/.github/workflows/codeql-analysis.yml +53 -0
  7. package/.github/workflows/continuous-delivery.yml +93 -0
  8. package/.github/workflows/continuous-integration.yml +382 -0
  9. package/.github/workflows/linter.yml +47 -0
  10. package/.github/workflows/release.yaml +100 -0
  11. package/.github/workflows/version-check.yml +44 -0
  12. package/.grype.yml +151 -0
  13. package/.markdown-lint.yml +7 -0
  14. package/.mega-linter.yml +188 -0
  15. package/.node-version +1 -0
  16. package/.prettierignore +4 -0
  17. package/.prettierrc.yml +14 -0
  18. package/.vscode/launch.json +15 -0
  19. package/.vscode/mcp.json +9 -0
  20. package/.vscode/settings.json +15 -0
  21. package/.vscode/tasks.json +51 -0
  22. package/.yaml-lint.yml +10 -0
  23. package/CHANGELOG.md +75 -0
  24. package/CODEOWNERS +3 -0
  25. package/CODE_OF_CONDUCT.md +74 -0
  26. package/CONTRIBUTING.md +140 -0
  27. package/LICENSE +21 -0
  28. package/README.md +277 -2
  29. package/SECURITY.md +42 -0
  30. package/SUPPORT.md +19 -0
  31. package/__fixtures__/@actions/core.ts +14 -0
  32. package/__fixtures__/@actions/exec.ts +9 -0
  33. package/__fixtures__/@actions/github.ts +3 -0
  34. package/__fixtures__/@actions/http-client.ts +9 -0
  35. package/__fixtures__/@actions/io.ts +9 -0
  36. package/__fixtures__/@octokit/rest.ts +18 -0
  37. package/__fixtures__/crypto.ts +7 -0
  38. package/__fixtures__/fs.ts +27 -0
  39. package/__fixtures__/javascript/no-export/.env.fixture +2 -0
  40. package/__fixtures__/javascript/no-export/action.yml +16 -0
  41. package/__fixtures__/javascript/no-export/node_modules/.gitkeep +0 -0
  42. package/__fixtures__/javascript/no-export/package.json +12 -0
  43. package/__fixtures__/javascript/no-export/src/index.js +0 -0
  44. package/__fixtures__/javascript/no-export/src/main.js +0 -0
  45. package/__fixtures__/javascript/no-import/.env.fixture +2 -0
  46. package/__fixtures__/javascript/no-import/action.yml +16 -0
  47. package/__fixtures__/javascript/no-import/node_modules/.gitkeep +0 -0
  48. package/__fixtures__/javascript/no-import/package.json +12 -0
  49. package/__fixtures__/javascript/no-import/src/index.js +3 -0
  50. package/__fixtures__/javascript/no-import/src/main.js +7 -0
  51. package/__fixtures__/javascript/success/.env.fixture +2 -0
  52. package/__fixtures__/javascript/success/action.yml +16 -0
  53. package/__fixtures__/javascript/success/node_modules/.gitkeep +0 -0
  54. package/__fixtures__/javascript/success/package.json +12 -0
  55. package/__fixtures__/javascript/success/post/index.js +3 -0
  56. package/__fixtures__/javascript/success/post/main.js +13 -0
  57. package/__fixtures__/javascript/success/pre/index.js +3 -0
  58. package/__fixtures__/javascript/success/pre/main.js +13 -0
  59. package/__fixtures__/javascript/success/src/index.js +3 -0
  60. package/__fixtures__/javascript/success/src/main.js +13 -0
  61. package/__fixtures__/javascript-esm/no-import/.env.fixture +2 -0
  62. package/__fixtures__/javascript-esm/no-import/action.yml +16 -0
  63. package/__fixtures__/javascript-esm/no-import/node_modules/.gitkeep +0 -0
  64. package/__fixtures__/javascript-esm/no-import/package.json +13 -0
  65. package/__fixtures__/javascript-esm/no-import/src/index.js +3 -0
  66. package/__fixtures__/javascript-esm/no-import/src/main.js +7 -0
  67. package/__fixtures__/javascript-esm/success/.env.fixture +2 -0
  68. package/__fixtures__/javascript-esm/success/action.yml +16 -0
  69. package/__fixtures__/javascript-esm/success/node_modules/.gitkeep +0 -0
  70. package/__fixtures__/javascript-esm/success/package.json +13 -0
  71. package/__fixtures__/javascript-esm/success/post/index.js +3 -0
  72. package/__fixtures__/javascript-esm/success/post/main.js +13 -0
  73. package/__fixtures__/javascript-esm/success/pre/index.js +3 -0
  74. package/__fixtures__/javascript-esm/success/pre/main.js +13 -0
  75. package/__fixtures__/javascript-esm/success/src/index.js +3 -0
  76. package/__fixtures__/javascript-esm/success/src/main.js +13 -0
  77. package/__fixtures__/path.ts +7 -0
  78. package/__fixtures__/payloads/issue_opened.json +33 -0
  79. package/__fixtures__/stream/promises.ts +3 -0
  80. package/__fixtures__/tsconfig-paths.ts +4 -0
  81. package/__fixtures__/typescript/no-import/.env.fixture +2 -0
  82. package/__fixtures__/typescript/no-import/action.yml +16 -0
  83. package/__fixtures__/typescript/no-import/node_modules/.gitkeep +0 -0
  84. package/__fixtures__/typescript/no-import/package.json +15 -0
  85. package/__fixtures__/typescript/no-import/src/index.ts +3 -0
  86. package/__fixtures__/typescript/no-import/src/main.ts +3 -0
  87. package/__fixtures__/typescript/no-import/tsconfig.json +20 -0
  88. package/__fixtures__/typescript/success/.env.fixture +2 -0
  89. package/__fixtures__/typescript/success/action.yml +16 -0
  90. package/__fixtures__/typescript/success/node_modules/.gitkeep +0 -0
  91. package/__fixtures__/typescript/success/package.json +15 -0
  92. package/__fixtures__/typescript/success/post/index.ts +3 -0
  93. package/__fixtures__/typescript/success/post/main.ts +9 -0
  94. package/__fixtures__/typescript/success/pre/index.ts +3 -0
  95. package/__fixtures__/typescript/success/pre/main.ts +9 -0
  96. package/__fixtures__/typescript/success/src/index.ts +3 -0
  97. package/__fixtures__/typescript/success/src/main.ts +9 -0
  98. package/__fixtures__/typescript/success/tsconfig.json +20 -0
  99. package/__fixtures__/typescript/success-yaml/.env.fixture +2 -0
  100. package/__fixtures__/typescript/success-yaml/action.yaml +16 -0
  101. package/__fixtures__/typescript/success-yaml/node_modules/.gitkeep +0 -0
  102. package/__fixtures__/typescript/success-yaml/package.json +15 -0
  103. package/__fixtures__/typescript/success-yaml/post/index.ts +3 -0
  104. package/__fixtures__/typescript/success-yaml/post/main.ts +9 -0
  105. package/__fixtures__/typescript/success-yaml/pre/index.ts +3 -0
  106. package/__fixtures__/typescript/success-yaml/pre/main.ts +9 -0
  107. package/__fixtures__/typescript/success-yaml/src/index.ts +3 -0
  108. package/__fixtures__/typescript/success-yaml/src/main.ts +9 -0
  109. package/__fixtures__/typescript/success-yaml/tsconfig.json +20 -0
  110. package/__fixtures__/typescript-esm/no-export/.env.fixture +2 -0
  111. package/__fixtures__/typescript-esm/no-export/action.yml +17 -0
  112. package/__fixtures__/typescript-esm/no-export/node_modules/.gitkeep +0 -0
  113. package/__fixtures__/typescript-esm/no-export/package.json +17 -0
  114. package/__fixtures__/typescript-esm/no-export/src/index.ts +0 -0
  115. package/__fixtures__/typescript-esm/no-export/src/main.ts +0 -0
  116. package/__fixtures__/typescript-esm/no-export/tsconfig.json +25 -0
  117. package/__fixtures__/typescript-esm/no-import/.env.fixture +2 -0
  118. package/__fixtures__/typescript-esm/no-import/action.yml +17 -0
  119. package/__fixtures__/typescript-esm/no-import/node_modules/.gitkeep +0 -0
  120. package/__fixtures__/typescript-esm/no-import/package.json +17 -0
  121. package/__fixtures__/typescript-esm/no-import/src/index.ts +3 -0
  122. package/__fixtures__/typescript-esm/no-import/src/main.ts +3 -0
  123. package/__fixtures__/typescript-esm/no-import/tsconfig.json +25 -0
  124. package/__fixtures__/typescript-esm/success/.env.fixture +2 -0
  125. package/__fixtures__/typescript-esm/success/action.yml +17 -0
  126. package/__fixtures__/typescript-esm/success/node_modules/.gitkeep +0 -0
  127. package/__fixtures__/typescript-esm/success/package.json +17 -0
  128. package/__fixtures__/typescript-esm/success/post/index.ts +3 -0
  129. package/__fixtures__/typescript-esm/success/post/main.ts +9 -0
  130. package/__fixtures__/typescript-esm/success/pre/index.ts +3 -0
  131. package/__fixtures__/typescript-esm/success/pre/main.ts +9 -0
  132. package/__fixtures__/typescript-esm/success/src/index.ts +3 -0
  133. package/__fixtures__/typescript-esm/success/src/main.ts +9 -0
  134. package/__fixtures__/typescript-esm/success/tsconfig.json +25 -0
  135. package/__fixtures__/typescript-esm/tsconfig-comments/.env.fixture +2 -0
  136. package/__fixtures__/typescript-esm/tsconfig-comments/action.yml +17 -0
  137. package/__fixtures__/typescript-esm/tsconfig-comments/node_modules/.gitkeep +0 -0
  138. package/__fixtures__/typescript-esm/tsconfig-comments/package.json +17 -0
  139. package/__fixtures__/typescript-esm/tsconfig-comments/src/index.ts +3 -0
  140. package/__fixtures__/typescript-esm/tsconfig-comments/src/main.ts +9 -0
  141. package/__fixtures__/typescript-esm/tsconfig-comments/tsconfig.json +21 -0
  142. package/__tests__/command.test.ts +224 -0
  143. package/__tests__/stubs/artifact/internal/client.test.ts +340 -0
  144. package/__tests__/stubs/artifact/internal/delete/delete-artifact.test.ts +152 -0
  145. package/__tests__/stubs/artifact/internal/download/download-artifact.test.ts +119 -0
  146. package/__tests__/stubs/artifact/internal/find/get-artifact.test.ts +237 -0
  147. package/__tests__/stubs/artifact/internal/find/list-artifacts.test.ts +218 -0
  148. package/__tests__/stubs/artifact/internal/find/retry-options.test.ts +54 -0
  149. package/__tests__/stubs/artifact/internal/shared/config.test.ts +91 -0
  150. package/__tests__/stubs/artifact/internal/shared/errors.test.ts +38 -0
  151. package/__tests__/stubs/artifact/internal/shared/user-agent.test.ts +22 -0
  152. package/__tests__/stubs/artifact/internal/upload/path-and-artifact-name-validation.test.ts +53 -0
  153. package/__tests__/stubs/artifact/internal/upload/upload-artifact.test.ts +126 -0
  154. package/__tests__/stubs/artifact/internal/upload/upload-zip-specification.test.ts +49 -0
  155. package/__tests__/stubs/cache/cache.test.ts +357 -0
  156. package/__tests__/stubs/cache/errors.test.ts +55 -0
  157. package/__tests__/stubs/cache/internal/cacheUtils.test.ts +109 -0
  158. package/__tests__/stubs/cache/internal/constants.test.ts +81 -0
  159. package/__tests__/stubs/cache/internal/tar.test.ts +129 -0
  160. package/__tests__/stubs/core/core.test.ts +760 -0
  161. package/__tests__/stubs/core/path-utils.test.ts +45 -0
  162. package/__tests__/stubs/core/platform.test.ts +89 -0
  163. package/__tests__/stubs/core/summary.test.ts +455 -0
  164. package/__tests__/stubs/env.test.ts +72 -0
  165. package/__tests__/stubs/github/context.test.ts +73 -0
  166. package/__tests__/stubs/github/github.test.ts +15 -0
  167. package/__tests__/stubs/github/internal/utils.test.ts +98 -0
  168. package/__tests__/stubs/github/utils.test.ts +16 -0
  169. package/__tests__/utils/config.test.ts +78 -0
  170. package/__tests__/utils/output.test.ts +32 -0
  171. package/__tests__/utils/package.test.ts +33 -0
  172. package/badges/coverage.svg +1 -0
  173. package/bin/local-action.js +121 -0
  174. package/docs/create-a-job-summary.md +32 -0
  175. package/docs/debugging-in-vscode.md +27 -0
  176. package/docs/img/job-summary.png +0 -0
  177. package/docs/supported-functionality.md +126 -0
  178. package/eslint.config.mjs +74 -0
  179. package/jest.config.ts +41 -0
  180. package/package.json +93 -4
  181. package/src/command.ts +171 -0
  182. package/src/commands/run.ts +616 -0
  183. package/src/index.ts +21 -0
  184. package/src/stubs/artifact/artifact.ts +17 -0
  185. package/src/stubs/artifact/internal/client.ts +400 -0
  186. package/src/stubs/artifact/internal/delete/delete-artifact.ts +126 -0
  187. package/src/stubs/artifact/internal/download/download-artifact.ts +309 -0
  188. package/src/stubs/artifact/internal/find/get-artifact.ts +135 -0
  189. package/src/stubs/artifact/internal/find/list-artifacts.ts +188 -0
  190. package/src/stubs/artifact/internal/find/retry-options.ts +57 -0
  191. package/src/stubs/artifact/internal/shared/config.ts +64 -0
  192. package/src/stubs/artifact/internal/shared/errors.ts +53 -0
  193. package/src/stubs/artifact/internal/shared/interfaces.ts +195 -0
  194. package/src/stubs/artifact/internal/shared/user-agent.ts +13 -0
  195. package/src/stubs/artifact/internal/upload/path-and-artifact-name-validation.ts +92 -0
  196. package/src/stubs/artifact/internal/upload/upload-artifact.ts +127 -0
  197. package/src/stubs/artifact/internal/upload/upload-zip-specification.ts +108 -0
  198. package/src/stubs/artifact/internal/upload/zip.ts +122 -0
  199. package/src/stubs/cache/cache.ts +334 -0
  200. package/src/stubs/cache/errors.ts +31 -0
  201. package/src/stubs/cache/interfaces.ts +4 -0
  202. package/src/stubs/cache/internal/cacheUtils.ts +207 -0
  203. package/src/stubs/cache/internal/constants.ts +45 -0
  204. package/src/stubs/cache/internal/tar.ts +374 -0
  205. package/src/stubs/cache/options.ts +91 -0
  206. package/src/stubs/core/core.ts +743 -0
  207. package/src/stubs/core/path-utils.ts +39 -0
  208. package/src/stubs/core/platform.ts +132 -0
  209. package/src/stubs/core/summary.ts +399 -0
  210. package/src/stubs/env.ts +40 -0
  211. package/src/stubs/github/context.ts +94 -0
  212. package/src/stubs/github/github.ts +29 -0
  213. package/src/stubs/github/interfaces.ts +52 -0
  214. package/src/stubs/github/internal/utils.ts +83 -0
  215. package/src/stubs/github/utils.ts +52 -0
  216. package/src/types/quibble.d.ts +5 -0
  217. package/src/types.ts +116 -0
  218. package/src/utils/config.ts +47 -0
  219. package/src/utils/output.ts +20 -0
  220. package/src/utils/package.ts +38 -0
  221. package/tsconfig.base.json +29 -0
  222. package/tsconfig.eslint.json +22 -0
  223. package/tsconfig.json +18 -0
@@ -0,0 +1,109 @@
1
+ import { jest } from '@jest/globals'
2
+ import * as io from '../../../../__fixtures__/@actions/io.js'
3
+ import * as fs from '../../../../__fixtures__/fs.js'
4
+
5
+ jest.unstable_mockModule('@actions/io', () => io)
6
+ jest.unstable_mockModule('fs', () => fs)
7
+
8
+ // Import after mocking
9
+ const {
10
+ getCacheFileName,
11
+ getCacheVersion,
12
+ createTempDirectory,
13
+ getArchiveFileSizeInBytes
14
+ } = await import('../../../../src/stubs/cache/internal/cacheUtils.js')
15
+ const { CacheFilename, CompressionMethod } =
16
+ await import('../../../../src/stubs/cache/internal/constants.js')
17
+
18
+ describe('cache/internal/cacheUtils', () => {
19
+ beforeEach(() => {
20
+ jest.clearAllMocks()
21
+
22
+ process.env.LOCAL_ACTION_WORKSPACE = '/tmp/workspace'
23
+
24
+ io.mkdirP.mockResolvedValue(undefined as never)
25
+ fs.statSync.mockReturnValue({ size: 1024 })
26
+ })
27
+
28
+ describe('getCacheFileName', () => {
29
+ it('Returns gzip filename for gzip compression', () => {
30
+ const result = getCacheFileName(CompressionMethod.Gzip)
31
+
32
+ expect(result).toBe(CacheFilename.Gzip)
33
+ })
34
+
35
+ it('Returns zstd filename for zstd compression', () => {
36
+ const result = getCacheFileName(CompressionMethod.Zstd)
37
+
38
+ expect(result).toBe(CacheFilename.Zstd)
39
+ })
40
+
41
+ it('Returns zstd filename for zstd without long compression', () => {
42
+ const result = getCacheFileName(CompressionMethod.ZstdWithoutLong)
43
+
44
+ expect(result).toBe(CacheFilename.Zstd)
45
+ })
46
+ })
47
+
48
+ describe('getCacheVersion', () => {
49
+ it('Generates cache version hash from paths', () => {
50
+ const paths = ['src/', 'dist/']
51
+
52
+ const result = getCacheVersion(paths)
53
+
54
+ // Should be a 64-character hex string (SHA-256)
55
+ expect(result).toMatch(/^[a-f0-9]{64}$/)
56
+ })
57
+
58
+ it('Includes compression method in cache version', () => {
59
+ const paths = ['src/']
60
+
61
+ const resultGzip = getCacheVersion(paths, CompressionMethod.Gzip)
62
+ const resultZstd = getCacheVersion(paths, CompressionMethod.Zstd)
63
+
64
+ expect(resultGzip).not.toBe(resultZstd)
65
+ })
66
+
67
+ it('Does not modify original paths array', () => {
68
+ const paths = ['src/', 'dist/']
69
+ const originalPaths = [...paths]
70
+
71
+ getCacheVersion(paths)
72
+
73
+ expect(paths).toEqual(originalPaths)
74
+ })
75
+ })
76
+
77
+ describe('createTempDirectory', () => {
78
+ beforeEach(() => {
79
+ process.env.LOCAL_ACTION_WORKSPACE = '/tmp/workspace'
80
+ })
81
+
82
+ it('Creates a temporary directory', async () => {
83
+ const tempDir = await createTempDirectory()
84
+
85
+ expect(tempDir).toMatch(
86
+ /^\/tmp\/workspace\/actions\/temp\/[a-f0-9-]{36}$/
87
+ )
88
+ })
89
+
90
+ it('Creates unique directories on multiple calls', async () => {
91
+ const tempDir1 = await createTempDirectory()
92
+ const tempDir2 = await createTempDirectory()
93
+
94
+ expect(tempDir1).not.toBe(tempDir2)
95
+ })
96
+ })
97
+
98
+ describe('getArchiveFileSizeInBytes', () => {
99
+ it('Returns the size of an archive file', () => {
100
+ const filePath = '/path/to/archive.tar.gz'
101
+ fs.statSync.mockReturnValue({ size: 2048 })
102
+
103
+ const size = getArchiveFileSizeInBytes(filePath)
104
+
105
+ expect(fs.statSync).toHaveBeenCalledWith(filePath)
106
+ expect(size).toBe(2048)
107
+ })
108
+ })
109
+ })
@@ -0,0 +1,81 @@
1
+ import {
2
+ ArchiveToolType,
3
+ CacheFilename,
4
+ CacheFileSizeLimit,
5
+ CompressionMethod,
6
+ DefaultRetryAttempts,
7
+ DefaultRetryDelay,
8
+ GnuTarPathOnWindows,
9
+ ManifestFilename,
10
+ SocketTimeout,
11
+ SystemTarPathOnWindows,
12
+ TarFilename
13
+ } from '../../../../src/stubs/cache/internal/constants.js'
14
+
15
+ describe('cache/internal/constants', () => {
16
+ describe('CacheFilename', () => {
17
+ it('Has the correct values', () => {
18
+ expect(CacheFilename.Gzip).toBe('cache.tgz')
19
+ expect(CacheFilename.Zstd).toBe('cache.tzst')
20
+ })
21
+ })
22
+
23
+ describe('CompressionMethod', () => {
24
+ it('Has the correct values', () => {
25
+ expect(CompressionMethod.Gzip).toBe('gzip')
26
+ expect(CompressionMethod.ZstdWithoutLong).toBe('zstd-without-long')
27
+ expect(CompressionMethod.Zstd).toBe('zstd')
28
+ })
29
+ })
30
+
31
+ describe('ArchiveToolType', () => {
32
+ it('Has the correct values', () => {
33
+ expect(ArchiveToolType.GNU).toBe('gnu')
34
+ expect(ArchiveToolType.BSD).toBe('bsd')
35
+ })
36
+ })
37
+
38
+ describe('Default values', () => {
39
+ it('Has the correct default retry attempts', () => {
40
+ expect(DefaultRetryAttempts).toBe(2)
41
+ })
42
+
43
+ it('Has the correct default retry delay', () => {
44
+ expect(DefaultRetryDelay).toBe(5000)
45
+ })
46
+
47
+ it('Has the correct socket timeout', () => {
48
+ expect(SocketTimeout).toBe(5000)
49
+ })
50
+ })
51
+
52
+ describe('Windows tar paths', () => {
53
+ it('Has the correct GNU tar path', () => {
54
+ expect(GnuTarPathOnWindows).toBe(
55
+ `${process.env['PROGRAMFILES']}\\Git\\usr\\bin\\tar.exe`
56
+ )
57
+ })
58
+
59
+ it('Has the correct system tar path', () => {
60
+ expect(SystemTarPathOnWindows).toBe(
61
+ `${process.env['SYSTEMDRIVE']}\\Windows\\System32\\tar.exe`
62
+ )
63
+ })
64
+ })
65
+
66
+ describe('File names', () => {
67
+ it('Has the correct tar filename', () => {
68
+ expect(TarFilename).toBe('cache.tar')
69
+ })
70
+
71
+ it('Has the correct manifest filename', () => {
72
+ expect(ManifestFilename).toBe('manifest.txt')
73
+ })
74
+ })
75
+
76
+ describe('Cache file size limit', () => {
77
+ it('Has the correct size limit (10GiB)', () => {
78
+ expect(CacheFileSizeLimit).toBe(10 * Math.pow(1024, 3))
79
+ })
80
+ })
81
+ })
@@ -0,0 +1,129 @@
1
+ import { jest } from '@jest/globals'
2
+ import * as exec from '../../../../__fixtures__/@actions/exec.js'
3
+ import * as io from '../../../../__fixtures__/@actions/io.js'
4
+ import * as fs from '../../../../__fixtures__/fs.js'
5
+
6
+ // Mock dependencies first
7
+ const mockGetGnuTarPathOnWindows = jest.fn() as jest.MockedFunction<any>
8
+
9
+ jest.unstable_mockModule('@actions/exec', () => exec)
10
+ jest.unstable_mockModule('@actions/io', () => io)
11
+ jest.unstable_mockModule('fs', () => fs)
12
+
13
+ jest.unstable_mockModule(
14
+ '../../../../src/stubs/cache/internal/cacheUtils.js',
15
+ () => ({
16
+ getGnuTarPathOnWindows: mockGetGnuTarPathOnWindows,
17
+ getCacheFileName: jest.fn().mockReturnValue('cache.tgz')
18
+ })
19
+ )
20
+
21
+ // Import after mocking
22
+ const { CompressionMethod } =
23
+ await import('../../../../src/stubs/cache/internal/constants.js')
24
+ const { createTar, extractTar, listTar } =
25
+ await import('../../../../src/stubs/cache/internal/tar.js')
26
+
27
+ describe('cache/internal/tar', () => {
28
+ beforeEach(() => {
29
+ jest.clearAllMocks()
30
+ process.env.LOCAL_ACTION_WORKSPACE = '/tmp/workspace'
31
+
32
+ // Default mock values
33
+ exec.exec.mockResolvedValue(0 as never)
34
+ fs.existsSync.mockReturnValue(true)
35
+ io.which.mockResolvedValue('/usr/bin/tar' as never)
36
+ mockGetGnuTarPathOnWindows.mockResolvedValue('/usr/bin/tar')
37
+ fs.writeFileSync.mockImplementation(() => {})
38
+ })
39
+
40
+ describe('listTar', () => {
41
+ it('Lists tar contents with gzip compression', async () => {
42
+ await listTar('/path/to/archive.tar.gz', CompressionMethod.Gzip)
43
+
44
+ expect(exec.exec).toHaveBeenCalledWith(
45
+ expect.stringContaining('tar'),
46
+ undefined,
47
+ expect.objectContaining({
48
+ env: expect.any(Object)
49
+ })
50
+ )
51
+ })
52
+ })
53
+
54
+ describe('extractTar', () => {
55
+ it('Extracts tar with gzip compression', async () => {
56
+ await extractTar('/path/to/archive.tar.gz', CompressionMethod.Gzip)
57
+
58
+ expect(exec.exec).toHaveBeenCalledWith(
59
+ expect.stringContaining('tar'),
60
+ undefined,
61
+ expect.objectContaining({
62
+ env: expect.any(Object)
63
+ })
64
+ )
65
+ })
66
+ })
67
+
68
+ describe('createTar', () => {
69
+ it('Creates tar with gzip compression', async () => {
70
+ const sourceDirectories = ['src/', 'dist/']
71
+ await createTar(
72
+ '/path/to/archive.tar.gz',
73
+ sourceDirectories,
74
+ CompressionMethod.Gzip
75
+ )
76
+
77
+ expect(fs.writeFileSync).toHaveBeenCalled()
78
+ expect(exec.exec).toHaveBeenCalledWith(
79
+ expect.stringContaining('tar'),
80
+ undefined,
81
+ expect.objectContaining({
82
+ cwd: expect.any(String),
83
+ env: expect.any(Object)
84
+ })
85
+ )
86
+ })
87
+
88
+ it('Creates tar with platform-specific args on macOS', async () => {
89
+ // Mock the process.platform to be darwin to test the platform-specific code path
90
+ const originalPlatform = Object.getOwnPropertyDescriptor(
91
+ process,
92
+ 'platform'
93
+ )
94
+ Object.defineProperty(process, 'platform', {
95
+ value: 'darwin',
96
+ configurable: true
97
+ })
98
+
99
+ // Mock gtar being available to trigger GNU tar type
100
+ // The first call to which('gtar', false) should return the gtar path
101
+ // The subsequent calls to which('tar', true) can return regular tar
102
+ io.which.mockImplementation(((cmd: string) => {
103
+ if (cmd === 'gtar') {
104
+ return Promise.resolve('/usr/local/bin/gtar')
105
+ }
106
+ return Promise.resolve('/usr/bin/tar')
107
+ }) as never)
108
+
109
+ const sourceDirectories = ['src/']
110
+ await createTar(
111
+ '/path/to/archive.tar.gz',
112
+ sourceDirectories,
113
+ CompressionMethod.Gzip
114
+ )
115
+
116
+ expect(exec.exec).toHaveBeenCalledWith(
117
+ expect.stringContaining('--delay-directory-restore'),
118
+ undefined,
119
+ expect.objectContaining({
120
+ env: expect.any(Object)
121
+ })
122
+ )
123
+
124
+ // Restore original platform
125
+ if (originalPlatform)
126
+ Object.defineProperty(process, 'platform', originalPlatform)
127
+ })
128
+ })
129
+ })