hammerkit 1.6.0 → 1.7.0

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 (256) hide show
  1. package/README.md +4 -4
  2. package/build.schema.json +49 -2
  3. package/dist/cache/backends/local-cache-backend.js +58 -1
  4. package/dist/cache/backends/registry/registry-client.js +264 -0
  5. package/dist/cache/backends/registry/registry-credentials.js +81 -0
  6. package/dist/cache/backends/registry/registry-reference.js +36 -0
  7. package/dist/cache/backends/registry-cache-backend.js +145 -0
  8. package/dist/cache/backends/s3-cache-backend.js +99 -46
  9. package/dist/cache/cache-backend-registry.js +2 -0
  10. package/dist/cache/cache-inventory.js +84 -0
  11. package/dist/cache/cache-sync.js +77 -0
  12. package/dist/cache/explain.js +214 -0
  13. package/dist/cache/last-resolved.js +48 -0
  14. package/dist/cache/read-only.js +15 -0
  15. package/dist/cache/retention.js +61 -0
  16. package/dist/cli.js +43 -0
  17. package/dist/docker/using-container.js +5 -1
  18. package/dist/executer/archive-task-entry.js +21 -0
  19. package/dist/executer/await-completed-dependencies.js +32 -14
  20. package/dist/executer/cache-metadata.js +9 -2
  21. package/dist/executer/docker-service.js +2 -1
  22. package/dist/executer/docker-task.js +2 -1
  23. package/dist/executer/dry-run.js +73 -0
  24. package/dist/executer/event-cache.js +6 -5
  25. package/dist/executer/execute-command.js +21 -3
  26. package/dist/executer/execute-work-service.js +10 -1
  27. package/dist/executer/execute-work-task.js +95 -25
  28. package/dist/executer/execute-work-tree.js +26 -1
  29. package/dist/executer/get-scheduler-execute-result.js +4 -1
  30. package/dist/executer/lazy-resolver.js +15 -3
  31. package/dist/executer/reset-work-tree.js +2 -0
  32. package/dist/executer/run-summary.js +102 -0
  33. package/dist/executer/scheduler/enqueue-next.js +15 -60
  34. package/dist/executer/scheduler/state-key.js +78 -0
  35. package/dist/kubernetes/await-running-state.js +73 -19
  36. package/dist/log.js +16 -6
  37. package/dist/logging/live-logger.js +2 -1
  38. package/dist/optimizer/calculate-checksum.js +8 -2
  39. package/dist/optimizer/get-work-cache-stats.js +66 -16
  40. package/dist/optimizer/work-task-cache-description.js +34 -5
  41. package/dist/planner/project-root.js +26 -0
  42. package/dist/planner/utils/append-work-service.js +2 -1
  43. package/dist/planner/utils/append-work-task.js +7 -1
  44. package/dist/planner/utils/parse-work-source.js +35 -30
  45. package/dist/planner/utils/portable-path.js +30 -0
  46. package/dist/planner/work-cache-id.js +2 -2
  47. package/dist/planner/work-graph-serializer.js +103 -0
  48. package/dist/planner/work-instance-id.js +15 -0
  49. package/dist/planner/work-runtime-docker.js +53 -15
  50. package/dist/planner/work-runtime-kubernetes.js +35 -3
  51. package/dist/planner/work-runtime-local.js +9 -3
  52. package/dist/planner/work-service-id.js +16 -4
  53. package/dist/program.js +235 -1
  54. package/dist/schema/build-file-base-task-schema.js +4 -0
  55. package/dist/schema/cache-schema.js +21 -2
  56. package/dist/schema/duration-schema.js +18 -0
  57. package/dist/schema/reference-parser.js +3 -0
  58. package/dist/schema/size-schema.js +18 -0
  59. package/dist/schema/work-scope-parser.js +15 -2
  60. package/dist/utils/units.js +87 -0
  61. package/package.json +12 -1
  62. package/.agents/FEEDBACK.md +0 -74
  63. package/.agents/skills/before-commit/SKILL.md +0 -101
  64. package/.agents/skills/do-the-work/SKILL.md +0 -64
  65. package/.agents/skills/fix-ci/SKILL.md +0 -98
  66. package/.agents/skills/speckit-git-commit/SKILL.md +0 -53
  67. package/.agents/skills/speckit-git-feature/SKILL.md +0 -72
  68. package/.agents/skills/speckit-git-initialize/SKILL.md +0 -54
  69. package/.agents/skills/speckit-git-remote/SKILL.md +0 -50
  70. package/.agents/skills/speckit-git-validate/SKILL.md +0 -54
  71. package/.devcontainer/Dockerfile +0 -5
  72. package/.devcontainer/devcontainer.json +0 -40
  73. package/.gitbook.yaml +0 -5
  74. package/.specify/extensions/.registry +0 -37
  75. package/.specify/extensions/git/README.md +0 -100
  76. package/.specify/extensions/git/commands/speckit.git.commit.md +0 -48
  77. package/.specify/extensions/git/commands/speckit.git.feature.md +0 -67
  78. package/.specify/extensions/git/commands/speckit.git.initialize.md +0 -49
  79. package/.specify/extensions/git/commands/speckit.git.remote.md +0 -45
  80. package/.specify/extensions/git/commands/speckit.git.validate.md +0 -49
  81. package/.specify/extensions/git/config-template.yml +0 -62
  82. package/.specify/extensions/git/extension.yml +0 -140
  83. package/.specify/extensions/git/git-config.yml +0 -62
  84. package/.specify/extensions.yml +0 -149
  85. package/.specify/feature.json +0 -3
  86. package/.specify/init-options.json +0 -10
  87. package/.specify/integration.json +0 -15
  88. package/.specify/integrations/claude.manifest.json +0 -16
  89. package/.specify/integrations/speckit.manifest.json +0 -17
  90. package/.specify/memory/constitution.md +0 -162
  91. package/.specify/templates/checklist-template.md +0 -40
  92. package/.specify/templates/constitution-template.md +0 -50
  93. package/.specify/templates/plan-template.md +0 -113
  94. package/.specify/templates/spec-template.md +0 -131
  95. package/.specify/templates/tasks-template.md +0 -252
  96. package/.specify/workflows/speckit/workflow.yml +0 -77
  97. package/.specify/workflows/workflow-registry.json +0 -13
  98. package/AGENTS.md +0 -94
  99. package/Dockerfile +0 -32
  100. package/FOLLOWUPS.md +0 -34
  101. package/SUMMARY.md +0 -68
  102. package/VALUES.md +0 -53
  103. package/dist/cache/auto-pull.spec.js +0 -123
  104. package/dist/cache/backends/local-cache-backend.spec.js +0 -72
  105. package/dist/cache/backends/s3-cache-backend.spec.js +0 -118
  106. package/dist/cache/cache-backend-registry.spec.js +0 -22
  107. package/dist/cache/resolve-cache.spec.js +0 -52
  108. package/dist/cli.spec.js +0 -23
  109. package/dist/console/get-logger.spec.js +0 -23
  110. package/dist/docker/get-default-platform.spec.js +0 -29
  111. package/dist/docker/longest-common-prefix.spec.js +0 -26
  112. package/dist/docker/package.spec.js +0 -145
  113. package/dist/docker/remove-container.spec.js +0 -32
  114. package/dist/docker/using-container.spec.js +0 -90
  115. package/dist/environment/merge-environment-variables.spec.js +0 -24
  116. package/dist/environment/replace-env-variables.spec.js +0 -47
  117. package/dist/executer/abort.spec.js +0 -18
  118. package/dist/executer/environment-mock.spec.js +0 -22
  119. package/dist/executer/execute.spec.js +0 -51
  120. package/dist/executer/get-service-containers.spec.js +0 -59
  121. package/dist/executer/get-service-env-hints.spec.js +0 -65
  122. package/dist/executer/label-values.spec.js +0 -61
  123. package/dist/executer/lazy-resolver.spec.js +0 -20
  124. package/dist/executer/process-manager.spec.js +0 -54
  125. package/dist/executer/scheduler/enqueue-next.spec.js +0 -136
  126. package/dist/executer/state-resolver.spec.js +0 -37
  127. package/dist/executer/state.spec.js +0 -66
  128. package/dist/executer/states.spec.js +0 -14
  129. package/dist/file/get-file-context.spec.js +0 -178
  130. package/dist/file/move-files.spec.js +0 -48
  131. package/dist/kubernetes/ensure-http-route.spec.js +0 -70
  132. package/dist/kubernetes/ensure-namespace.spec.js +0 -39
  133. package/dist/kubernetes/resolve-pod-name.spec.js +0 -81
  134. package/dist/log.spec.js +0 -131
  135. package/dist/logging/grouped-logger.spec.js +0 -84
  136. package/dist/logging/interactive-logger.spec.js +0 -57
  137. package/dist/logging/live-logger.spec.js +0 -37
  138. package/dist/logging/loggers.spec.js +0 -154
  139. package/dist/optimizer/calculate-checksum.spec.js +0 -34
  140. package/dist/optimizer/get-cache-directory.spec.js +0 -59
  141. package/dist/optimizer/get-work-cache-stats.spec.js +0 -79
  142. package/dist/optimizer/work-task-cache-description.spec.js +0 -45
  143. package/dist/parser/default-build-file.spec.js +0 -48
  144. package/dist/parser/parse-label-arguments.spec.js +0 -27
  145. package/dist/parser/read-build-file.spec.js +0 -89
  146. package/dist/parser/read-env-file.spec.js +0 -42
  147. package/dist/planner/utils/append-work-service.spec.js +0 -71
  148. package/dist/planner/utils/get-container-user.spec.js +0 -30
  149. package/dist/planner/utils/get-default-kube-config.spec.js +0 -11
  150. package/dist/planner/utils/normalize-path.spec.js +0 -24
  151. package/dist/planner/utils/parse-work-command.spec.js +0 -21
  152. package/dist/planner/utils/parse-work-generate.spec.js +0 -45
  153. package/dist/planner/utils/parse-work-mount.spec.js +0 -62
  154. package/dist/planner/utils/parse-work-mounts.spec.js +0 -19
  155. package/dist/planner/utils/parse-work-port.spec.js +0 -24
  156. package/dist/planner/utils/parse-work-ports.spec.js +0 -24
  157. package/dist/planner/utils/parse-work-source.spec.js +0 -58
  158. package/dist/planner/utils/parse-work-volume.spec.js +0 -18
  159. package/dist/planner/utils/plan-work-tasks.spec.js +0 -30
  160. package/dist/planner/utils/plan-work-volume.spec.js +0 -33
  161. package/dist/planner/utils/split-name.spec.js +0 -16
  162. package/dist/planner/utils/template-value.spec.js +0 -14
  163. package/dist/planner/validate.spec.js +0 -251
  164. package/dist/planner/work-cache-id.spec.js +0 -173
  165. package/dist/planner/work-runtime-local.spec.js +0 -193
  166. package/dist/program-commands.spec.js +0 -84
  167. package/dist/program.spec.js +0 -43
  168. package/dist/schema/build-file-schema.spec.js +0 -61
  169. package/dist/schema/doc-build-files.spec.js +0 -223
  170. package/dist/schema/parse-error.spec.js +0 -18
  171. package/dist/schema/reference-parser.spec.js +0 -83
  172. package/dist/schema/schema-parser.spec.js +0 -80
  173. package/dist/schema/type-guards.spec.js +0 -23
  174. package/dist/schema/work-scope-parser.spec.js +0 -66
  175. package/dist/service/update-service-status.spec.js +0 -27
  176. package/dist/testing/ensure-local-registry.js +0 -134
  177. package/dist/testing/example-test-suite.js +0 -63
  178. package/dist/testing/expect.js +0 -82
  179. package/dist/testing/get-test-suite.js +0 -9
  180. package/dist/testing/http-get.js +0 -21
  181. package/dist/testing/integration/cache.spec.js +0 -49
  182. package/dist/testing/integration/cancellation.spec.js +0 -45
  183. package/dist/testing/integration/clean.spec.js +0 -43
  184. package/dist/testing/integration/cmd.spec.js +0 -15
  185. package/dist/testing/integration/concurrency.spec.js +0 -19
  186. package/dist/testing/integration/docker-package-registry.spec.js +0 -44
  187. package/dist/testing/integration/docker-service-crash.spec.js +0 -36
  188. package/dist/testing/integration/docker.spec.js +0 -18
  189. package/dist/testing/integration/env.spec.js +0 -48
  190. package/dist/testing/integration/environment.spec.js +0 -97
  191. package/dist/testing/integration/error.spec.js +0 -19
  192. package/dist/testing/integration/export.spec.js +0 -22
  193. package/dist/testing/integration/extend.spec.js +0 -29
  194. package/dist/testing/integration/glob.spec.js +0 -40
  195. package/dist/testing/integration/include.spec.js +0 -31
  196. package/dist/testing/integration/invalid.spec.js +0 -17
  197. package/dist/testing/integration/invalid_loop.spec.js +0 -56
  198. package/dist/testing/integration/k8s-state-cache.spec.js +0 -41
  199. package/dist/testing/integration/kubernetes-service.spec.js +0 -148
  200. package/dist/testing/integration/kubernetes.spec.js +0 -99
  201. package/dist/testing/integration/labels.spec.js +0 -42
  202. package/dist/testing/integration/local.spec.js +0 -14
  203. package/dist/testing/integration/monorepo.spec.js +0 -15
  204. package/dist/testing/integration/multi-line.spec.js +0 -17
  205. package/dist/testing/integration/reference.spec.js +0 -21
  206. package/dist/testing/integration/services.spec.js +0 -38
  207. package/dist/testing/integration/store.spec.js +0 -52
  208. package/dist/testing/integration/unknown.spec.js +0 -28
  209. package/dist/testing/integration/validate.spec.js +0 -160
  210. package/dist/testing/integration/watch-dependency.spec.js +0 -33
  211. package/dist/testing/integration/watch.spec.js +0 -45
  212. package/dist/testing/requires-kubernetes.js +0 -18
  213. package/dist/testing/requires-linux-containers.js +0 -18
  214. package/dist/testing/requires-windows-containers.js +0 -18
  215. package/dist/testing/test-case.js +0 -75
  216. package/dist/testing/test-streams.js +0 -28
  217. package/dist/testing/test-suite-setup.js +0 -3
  218. package/dist/testing/test-suite.js +0 -3
  219. package/dist/testing/testing-timeout.js +0 -32
  220. package/dist/utils/abort-event.spec.js +0 -46
  221. package/dist/utils/buffer-context.spec.js +0 -38
  222. package/dist/utils/ci.spec.js +0 -53
  223. package/dist/utils/debouncer.spec.js +0 -58
  224. package/dist/utils/emitter.spec.js +0 -34
  225. package/dist/utils/empty-writable.spec.js +0 -18
  226. package/dist/utils/environment-config.spec.js +0 -26
  227. package/dist/utils/fail-never.spec.js +0 -9
  228. package/dist/utils/sleep.spec.js +0 -22
  229. package/dist/version.spec.js +0 -12
  230. package/specs/build-file/caches/spec.md +0 -114
  231. package/specs/build-file/environment-variables/spec.md +0 -82
  232. package/specs/build-file/includes/spec.md +0 -60
  233. package/specs/build-file/references/spec.md +0 -56
  234. package/specs/build-file/spec.md +0 -62
  235. package/specs/cli/clean/spec.md +0 -85
  236. package/specs/cli/down/spec.md +0 -85
  237. package/specs/cli/execute/spec.md +0 -101
  238. package/specs/cli/init/spec.md +0 -64
  239. package/specs/cli/ls/spec.md +0 -66
  240. package/specs/cli/package/spec.md +0 -110
  241. package/specs/cli/spec.md +0 -73
  242. package/specs/cli/store-restore/spec.md +0 -74
  243. package/specs/cli/up/spec.md +0 -80
  244. package/specs/cli/validate/spec.md +0 -70
  245. package/specs/labels/spec.md +0 -91
  246. package/specs/service/container/spec.md +0 -120
  247. package/specs/service/kubernetes/spec.md +0 -97
  248. package/specs/service/spec.md +0 -105
  249. package/specs/task/caching/spec.md +0 -107
  250. package/specs/task/container/spec.md +0 -118
  251. package/specs/task/dependencies/spec.md +0 -70
  252. package/specs/task/extending/spec.md +0 -74
  253. package/specs/task/kubernetes/spec.md +0 -125
  254. package/specs/task/needs/spec.md +0 -59
  255. package/specs/task/spec.md +0 -87
  256. package/specs/task/watching/spec.md +0 -69
