@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,237 @@
1
+ import { jest } from '@jest/globals'
2
+ import * as core from '../../../../../__fixtures__/@actions/core.js'
3
+ import * as github from '../../../../../__fixtures__/@actions/github.js'
4
+ import * as octokit from '../../../../../__fixtures__/@octokit/rest.js'
5
+ import { ResetCoreMetadata } from '../../../../../src/stubs/core/core.js'
6
+ import { EnvMeta, ResetEnvMetadata } from '../../../../../src/stubs/env.js'
7
+
8
+ jest.unstable_mockModule('@octokit/rest', async () => {
9
+ class Octokit {
10
+ constructor() {
11
+ return octokit
12
+ }
13
+ }
14
+
15
+ return {
16
+ Octokit
17
+ }
18
+ })
19
+
20
+ jest.unstable_mockModule('../../../../../src/stubs/core/core.js', () => core)
21
+ jest.unstable_mockModule(
22
+ '../../../../../src/stubs/github/github.js',
23
+ () => github
24
+ )
25
+
26
+ const getArtifact =
27
+ await import('../../../../../src/stubs/artifact/internal/find/get-artifact.js')
28
+
29
+ const { Octokit } = await import('@octokit/rest')
30
+ const mocktokit = jest.mocked(new Octokit())
31
+
32
+ describe('get-artifact', () => {
33
+ beforeEach(() => {
34
+ // Reset metadata
35
+ ResetEnvMetadata()
36
+ ResetCoreMetadata()
37
+ })
38
+
39
+ afterEach(() => {
40
+ jest.resetAllMocks()
41
+ })
42
+
43
+ describe('getArtifactPublic', () => {
44
+ it('Gets an artifact', async () => {
45
+ mocktokit.request.mockResolvedValue({
46
+ data: {
47
+ artifacts: [
48
+ {
49
+ name: 'artifact-name',
50
+ id: 1,
51
+ size_in_bytes: 0,
52
+ created_at: new Date().toISOString()
53
+ }
54
+ ]
55
+ },
56
+ status: 200,
57
+ headers: {
58
+ 'x-github-request-id': 'request-id'
59
+ }
60
+ } as any)
61
+
62
+ const response = await getArtifact.getArtifactPublic(
63
+ 'artifact-name',
64
+ 1,
65
+ 'owner',
66
+ 'repo',
67
+ 'token'
68
+ )
69
+
70
+ expect(mocktokit.request).toHaveBeenCalledTimes(1)
71
+ expect(response).toMatchObject({
72
+ artifact: {
73
+ name: 'artifact-name',
74
+ id: 1,
75
+ size: 0,
76
+ createdAt: expect.any(Date)
77
+ }
78
+ })
79
+ })
80
+
81
+ it('Throws if there is an API error', async () => {
82
+ mocktokit.request.mockResolvedValue({
83
+ status: 500,
84
+ headers: {
85
+ 'x-github-request-id': 'request-id'
86
+ }
87
+ } as any)
88
+
89
+ await expect(
90
+ getArtifact.getArtifactPublic(
91
+ 'artifact-name',
92
+ 1,
93
+ 'owner',
94
+ 'repo',
95
+ 'token'
96
+ )
97
+ ).rejects.toThrow('Invalid response from GitHub API: 500 (request-id)')
98
+ })
99
+
100
+ it('Throws if no artifacts are found', async () => {
101
+ mocktokit.request.mockResolvedValue({
102
+ data: {
103
+ artifacts: []
104
+ },
105
+ status: 200,
106
+ headers: {
107
+ 'x-github-request-id': 'request-id'
108
+ }
109
+ } as any)
110
+
111
+ await expect(
112
+ getArtifact.getArtifactPublic(
113
+ 'artifact-name',
114
+ 1,
115
+ 'owner',
116
+ 'repo',
117
+ 'token'
118
+ )
119
+ ).rejects.toThrow()
120
+ })
121
+
122
+ it('Chooses the latest artifact if multiple are found', async () => {
123
+ mocktokit.request.mockResolvedValue({
124
+ data: {
125
+ artifacts: [
126
+ {
127
+ name: 'artifact-name',
128
+ id: 1,
129
+ size_in_bytes: 0,
130
+ created_at: new Date().toISOString()
131
+ },
132
+ {
133
+ name: 'artifact-name',
134
+ id: 2,
135
+ size_in_bytes: 0,
136
+ created_at: new Date().toISOString()
137
+ }
138
+ ]
139
+ },
140
+ status: 200,
141
+ headers: {
142
+ 'x-github-request-id': 'request-id'
143
+ }
144
+ } as any)
145
+
146
+ const response = await getArtifact.getArtifactPublic(
147
+ 'artifact-name',
148
+ 1,
149
+ 'owner',
150
+ 'repo',
151
+ 'token'
152
+ )
153
+
154
+ expect(mocktokit.request).toHaveBeenCalledTimes(1)
155
+ expect(response).toMatchObject({
156
+ artifact: {
157
+ name: 'artifact-name',
158
+ id: 2,
159
+ size: 0,
160
+ createdAt: expect.any(Date)
161
+ }
162
+ })
163
+ })
164
+
165
+ it('Returns an undefined date if there is no created_at', async () => {
166
+ mocktokit.request.mockResolvedValue({
167
+ data: {
168
+ artifacts: [
169
+ {
170
+ name: 'artifact-name',
171
+ id: 1,
172
+ size_in_bytes: 0,
173
+ created_at: undefined
174
+ }
175
+ ]
176
+ },
177
+ status: 200,
178
+ headers: {
179
+ 'x-github-request-id': 'request-id'
180
+ }
181
+ } as any)
182
+
183
+ const response = await getArtifact.getArtifactPublic(
184
+ 'artifact-name',
185
+ 1,
186
+ 'owner',
187
+ 'repo',
188
+ 'token'
189
+ )
190
+
191
+ expect(mocktokit.request).toHaveBeenCalledTimes(1)
192
+ expect(response).toMatchObject({
193
+ artifact: {
194
+ name: 'artifact-name',
195
+ id: 1,
196
+ size: 0,
197
+ createdAt: undefined
198
+ }
199
+ })
200
+ })
201
+ })
202
+
203
+ describe('getArtifactInternal', () => {
204
+ it('Gets an artifact', async () => {
205
+ EnvMeta.artifacts = [{ name: 'artifact-name', id: 1, size: 0 }]
206
+
207
+ const response = await getArtifact.getArtifactInternal('artifact-name')
208
+
209
+ expect(response.artifact).toMatchObject({
210
+ name: 'artifact-name',
211
+ id: 1,
212
+ size: 0
213
+ })
214
+ })
215
+
216
+ it('Gets the latest artifact', async () => {
217
+ EnvMeta.artifacts = [
218
+ { name: 'artifact-name', id: 1, size: 0 },
219
+ { name: 'artifact-name', id: 2, size: 0 }
220
+ ]
221
+
222
+ const response = await getArtifact.getArtifactInternal('artifact-name')
223
+
224
+ expect(response.artifact).toMatchObject({
225
+ name: 'artifact-name',
226
+ id: 2,
227
+ size: 0
228
+ })
229
+ })
230
+
231
+ it('Throws if no matching artifact is found', async () => {
232
+ await expect(
233
+ getArtifact.getArtifactInternal('artifact-name')
234
+ ).rejects.toThrow()
235
+ })
236
+ })
237
+ })
@@ -0,0 +1,218 @@
1
+ import { jest } from '@jest/globals'
2
+ import * as core from '../../../../../__fixtures__/@actions/core.js'
3
+ import * as github from '../../../../../__fixtures__/@actions/github.js'
4
+ import * as octokit from '../../../../../__fixtures__/@octokit/rest.js'
5
+ import { ResetCoreMetadata } from '../../../../../src/stubs/core/core.js'
6
+ import { EnvMeta, ResetEnvMetadata } from '../../../../../src/stubs/env.js'
7
+
8
+ jest.unstable_mockModule('@octokit/rest', async () => {
9
+ class Octokit {
10
+ constructor() {
11
+ return octokit
12
+ }
13
+ }
14
+
15
+ return {
16
+ Octokit
17
+ }
18
+ })
19
+
20
+ jest.unstable_mockModule('../../../../../src/stubs/core/core.js', () => core)
21
+ jest.unstable_mockModule(
22
+ '../../../../../src/stubs/github/github.js',
23
+ () => github
24
+ )
25
+
26
+ const listArtifacts =
27
+ await import('../../../../../src/stubs/artifact/internal/find/list-artifacts.js')
28
+
29
+ const { Octokit } = await import('@octokit/rest')
30
+ const mocktokit = jest.mocked(new Octokit())
31
+
32
+ describe('list-artifacts', () => {
33
+ beforeEach(() => {
34
+ // Reset metadata
35
+ ResetEnvMetadata()
36
+ ResetCoreMetadata()
37
+ })
38
+
39
+ afterEach(() => {
40
+ jest.resetAllMocks()
41
+ })
42
+
43
+ describe('listArtifactsPublic', () => {
44
+ it('Lists the artifacts', async () => {
45
+ mocktokit.rest.actions.listWorkflowRunArtifacts.mockResolvedValue({
46
+ data: {
47
+ total_count: 1,
48
+ artifacts: [
49
+ {
50
+ name: 'artifact-name',
51
+ id: 1,
52
+ size_in_bytes: 0,
53
+ created_at: new Date().toISOString()
54
+ }
55
+ ]
56
+ }
57
+ } as any)
58
+
59
+ const response = await listArtifacts.listArtifactsPublic(
60
+ 1,
61
+ 'owner',
62
+ 'repo',
63
+ 'token'
64
+ )
65
+
66
+ expect(
67
+ mocktokit.rest.actions.listWorkflowRunArtifacts
68
+ ).toHaveBeenCalledTimes(1)
69
+ expect(response).toMatchObject({
70
+ artifacts: [
71
+ {
72
+ name: 'artifact-name',
73
+ id: 1,
74
+ size: 0,
75
+ createdAt: expect.any(Date)
76
+ }
77
+ ]
78
+ })
79
+ })
80
+
81
+ it('Sets the date to undefined if created_at is not present', async () => {
82
+ mocktokit.rest.actions.listWorkflowRunArtifacts.mockResolvedValue({
83
+ data: {
84
+ total_count: 1,
85
+ artifacts: [
86
+ {
87
+ name: 'artifact-name',
88
+ id: 1,
89
+ size_in_bytes: 0
90
+ }
91
+ ]
92
+ }
93
+ } as any)
94
+
95
+ const response = await listArtifacts.listArtifactsPublic(
96
+ 1,
97
+ 'owner',
98
+ 'repo',
99
+ 'token'
100
+ )
101
+
102
+ expect(
103
+ mocktokit.rest.actions.listWorkflowRunArtifacts
104
+ ).toHaveBeenCalledTimes(1)
105
+ expect(response).toMatchObject({
106
+ artifacts: [
107
+ {
108
+ name: 'artifact-name',
109
+ id: 1,
110
+ size: 0,
111
+ createdAt: undefined
112
+ }
113
+ ]
114
+ })
115
+ })
116
+
117
+ it('Returns the first 1000 artifacts', async () => {
118
+ mocktokit.rest.actions.listWorkflowRunArtifacts.mockResolvedValue({
119
+ data: {
120
+ total_count: 1001,
121
+ artifacts: [
122
+ {
123
+ name: 'artifact-name',
124
+ id: 1,
125
+ size_in_bytes: 0,
126
+ created_at: new Date().toISOString()
127
+ }
128
+ ]
129
+ }
130
+ } as any)
131
+
132
+ await listArtifacts.listArtifactsPublic(1, 'owner', 'repo', 'token')
133
+
134
+ expect(mocktokit.rest.actions.listWorkflowRunArtifacts).toHaveBeenCalled()
135
+ expect(core.warning).toHaveBeenCalledWith(
136
+ 'Workflow run 1 has more than 1000 artifacts. Results will be incomplete as only the first 1000 artifacts will be returned'
137
+ )
138
+ })
139
+
140
+ it('Filters the latest artifacts', async () => {
141
+ mocktokit.rest.actions.listWorkflowRunArtifacts.mockResolvedValue({
142
+ data: {
143
+ total_count: 3,
144
+ artifacts: [
145
+ {
146
+ name: 'artifact-name',
147
+ id: 1,
148
+ size_in_bytes: 0,
149
+ created_at: new Date().toISOString()
150
+ },
151
+ {
152
+ name: 'artifact-name',
153
+ id: 2,
154
+ size_in_bytes: 0,
155
+ created_at: new Date().toISOString()
156
+ },
157
+ {
158
+ name: 'artifact-name-2',
159
+ id: 3,
160
+ size_in_bytes: 0,
161
+ created_at: new Date().toISOString()
162
+ }
163
+ ]
164
+ }
165
+ } as any)
166
+
167
+ const response = await listArtifacts.listArtifactsPublic(
168
+ 1,
169
+ 'owner',
170
+ 'repo',
171
+ 'token',
172
+ true
173
+ )
174
+
175
+ expect(
176
+ mocktokit.rest.actions.listWorkflowRunArtifacts
177
+ ).toHaveBeenCalledTimes(1)
178
+ expect(response).toMatchObject({
179
+ artifacts: [
180
+ {
181
+ name: 'artifact-name-2',
182
+ id: 3,
183
+ size: 0,
184
+ createdAt: expect.any(Date)
185
+ },
186
+ {
187
+ name: 'artifact-name',
188
+ id: 2,
189
+ size: 0,
190
+ createdAt: expect.any(Date)
191
+ }
192
+ ]
193
+ })
194
+ })
195
+ })
196
+
197
+ describe('listArtifactsInternal', () => {
198
+ it('Lists artifacts', async () => {
199
+ EnvMeta.artifacts = [{ name: 'artifact-name', id: 1, size: 0 }]
200
+
201
+ const response = await listArtifacts.listArtifactsInternal()
202
+
203
+ expect(response.artifacts.length).toBe(1)
204
+ })
205
+
206
+ it('Only returns the latest artifacts', async () => {
207
+ EnvMeta.artifacts = [
208
+ { name: 'artifact-name', id: 1, size: 0 },
209
+ { name: 'artifact-name', id: 2, size: 0 },
210
+ { name: 'artifact-name-2', id: 3, size: 0 }
211
+ ]
212
+
213
+ const response = await listArtifacts.listArtifactsInternal(true)
214
+
215
+ expect(response.artifacts.length).toBe(2)
216
+ })
217
+ })
218
+ })
@@ -0,0 +1,54 @@
1
+ import { jest } from '@jest/globals'
2
+ import * as retry from '../../../../../src/stubs/artifact/internal/find/retry-options.js'
3
+
4
+ describe('retry-options', () => {
5
+ afterEach(() => {
6
+ jest.resetAllMocks()
7
+ })
8
+
9
+ describe('getRetryOptions', () => {
10
+ it('Gets the retry options', async () => {
11
+ const [retryOptions, requestOptions] = retry.getRetryOptions(
12
+ {} as any,
13
+ 5,
14
+ [400, 401, 403, 404, 422]
15
+ )
16
+
17
+ expect(retryOptions).toEqual({
18
+ enabled: true,
19
+ doNotRetry: [400, 401, 403, 404, 422]
20
+ })
21
+ expect(requestOptions).toEqual({
22
+ retries: 5
23
+ })
24
+ })
25
+
26
+ it('Disables retries', async () => {
27
+ const [retryOptions, requestOptions] = retry.getRetryOptions(
28
+ {} as any,
29
+ 0,
30
+ [400, 401, 403, 404, 422]
31
+ )
32
+
33
+ expect(retryOptions).toEqual({
34
+ enabled: false
35
+ })
36
+ expect(requestOptions).toBeUndefined()
37
+ })
38
+
39
+ it('Uses default exempt status codes', async () => {
40
+ const [retryOptions, requestOptions] = retry.getRetryOptions(
41
+ {} as any,
42
+ 5,
43
+ []
44
+ )
45
+
46
+ expect(retryOptions).toEqual({
47
+ enabled: true
48
+ })
49
+ expect(requestOptions).toEqual({
50
+ retries: 5
51
+ })
52
+ })
53
+ })
54
+ })
@@ -0,0 +1,91 @@
1
+ import { jest } from '@jest/globals'
2
+ import * as config from '../../../../../src/stubs/artifact/internal/shared/config.js'
3
+ import { ResetCoreMetadata } from '../../../../../src/stubs/core/core.js'
4
+ import { ResetEnvMetadata } from '../../../../../src/stubs/env.js'
5
+
6
+ describe('config', () => {
7
+ beforeEach(() => {
8
+ // Reset metadata
9
+ ResetEnvMetadata()
10
+ ResetCoreMetadata()
11
+ })
12
+
13
+ afterEach(() => {
14
+ jest.resetAllMocks()
15
+
16
+ delete process.env.GITHUB_WORKSPACE
17
+ delete process.env.GITHUB_SERVER_URL
18
+ })
19
+
20
+ describe('getUploadChunkSize', () => {
21
+ it('Gets the upload chunk size', () => {
22
+ expect(config.getUploadChunkSize()).toEqual(8 * 1024 * 1024) // 8 MB
23
+ })
24
+ })
25
+
26
+ describe('isGhes', () => {
27
+ it('Returns false if using GitHub.com', () => {
28
+ process.env.GITHUB_SERVER_URL = 'https://github.com'
29
+
30
+ expect(config.isGhes()).toBe(false)
31
+ })
32
+
33
+ it('Returns false if using GitHub.com (default value)', () => {
34
+ expect(config.isGhes()).toBe(false)
35
+ })
36
+
37
+ it('Returns false if using GHE.com', () => {
38
+ process.env.GITHUB_SERVER_URL = 'https://example.ghe.com'
39
+
40
+ expect(config.isGhes()).toBe(false)
41
+ })
42
+
43
+ it('Returns false if using localhost', () => {
44
+ process.env.GITHUB_SERVER_URL = 'https://example.localhost'
45
+
46
+ expect(config.isGhes()).toBe(false)
47
+ })
48
+
49
+ it('Returns true if using a custom domain', () => {
50
+ process.env.GITHUB_SERVER_URL = 'https://example.com'
51
+
52
+ expect(config.isGhes()).toBe(true)
53
+ })
54
+ })
55
+
56
+ describe('getGitHubWorkspaceDir', () => {
57
+ it('Gets the workspace directory (default)', () => {
58
+ expect(config.getGitHubWorkspaceDir()).toEqual(process.cwd())
59
+ })
60
+
61
+ it('Gets the workspace directory (env var)', () => {
62
+ process.env.GITHUB_WORKSPACE = '/tmp/workspace'
63
+ expect(config.getGitHubWorkspaceDir()).toEqual('/tmp/workspace')
64
+ })
65
+ })
66
+
67
+ describe('getMaxArtifactListCount', () => {
68
+ it('Gets the default max artifact list count', () => {
69
+ expect(config.getMaxArtifactListCount()).toEqual(1000)
70
+ })
71
+
72
+ it('Gets the max artifact list count (env var)', () => {
73
+ process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = '500'
74
+ expect(config.getMaxArtifactListCount()).toEqual(500)
75
+ })
76
+
77
+ it('Throws if the env var is not a number', () => {
78
+ process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = 'hello'
79
+ expect(() => config.getMaxArtifactListCount()).toThrow(
80
+ 'Invalid value set for ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT env variable'
81
+ )
82
+ })
83
+
84
+ it('Throws if the env var is less than 1', () => {
85
+ process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = '0'
86
+ expect(() => config.getMaxArtifactListCount()).toThrow(
87
+ 'Invalid value set for ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT env variable'
88
+ )
89
+ })
90
+ })
91
+ })
@@ -0,0 +1,38 @@
1
+ import { jest } from '@jest/globals'
2
+ import * as errors from '../../../../../src/stubs/artifact/internal/shared/errors.js'
3
+
4
+ describe('errors', () => {
5
+ afterEach(() => {
6
+ jest.resetAllMocks()
7
+ })
8
+
9
+ describe('FilesNotFoundError', () => {
10
+ it('Returns a default message', () => {
11
+ const error = new errors.FilesNotFoundError()
12
+
13
+ expect(error.message).toEqual('No files were found to upload')
14
+ })
15
+
16
+ it('Returns a list of files', () => {
17
+ const error = new errors.FilesNotFoundError(['file1', 'file2'])
18
+
19
+ expect(error.message).toEqual(
20
+ 'No files were found to upload: file1, file2'
21
+ )
22
+ })
23
+ })
24
+
25
+ describe('ArtifactNotFoundError', () => {
26
+ it('Returns a default message', () => {
27
+ const error = new errors.ArtifactNotFoundError()
28
+
29
+ expect(error.message).toEqual('Artifact not found')
30
+ })
31
+
32
+ it('Returns a custom message', () => {
33
+ const error = new errors.ArtifactNotFoundError('Custom message')
34
+
35
+ expect(error.message).toEqual('Custom message')
36
+ })
37
+ })
38
+ })
@@ -0,0 +1,22 @@
1
+ import { jest } from '@jest/globals'
2
+ import { getUserAgentString } from '../../../../../src/stubs/artifact/internal/shared/user-agent.js'
3
+ import { ResetCoreMetadata } from '../../../../../src/stubs/core/core.js'
4
+ import { ResetEnvMetadata } from '../../../../../src/stubs/env.js'
5
+
6
+ describe('user-agent', () => {
7
+ beforeEach(() => {
8
+ // Reset metadata
9
+ ResetEnvMetadata()
10
+ ResetCoreMetadata()
11
+ })
12
+
13
+ afterEach(() => {
14
+ jest.resetAllMocks()
15
+ })
16
+
17
+ it('Outputs the correct user agent header', () => {
18
+ expect(getUserAgentString()).toEqual(
19
+ `@ronaldphilipsen/local-action-${process.env.npm_package_version}`
20
+ )
21
+ })
22
+ })