@@ -1,45 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const path_1 = require("path");
4
- const get_test_suite_1 = require("../get-test-suite");
5
- const requires_linux_containers_1 = require("../requires-linux-containers");
6
- describe('cancellation', () => {
7
- const suite = (0, get_test_suite_1.getTestSuite)('cancellation', ['.hammerkit.yaml']);
8
- afterAll(() => suite.close());
9
- async function testAbort(taskName, expectedState) {
10
- const { cli, environment } = await suite.setup({ taskName });
11
- const exec = await cli.exec({ logMode: 'live' });
12
- const abortNode = Object.values(exec.state.current.tasks).find((n) => n.data.name.startsWith('long_'));
13
- expect_toBeDefined(abortNode);
14
- exec.state.on('check-status', (evt) => {
15
- if (evt.tasks[abortNode.name].state.current.type === 'running') {
16
- environment.abortCtrl.abort();
17
- }
18
- });
19
- const result = await exec.start();
20
- expect(result.success).toBeFalsy();
21
- if (abortNode) {
22
- expect(abortNode.state.current.type).toEqual(expectedState);
23
- }
24
- else {
25
- expect(abortNode).toBeDefined();
26
- }
27
- expect(await environment.file.exists((0, path_1.join)(suite.path, 'test'))).toBeFalsy();
28
- }
29
- it('should cancel local task with dependencies', async () => {
30
- await testAbort('local_cancel', 'canceled');
31
- });
32
- it('should cancel local task', async () => {
33
- await testAbort('long_running_local', 'canceled');
34
- });
35
- it('should cancel docker task', (0, requires_linux_containers_1.requiresLinuxContainers)(async () => {
36
- await testAbort('long_running_docker', 'canceled');
37
- }));
38
- it('should cancel docker task with dependencies', (0, requires_linux_containers_1.requiresLinuxContainers)(async () => {
39
- await testAbort('docker_cancel', 'canceled');
40
- }));
41
- });
42
- function expect_toBeDefined(arg) {
43
- expect(arg).toBeDefined();
44
- }
45
- //# sourceMappingURL=cancellation.spec.js.map
@@ -1,43 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const path_1 = require("path");
4
- const fs_1 = require("fs");
5
- const expect_1 = require("../expect");
6
- const get_test_suite_1 = require("../get-test-suite");
7
- const get_docker_executor_1 = require("../../executer/get-docker-executor");
8
- const plan_work_volume_1 = require("../../planner/utils/plan-work-volume");
9
- const execute_docker_1 = require("../../executer/execute-docker");
10
- const requires_linux_containers_1 = require("../requires-linux-containers");
11
- describe('clean', () => {
12
- const suite = (0, get_test_suite_1.getTestSuite)('clean', ['.hammerkit.yaml', 'package.json']);
13
- afterAll(() => suite.close());
14
- it('should clean generated outputs locally', async () => {
15
- const { cli, environment } = await suite.setup({ taskName: 'example' });
16
- const result = await cli.runExec({ cacheDefault: 'none' });
17
- await (0, expect_1.expectSuccessfulResult)(result, environment);
18
- const outputPath = (0, path_1.join)(suite.path, 'node_modules');
19
- expect((0, fs_1.existsSync)(outputPath)).toBeTruthy();
20
- await cli.clean();
21
- expect((0, fs_1.existsSync)(outputPath)).toBeFalsy();
22
- });
23
- it('should clean generated outputs in containers', (0, requires_linux_containers_1.requiresLinuxContainers)(async () => {
24
- const { cli, environment } = await suite.setup({ taskName: 'docker:example' });
25
- const result = await cli.runExec({ cacheDefault: 'none' });
26
- await (0, expect_1.expectSuccessfulResult)(result, environment);
27
- const docker = (0, execute_docker_1.getContainerCli)({ type: 'docker' });
28
- const outputPath = (0, path_1.join)(suite.path, 'node_modules');
29
- const volumeName = (0, plan_work_volume_1.getVolumeName)(outputPath);
30
- expect(await (0, get_docker_executor_1.existsVolume)(docker, volumeName)).toBeTruthy();
31
- await cli.clean();
32
- expect(await (0, get_docker_executor_1.existsVolume)(docker, volumeName)).toBeFalsy();
33
- }));
34
- it('should clean and restore created data in volumes', (0, requires_linux_containers_1.requiresLinuxContainers)(async () => {
35
- const { cli, environment } = await suite.setup({ taskName: 'example:service' });
36
- const result = await cli.runExec();
37
- await (0, expect_1.expectSuccessfulResult)(result, environment);
38
- await cli.clean();
39
- const resultAfterClean = await cli.runExec();
40
- await (0, expect_1.expectSuccessfulResult)(resultAfterClean, environment);
41
- }));
42
- });
43
- //# sourceMappingURL=clean.spec.js.map
@@ -1,15 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const expect_1 = require("../expect");
4
- const get_test_suite_1 = require("../get-test-suite");
5
- describe('cmd', () => {
6
- const suite = (0, get_test_suite_1.getTestSuite)('cmd', ['.hammerkit.yaml', 'sub/README.md']);
7
- afterAll(() => suite.close());
8
- it('should run with path arg', async () => {
9
- const { cli, environment } = await suite.setup({ taskName: 'example' });
10
- const result = await cli.runExec();
11
- await (0, expect_1.expectSuccessfulResult)(result, environment);
12
- await (0, expect_1.expectContainsLog)(result, environment, `example`, 'README.md');
13
- });
14
- });
15
- //# sourceMappingURL=cmd.spec.js.map
@@ -1,19 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const expect_1 = require("../expect");
4
- const get_test_suite_1 = require("../get-test-suite");
5
- describe('concurrency', () => {
6
- const suite = (0, get_test_suite_1.getTestSuite)('concurrency', ['.hammerkit.yaml']);
7
- afterAll(() => suite.close());
8
- it('should run with concurrency lower than total tasks', async () => {
9
- const { cli, environment } = await suite.setup({ taskName: 'example' });
10
- const exec = await cli.exec({ workers: 1 });
11
- exec.state.on('check-status', (state) => {
12
- const runningNodes = Object.values(state.tasks).filter((n) => n.state.current.type === 'running');
13
- expect(runningNodes.length).toBeLessThanOrEqual(1);
14
- });
15
- const result = await exec.start();
16
- await (0, expect_1.expectSuccessfulResult)(result, environment);
17
- });
18
- });
19
- //# sourceMappingURL=concurrency.spec.js.map
@@ -1,44 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const test_case_1 = require("../test-case");
4
- const ensure_local_registry_1 = require("../ensure-local-registry");
5
- const requires_linux_containers_1 = require("../requires-linux-containers");
6
- describe('docker/package against a local registry', () => {
7
- let registry;
8
- beforeAll((0, requires_linux_containers_1.requiresLinuxContainers)(async () => {
9
- registry = await (0, ensure_local_registry_1.ensureLocalRegistry)();
10
- }));
11
- afterAll(async () => {
12
- if (registry && process.env.HAMMERKIT_KEEP_REGISTRY !== 'true') {
13
- await registry.cleanup();
14
- }
15
- });
16
- it('pushes a built service image and the registry lists its tag', (0, requires_linux_containers_1.requiresLinuxContainers)(async () => {
17
- const repository = `pkg-${Date.now()}`;
18
- const testCase = (0, test_case_1.createTestCase)('docker-package-registry', {
19
- '.hammerkit.yaml': {
20
- services: {
21
- [repository]: {
22
- image: 'alpine:3.19',
23
- labels: { app: 'svc' },
24
- cmd: 'sh -c "echo hi && sleep 3600"',
25
- src: ['hello.txt'],
26
- ports: ['8080'],
27
- },
28
- },
29
- },
30
- 'hello.txt': 'hi from hammerkit',
31
- });
32
- await testCase.cli({ filterLabels: { app: ['svc'] } }, async (cli) => {
33
- await cli.package({
34
- registry: `${registry.host}:${registry.hostPort}`,
35
- push: true,
36
- overrideUser: false,
37
- username: null,
38
- password: null,
39
- });
40
- });
41
- expect(await registry.listsTag(repository, 'latest')).toBe(true);
42
- }), 180000);
43
- });
44
- //# sourceMappingURL=docker-package-registry.spec.js.map
@@ -1,36 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const test_case_1 = require("../test-case");
4
- const requires_linux_containers_1 = require("../requires-linux-containers");
5
- /**
6
- * Regression for the crash detection in docker-service.ts: a container that
7
- * exits while the runtime is waiting on abort must surface as
8
- * `{ type: 'end', reason: 'crash' }` instead of being silently 'terminated'.
9
- */
10
- describe('docker service crash detection', () => {
11
- const testCase = (0, test_case_1.createTestCase)('docker-service-crash', {
12
- '.hammerkit.yaml': {
13
- services: {
14
- flaky: {
15
- image: 'alpine:3.19',
16
- // command exits with non-zero after a short delay
17
- cmd: 'sh -c "sleep 1 && exit 17"',
18
- ports: [':9000'],
19
- },
20
- },
21
- },
22
- });
23
- it('reports crash when the container exits while running', (0, requires_linux_containers_1.requiresLinuxContainers)(async () => {
24
- await testCase.cli({}, async (cli) => {
25
- // daemon=false so docker-service.ts awaits container.wait() instead of
26
- // returning as soon as the service is 'running'
27
- await cli.runUp({ daemon: false });
28
- const service = cli.service('flaky');
29
- expect(service.state.current.type).toBe('end');
30
- if (service.state.current.type === 'end') {
31
- expect(service.state.current.reason).toBe('crash');
32
- }
33
- });
34
- }), 90000);
35
- });
36
- //# sourceMappingURL=docker-service-crash.spec.js.map
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const expect_1 = require("../expect");
4
- const get_test_suite_1 = require("../get-test-suite");
5
- const requires_linux_containers_1 = require("../requires-linux-containers");
6
- describe('docker', () => {
7
- const suite = (0, get_test_suite_1.getTestSuite)('docker', ['.hammerkit.yaml']);
8
- afterAll(() => suite.close());
9
- it('should pull docker image', (0, requires_linux_containers_1.requiresLinuxContainers)(async () => {
10
- const { cli, environment } = await suite.setup({ taskName: 'example' });
11
- const result = await cli.runExec();
12
- await (0, expect_1.expectSuccessfulResult)(result, environment);
13
- // versions printed by the pinned node:24.16.0-alpine fixture image
14
- await (0, expect_1.expectLog)(result, environment, `example`, '11.13.0');
15
- await (0, expect_1.expectLog)(result, environment, `example`, 'v24.16.0');
16
- }));
17
- });
18
- //# sourceMappingURL=docker.spec.js.map
@@ -1,48 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const expect_1 = require("../expect");
4
- const get_test_suite_1 = require("../get-test-suite");
5
- const requires_linux_containers_1 = require("../requires-linux-containers");
6
- describe('env', () => {
7
- const suite = (0, get_test_suite_1.getTestSuite)('env', ['.hammerkit.yaml', '.env']);
8
- afterAll(() => suite.close());
9
- it('should use env from build file', async () => {
10
- const { cli, environment } = await suite.setup({ taskName: 'example' });
11
- const result = await cli.runExec();
12
- await (0, expect_1.expectSuccessfulResult)(result, environment);
13
- await (0, expect_1.expectLog)(result, environment, `example`, '16.6.0');
14
- });
15
- it('should pass env to docker', (0, requires_linux_containers_1.requiresLinuxContainers)(async () => {
16
- const { cli, environment } = await suite.setup({ taskName: 'example_docker' });
17
- const result = await cli.runExec();
18
- await (0, expect_1.expectSuccessfulResult)(result, environment);
19
- await (0, expect_1.expectLog)(result, environment, `example_docker`, '16.6.0');
20
- }));
21
- it('should use env from task', async () => {
22
- const { cli, environment } = await suite.setup({ taskName: 'example_override' });
23
- const result = await cli.runExec();
24
- await (0, expect_1.expectSuccessfulResult)(result, environment);
25
- await (0, expect_1.expectLog)(result, environment, `example_override`, '15.0.0');
26
- });
27
- it('should use env from .env', async () => {
28
- const { cli, environment } = await suite.setup({ taskName: 'example_with_dotenv' });
29
- const result = await cli.runExec();
30
- await (0, expect_1.expectSuccessfulResult)(result, environment);
31
- await (0, expect_1.expectLog)(result, environment, `example_with_dotenv`, '123456');
32
- });
33
- it('should use process env', async () => {
34
- const { cli, environment } = await suite.setup({
35
- taskName: 'example_with_shell_env',
36
- envs: {
37
- VERSION: '1.0.0',
38
- },
39
- });
40
- const result = await cli.runExec();
41
- await (0, expect_1.expectSuccessfulResult)(result, environment);
42
- await (0, expect_1.expectLog)(result, environment, `example_with_shell_env`, '1.0.0');
43
- });
44
- it('should throw if process env is missing', async () => {
45
- await expect(suite.setup({ taskName: 'example_with_shell_env' })).rejects.toThrow('missing environment variable VERSION');
46
- });
47
- });
48
- //# sourceMappingURL=env.spec.js.map
@@ -1,97 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const get_test_suite_1 = require("../get-test-suite");
4
- const test_case_1 = require("../test-case");
5
- const requires_kubernetes_1 = require("../requires-kubernetes");
6
- const testing_timeout_1 = require("../testing-timeout");
7
- describe('environment', () => {
8
- const suite = (0, get_test_suite_1.getTestSuite)('error', ['.hammerkit.yaml']);
9
- afterAll(() => suite.close());
10
- it('should run on environment (kubernetes)', (0, requires_kubernetes_1.requiresKubernetes)(async () => {
11
- const testCase = (0, test_case_1.createTestCase)('environment', {
12
- '.hammerkit.yaml': {
13
- tasks: {
14
- install: {
15
- image: 'node:18-alpine',
16
- cmds: ['npm install'],
17
- src: ['package.json'],
18
- generates: ['node_modules'],
19
- },
20
- },
21
- services: {
22
- postgres: {
23
- image: 'postgres:16-alpine',
24
- envs: {
25
- POSTGRES_USER: 'postgres',
26
- POSTGRES_DB: 'demo',
27
- POSTGRES_PASSWORD: '123456',
28
- },
29
- ports: [':5432'],
30
- volumes: ['postgres-db:/var/lib/postgresql/data'],
31
- },
32
- api: {
33
- deps: ['install'],
34
- needs: ['postgres'],
35
- image: 'node:16.6.0-alpine',
36
- envs: {
37
- DATABASE_URL: 'postgres://postgres:123456@postgres/demo',
38
- },
39
- cmd: 'node index.js',
40
- src: ['index.js'],
41
- ports: [':3000'],
42
- },
43
- },
44
- environments: {
45
- staging: {
46
- kubernetes: {
47
- namespace: `hammerkit-env-${(process.env.HAMMERKIT_TEST_RUN_ID ?? 'local').slice(0, 40)}`,
48
- context: process.env.CLUSTER_NAME || 'docker-desktop',
49
- ingresses: [
50
- {
51
- host: 'demo.bertschi.io',
52
- service: 'api',
53
- },
54
- ],
55
- },
56
- },
57
- },
58
- },
59
- 'package.json': '{ "dependencies": { "pg": "^8.7.1" } }',
60
- 'index.js': `const { Client } = require('pg')
61
- const { createServer } = require('http')
62
-
63
- const client = new Client(process.env.DATABASE_URL)
64
-
65
- const server = createServer(async (req, res) => {
66
- const result = await client.query('SELECT $1::text as message', ['Hello world!'])
67
- res.writeHead(200)
68
- res.end(result.rows[0].message)
69
- })
70
-
71
- async function main() {
72
- await client.connect()
73
- server.listen(3000)
74
- }
75
-
76
- process.on('SIGINT', async function () {
77
- server.close()
78
- await client.end()
79
- })
80
-
81
- main().catch((err) => {
82
- console.error(err)
83
- process.exit(1)
84
- })
85
- `,
86
- });
87
- await testCase.cli({ environmentName: 'staging' }, async (cli) => {
88
- try {
89
- await (0, testing_timeout_1.testingTimeout)(cli.up({ daemon: true }));
90
- }
91
- finally {
92
- await cli.runDown();
93
- }
94
- });
95
- }));
96
- });
97
- //# sourceMappingURL=environment.spec.js.map
@@ -1,19 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const get_test_suite_1 = require("../get-test-suite");
4
- const requires_linux_containers_1 = require("../requires-linux-containers");
5
- describe('error', () => {
6
- const suite = (0, get_test_suite_1.getTestSuite)('error', ['.hammerkit.yaml']);
7
- afterAll(() => suite.close());
8
- it('should return error when local task failed', async () => {
9
- const { cli } = await suite.setup({ taskName: 'local_error' });
10
- const result = await cli.runExec();
11
- expect(result.success).toBeFalsy();
12
- });
13
- it('should return error when docker task failed', (0, requires_linux_containers_1.requiresLinuxContainers)(async () => {
14
- const { cli } = await suite.setup({ taskName: 'docker_error' });
15
- const result = await cli.runExec();
16
- expect(result.success).toBeFalsy();
17
- }));
18
- });
19
- //# sourceMappingURL=error.spec.js.map
@@ -1,22 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const get_test_suite_1 = require("../get-test-suite");
4
- const path_1 = require("path");
5
- const requires_linux_containers_1 = require("../requires-linux-containers");
6
- describe('export', () => {
7
- const suite = (0, get_test_suite_1.getTestSuite)('export', ['.hammerkit.yaml']);
8
- afterAll(() => suite.close());
9
- it('should export created file', (0, requires_linux_containers_1.requiresLinuxContainers)(async () => {
10
- const { cli, environment } = await suite.setup({ taskName: 'example_file' });
11
- const result = await cli.runExec();
12
- expect(result.success).toBeTruthy();
13
- expect(await environment.file.read((0, path_1.join)(environment.cwd, 'test.txt'))).toEqual('hello\n');
14
- }));
15
- it('should export created directory', (0, requires_linux_containers_1.requiresLinuxContainers)(async () => {
16
- const { cli, environment } = await suite.setup({ taskName: 'example_dir' });
17
- const result = await cli.runExec();
18
- expect(result.success).toBeTruthy();
19
- expect(await environment.file.read((0, path_1.join)(environment.cwd, 'dist/test.txt'))).toEqual('hello\n');
20
- }));
21
- });
22
- //# sourceMappingURL=export.spec.js.map
@@ -1,29 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const get_test_suite_1 = require("../get-test-suite");
4
- describe('extend', () => {
5
- const suite = (0, get_test_suite_1.getTestSuite)('extend', ['.hammerkit.yaml']);
6
- afterAll(() => suite.close());
7
- it('should merge env variables', async () => {
8
- const { cli } = await suite.setup({ taskName: 'extend_env' });
9
- const task = await cli.task('extend_env');
10
- expect(task.data.envs.variables).toMatchObject({ NAME: 'base', KEEP: 'value' });
11
- });
12
- it('should extend and override', async () => {
13
- const { cli } = await suite.setup({ taskName: 'extend_container_task' });
14
- const task = await cli.task('extend_container_task');
15
- expect(task.data.envs.variables).toEqual({
16
- NAME: 'override',
17
- });
18
- expect(task.data.type).toBe('container-task');
19
- if (task.data.type === 'container-task') {
20
- expect(task.data.image).toBe('alpine:latest');
21
- }
22
- });
23
- it('should merge deps', async () => {
24
- const { cli } = await suite.setup({ taskName: 'extend_dep' });
25
- const task = await cli.task('extend_dep');
26
- expect(task.deps.map((d) => d.name).sort()).toEqual(['base_env', 'extend_env'].sort());
27
- });
28
- });
29
- //# sourceMappingURL=extend.spec.js.map
@@ -1,40 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const get_test_suite_1 = require("../get-test-suite");
4
- const enqueue_next_1 = require("../../executer/scheduler/enqueue-next");
5
- describe('glob', () => {
6
- const suite = (0, get_test_suite_1.getTestSuite)('glob', ['.hammerkit.yaml', 'test.md', 'test.txt']);
7
- afterAll(() => suite.close());
8
- async function testCache(expectInvalidate, action) {
9
- const { cli, environment } = await suite.setup({ taskName: 'example' });
10
- const task = cli.task('example');
11
- const cacheBefore = await (0, enqueue_next_1.checkCacheState)(task, 'checksum', environment);
12
- expect(cacheBefore.stateKey).not.toBeNull();
13
- if (action) {
14
- await action(environment);
15
- }
16
- const exampleAfter = cli.task('example');
17
- const cacheAfter = await (0, enqueue_next_1.checkCacheState)(exampleAfter, 'checksum', environment);
18
- expect(cacheAfter.stateKey).not.toBeNull();
19
- if (expectInvalidate) {
20
- expect(cacheAfter.stateKey).not.toEqual(cacheBefore.stateKey);
21
- }
22
- else {
23
- expect(cacheAfter.stateKey).toEqual(cacheBefore.stateKey);
24
- }
25
- }
26
- it('should remove task after written cache', async () => {
27
- await testCache(false);
28
- });
29
- it('should keep being cached after ignored file changed', async () => {
30
- await testCache(false, async (env) => {
31
- await env.file.appendFile('test.txt', '\n');
32
- });
33
- });
34
- it('should invalid cache after file has changed', async () => {
35
- await testCache(true, async (env) => {
36
- await env.file.appendFile('test.md', '\n');
37
- });
38
- });
39
- });
40
- //# sourceMappingURL=glob.spec.js.map
@@ -1,31 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const expect_1 = require("../expect");
4
- const get_test_suite_1 = require("../get-test-suite");
5
- describe('include', () => {
6
- const suite = (0, get_test_suite_1.getTestSuite)('include', ['.hammerkit.yaml', 'foo', 'foobar.txt']);
7
- afterAll(() => suite.close());
8
- it('should run included task', async () => {
9
- const { cli, environment } = await suite.setup({ taskName: 'example' });
10
- const result = await cli.runExec();
11
- await (0, expect_1.expectSuccessfulResult)(result, environment);
12
- await (0, expect_1.expectLog)(result, environment, `foo:bar`, 'foobar');
13
- });
14
- it('should get name:example', async () => {
15
- const { cli, environment } = await suite.setup({ taskName: 'name:example' });
16
- const result = await cli.runExec();
17
- await (0, expect_1.expectSuccessfulResult)(result, environment);
18
- });
19
- it('should get included task', async () => {
20
- const { cli } = await suite.setup({ taskName: 'foo:bar' });
21
- expect(cli.ls().map((n) => n.item.name)).toEqual(['foo:bar']);
22
- const item = cli.ls()[0];
23
- if (item.type === 'task') {
24
- expect(item.item.data.cwd).toBe(suite.path);
25
- }
26
- else {
27
- expect(item.type).toBe('task');
28
- }
29
- });
30
- });
31
- //# sourceMappingURL=include.spec.js.map
@@ -1,17 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const get_test_suite_1 = require("../get-test-suite");
4
- describe('invalid', () => {
5
- const suite = (0, get_test_suite_1.getTestSuite)('invalid', ['.hammerkit.yaml']);
6
- afterAll(() => suite.close());
7
- it('should throw on invalid yaml', async () => {
8
- try {
9
- await suite.setup({});
10
- expect.fail('should not be called');
11
- }
12
- catch (e) {
13
- expect(e.message.startsWith('unable to parse')).toBe(true);
14
- }
15
- });
16
- });
17
- //# sourceMappingURL=invalid.spec.js.map
@@ -1,56 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const test_case_1 = require("../test-case");
4
- describe('invalid', () => {
5
- it('should detect loop in execution', async () => {
6
- const testCase = (0, test_case_1.createTestCase)('invalid_loop', {
7
- '.hammerkit.yaml': {
8
- tasks: {
9
- bar: {
10
- deps: ['foo'],
11
- cmds: ['echo bar'],
12
- },
13
- foo: {
14
- deps: ['bar'],
15
- cmds: ['echo foo'],
16
- },
17
- },
18
- },
19
- });
20
- await testCase.cli({ taskName: 'foo' }, async (cli) => {
21
- const result = await cli.runExec();
22
- expect(result.success).toBeFalsy();
23
- });
24
- });
25
- it('should detect loop in services', async () => {
26
- const testCase = (0, test_case_1.createTestCase)('invalid_loop', {
27
- '.hammerkit.yaml': {
28
- services: {
29
- foodb: {
30
- image: 'postgres:12-alpine',
31
- volumes: ['foo:/var/lib/postgresql/data'],
32
- needs: ['bardb'],
33
- ports: [':5432'],
34
- },
35
- bardb: {
36
- image: 'postgres:12-alpine',
37
- volumes: ['bar:/var/lib/postgresql/data'],
38
- needs: ['foodb'],
39
- ports: [':5432'],
40
- },
41
- },
42
- tasks: {
43
- example: {
44
- needs: ['foodb'],
45
- cmds: ['echo bar'],
46
- },
47
- },
48
- },
49
- });
50
- await testCase.cli({ taskName: 'example' }, async (cli) => {
51
- const result = await cli.runExec();
52
- expect(result.success).toBeFalsy();
53
- });
54
- });
55
- });
56
- //# sourceMappingURL=invalid_loop.spec.js.map
@@ -1,41 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const test_case_1 = require("../test-case");
4
- const requires_kubernetes_1 = require("../requires-kubernetes");
5
- /**
6
- * Regression test for the k8s currentStateKey caching wired up in
7
- * feature/shared-services. Running `up` twice with no input change should
8
- * produce a cached second run, not redeploy.
9
- */
10
- describe('k8s deployment caches via hammerkit.dev/state label', () => {
11
- const namespace = `hammerkit-cache-${(process.env.HAMMERKIT_TEST_RUN_ID ?? 'local').slice(0, 30)}`;
12
- const suite = (0, test_case_1.createTestCase)('k8s-state-cache', {
13
- '.hammerkit.yaml': {
14
- services: {
15
- redis: {
16
- image: 'redis:7-alpine',
17
- ports: [':6379'],
18
- },
19
- },
20
- environments: {
21
- default: {
22
- kubernetes: {
23
- namespace,
24
- context: process.env.CLUSTER_NAME || 'docker-desktop',
25
- },
26
- },
27
- },
28
- },
29
- });
30
- it('second up() is a cache hit on the same state key', (0, requires_kubernetes_1.requiresKubernetes)(async () => {
31
- await suite.cli({}, async (cli, env) => {
32
- await cli.runUp({ daemon: true });
33
- const firstKey = await cli.service('redis').runtime.currentStateKey(env);
34
- expect(firstKey).not.toBeNull();
35
- await cli.runUp({ daemon: true });
36
- const secondKey = await cli.service('redis').runtime.currentStateKey(env);
37
- expect(secondKey).toBe(firstKey);
38
- });
39
- }), 240000);
40
- });
41
- //# sourceMappingURL=k8s-state-cache.spec.js.map