hammerkit 1.6.0 → 1.8.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.
- package/README.md +7 -7
- package/build.schema.json +59 -15
- package/dist/cache/backends/local-cache-backend.js +58 -1
- package/dist/cache/backends/registry/registry-client.js +264 -0
- package/dist/cache/backends/registry/registry-credentials.js +81 -0
- package/dist/cache/backends/registry/registry-reference.js +36 -0
- package/dist/cache/backends/registry-cache-backend.js +145 -0
- package/dist/cache/backends/s3-cache-backend.js +99 -46
- package/dist/cache/cache-backend-registry.js +2 -0
- package/dist/cache/cache-inventory.js +84 -0
- package/dist/cache/cache-sync.js +77 -0
- package/dist/cache/explain.js +214 -0
- package/dist/cache/last-resolved.js +48 -0
- package/dist/cache/read-only.js +15 -0
- package/dist/cache/retention.js +61 -0
- package/dist/cli.js +43 -0
- package/dist/docker/using-container.js +17 -1
- package/dist/executer/archive-task-entry.js +21 -0
- package/dist/executer/await-completed-dependencies.js +32 -14
- package/dist/executer/cache-metadata.js +9 -2
- package/dist/executer/docker-service.js +2 -1
- package/dist/executer/docker-task.js +18 -3
- package/dist/executer/dry-run.js +73 -0
- package/dist/executer/event-cache.js +6 -5
- package/dist/executer/execute-command.js +21 -3
- package/dist/executer/execute-docker.js +18 -2
- package/dist/executer/execute-work-service.js +10 -1
- package/dist/executer/execute-work-task.js +111 -26
- package/dist/executer/execute-work-tree.js +26 -1
- package/dist/executer/execution-steps.js +3 -8
- package/dist/executer/get-container-binds.js +13 -1
- package/dist/executer/get-scheduler-execute-result.js +4 -1
- package/dist/executer/lazy-resolver.js +15 -3
- package/dist/executer/reset-work-tree.js +2 -0
- package/dist/executer/run-summary.js +102 -0
- package/dist/executer/scheduler/enqueue-next.js +15 -60
- package/dist/executer/scheduler/state-key.js +78 -0
- package/dist/index.js +14 -1
- package/dist/kubernetes/apply.js +6 -7
- package/dist/kubernetes/await-running-state.js +100 -60
- package/dist/kubernetes/ensure-http-route.js +7 -10
- package/dist/kubernetes/ensure-namespace.js +9 -10
- package/dist/kubernetes/ensure-persistent-data.js +6 -5
- package/dist/kubernetes/get-service-ip.js +2 -2
- package/dist/kubernetes/kubernetes-instance.js +0 -4
- package/dist/kubernetes/remove-persistent-data.js +16 -6
- package/dist/kubernetes/resolve-pod-name.js +7 -7
- package/dist/log.js +16 -6
- package/dist/logging/live-logger.js +2 -1
- package/dist/optimizer/calculate-checksum.js +8 -2
- package/dist/optimizer/get-work-cache-stats.js +66 -16
- package/dist/optimizer/work-task-cache-description.js +34 -5
- package/dist/planner/project-root.js +26 -0
- package/dist/planner/utils/append-work-environment.js +1 -1
- package/dist/planner/utils/append-work-service.js +2 -1
- package/dist/planner/utils/append-work-task.js +7 -1
- package/dist/planner/utils/get-outputs-to-reset.js +20 -0
- package/dist/planner/utils/parse-work-generate.js +2 -2
- package/dist/planner/utils/parse-work-source.js +35 -30
- package/dist/planner/utils/portable-path.js +30 -0
- package/dist/planner/work-cache-id.js +2 -2
- package/dist/planner/work-graph-serializer.js +103 -0
- package/dist/planner/work-instance-id.js +15 -0
- package/dist/planner/work-runtime-docker.js +58 -15
- package/dist/planner/work-runtime-kubernetes.js +95 -45
- package/dist/planner/work-runtime-local.js +31 -8
- package/dist/planner/work-service-id.js +16 -4
- package/dist/program.js +235 -1
- package/dist/schema/build-file-base-task-schema.js +4 -0
- package/dist/schema/build-file-environment-schema-http-route.js +15 -0
- package/dist/schema/build-file-environment-schema.js +8 -2
- package/dist/schema/build-file-schema.js +1 -1
- package/dist/schema/cache-schema.js +21 -2
- package/dist/schema/duration-schema.js +18 -0
- package/dist/schema/envs-schema.js +1 -1
- package/dist/schema/reference-parser.js +3 -0
- package/dist/schema/size-schema.js +18 -0
- package/dist/schema/work-scope-parser.js +15 -2
- package/dist/utils/units.js +87 -0
- package/package.json +20 -9
- package/.agents/FEEDBACK.md +0 -74
- package/.agents/skills/before-commit/SKILL.md +0 -101
- package/.agents/skills/do-the-work/SKILL.md +0 -64
- package/.agents/skills/fix-ci/SKILL.md +0 -98
- package/.agents/skills/speckit-git-commit/SKILL.md +0 -53
- package/.agents/skills/speckit-git-feature/SKILL.md +0 -72
- package/.agents/skills/speckit-git-initialize/SKILL.md +0 -54
- package/.agents/skills/speckit-git-remote/SKILL.md +0 -50
- package/.agents/skills/speckit-git-validate/SKILL.md +0 -54
- package/.devcontainer/Dockerfile +0 -5
- package/.devcontainer/devcontainer.json +0 -40
- package/.gitbook.yaml +0 -5
- package/.specify/extensions/.registry +0 -37
- package/.specify/extensions/git/README.md +0 -100
- package/.specify/extensions/git/commands/speckit.git.commit.md +0 -48
- package/.specify/extensions/git/commands/speckit.git.feature.md +0 -67
- package/.specify/extensions/git/commands/speckit.git.initialize.md +0 -49
- package/.specify/extensions/git/commands/speckit.git.remote.md +0 -45
- package/.specify/extensions/git/commands/speckit.git.validate.md +0 -49
- package/.specify/extensions/git/config-template.yml +0 -62
- package/.specify/extensions/git/extension.yml +0 -140
- package/.specify/extensions/git/git-config.yml +0 -62
- package/.specify/extensions.yml +0 -149
- package/.specify/feature.json +0 -3
- package/.specify/init-options.json +0 -10
- package/.specify/integration.json +0 -15
- package/.specify/integrations/claude.manifest.json +0 -16
- package/.specify/integrations/speckit.manifest.json +0 -17
- package/.specify/memory/constitution.md +0 -162
- package/.specify/templates/checklist-template.md +0 -40
- package/.specify/templates/constitution-template.md +0 -50
- package/.specify/templates/plan-template.md +0 -113
- package/.specify/templates/spec-template.md +0 -131
- package/.specify/templates/tasks-template.md +0 -252
- package/.specify/workflows/speckit/workflow.yml +0 -77
- package/.specify/workflows/workflow-registry.json +0 -13
- package/AGENTS.md +0 -94
- package/Dockerfile +0 -32
- package/FOLLOWUPS.md +0 -34
- package/SUMMARY.md +0 -68
- package/VALUES.md +0 -53
- package/dist/cache/auto-pull.spec.js +0 -123
- package/dist/cache/backends/local-cache-backend.spec.js +0 -72
- package/dist/cache/backends/s3-cache-backend.spec.js +0 -118
- package/dist/cache/cache-backend-registry.spec.js +0 -22
- package/dist/cache/resolve-cache.spec.js +0 -52
- package/dist/cli.spec.js +0 -23
- package/dist/console/get-logger.spec.js +0 -23
- package/dist/docker/get-default-platform.spec.js +0 -29
- package/dist/docker/longest-common-prefix.spec.js +0 -26
- package/dist/docker/package.spec.js +0 -145
- package/dist/docker/remove-container.spec.js +0 -32
- package/dist/docker/using-container.spec.js +0 -90
- package/dist/environment/merge-environment-variables.spec.js +0 -24
- package/dist/environment/replace-env-variables.spec.js +0 -47
- package/dist/executer/abort.spec.js +0 -18
- package/dist/executer/environment-mock.spec.js +0 -22
- package/dist/executer/execute.spec.js +0 -51
- package/dist/executer/get-service-containers.spec.js +0 -59
- package/dist/executer/get-service-env-hints.spec.js +0 -65
- package/dist/executer/label-values.spec.js +0 -61
- package/dist/executer/lazy-resolver.spec.js +0 -20
- package/dist/executer/process-manager.spec.js +0 -54
- package/dist/executer/scheduler/enqueue-next.spec.js +0 -136
- package/dist/executer/state-resolver.spec.js +0 -37
- package/dist/executer/state.spec.js +0 -66
- package/dist/executer/states.spec.js +0 -14
- package/dist/file/get-file-context.spec.js +0 -178
- package/dist/file/move-files.spec.js +0 -48
- package/dist/kubernetes/ensure-http-route.spec.js +0 -70
- package/dist/kubernetes/ensure-ingress.js +0 -54
- package/dist/kubernetes/ensure-namespace.spec.js +0 -39
- package/dist/kubernetes/resolve-pod-name.spec.js +0 -81
- package/dist/log.spec.js +0 -131
- package/dist/logging/grouped-logger.spec.js +0 -84
- package/dist/logging/interactive-logger.spec.js +0 -57
- package/dist/logging/live-logger.spec.js +0 -37
- package/dist/logging/loggers.spec.js +0 -154
- package/dist/optimizer/calculate-checksum.spec.js +0 -34
- package/dist/optimizer/get-cache-directory.spec.js +0 -59
- package/dist/optimizer/get-work-cache-stats.spec.js +0 -79
- package/dist/optimizer/work-task-cache-description.spec.js +0 -45
- package/dist/parser/default-build-file.spec.js +0 -48
- package/dist/parser/parse-label-arguments.spec.js +0 -27
- package/dist/parser/read-build-file.spec.js +0 -89
- package/dist/parser/read-env-file.spec.js +0 -42
- package/dist/planner/utils/append-work-service.spec.js +0 -71
- package/dist/planner/utils/get-container-user.spec.js +0 -30
- package/dist/planner/utils/get-default-kube-config.spec.js +0 -11
- package/dist/planner/utils/normalize-path.spec.js +0 -24
- package/dist/planner/utils/parse-work-command.spec.js +0 -21
- package/dist/planner/utils/parse-work-generate.spec.js +0 -45
- package/dist/planner/utils/parse-work-mount.spec.js +0 -62
- package/dist/planner/utils/parse-work-mounts.spec.js +0 -19
- package/dist/planner/utils/parse-work-port.spec.js +0 -24
- package/dist/planner/utils/parse-work-ports.spec.js +0 -24
- package/dist/planner/utils/parse-work-source.spec.js +0 -58
- package/dist/planner/utils/parse-work-volume.spec.js +0 -18
- package/dist/planner/utils/plan-work-tasks.spec.js +0 -30
- package/dist/planner/utils/plan-work-volume.spec.js +0 -33
- package/dist/planner/utils/split-name.spec.js +0 -16
- package/dist/planner/utils/template-value.spec.js +0 -14
- package/dist/planner/validate.spec.js +0 -251
- package/dist/planner/work-cache-id.spec.js +0 -173
- package/dist/planner/work-runtime-local.spec.js +0 -193
- package/dist/program-commands.spec.js +0 -84
- package/dist/program.spec.js +0 -43
- package/dist/schema/build-file-environment-schema-ingress.js +0 -14
- package/dist/schema/build-file-schema.spec.js +0 -61
- package/dist/schema/doc-build-files.spec.js +0 -223
- package/dist/schema/parse-error.spec.js +0 -18
- package/dist/schema/reference-parser.spec.js +0 -83
- package/dist/schema/schema-parser.spec.js +0 -80
- package/dist/schema/type-guards.spec.js +0 -23
- package/dist/schema/work-scope-parser.spec.js +0 -66
- package/dist/service/update-service-status.spec.js +0 -27
- package/dist/testing/ensure-local-registry.js +0 -134
- package/dist/testing/example-test-suite.js +0 -63
- package/dist/testing/expect.js +0 -82
- package/dist/testing/get-test-suite.js +0 -9
- package/dist/testing/http-get.js +0 -21
- package/dist/testing/integration/cache.spec.js +0 -49
- package/dist/testing/integration/cancellation.spec.js +0 -45
- package/dist/testing/integration/clean.spec.js +0 -43
- package/dist/testing/integration/cmd.spec.js +0 -15
- package/dist/testing/integration/concurrency.spec.js +0 -19
- package/dist/testing/integration/docker-package-registry.spec.js +0 -44
- package/dist/testing/integration/docker-service-crash.spec.js +0 -36
- package/dist/testing/integration/docker.spec.js +0 -18
- package/dist/testing/integration/env.spec.js +0 -48
- package/dist/testing/integration/environment.spec.js +0 -97
- package/dist/testing/integration/error.spec.js +0 -19
- package/dist/testing/integration/export.spec.js +0 -22
- package/dist/testing/integration/extend.spec.js +0 -29
- package/dist/testing/integration/glob.spec.js +0 -40
- package/dist/testing/integration/include.spec.js +0 -31
- package/dist/testing/integration/invalid.spec.js +0 -17
- package/dist/testing/integration/invalid_loop.spec.js +0 -56
- package/dist/testing/integration/k8s-state-cache.spec.js +0 -41
- package/dist/testing/integration/kubernetes-service.spec.js +0 -148
- package/dist/testing/integration/kubernetes.spec.js +0 -99
- package/dist/testing/integration/labels.spec.js +0 -42
- package/dist/testing/integration/local.spec.js +0 -14
- package/dist/testing/integration/monorepo.spec.js +0 -15
- package/dist/testing/integration/multi-line.spec.js +0 -17
- package/dist/testing/integration/reference.spec.js +0 -21
- package/dist/testing/integration/services.spec.js +0 -38
- package/dist/testing/integration/store.spec.js +0 -52
- package/dist/testing/integration/unknown.spec.js +0 -28
- package/dist/testing/integration/validate.spec.js +0 -160
- package/dist/testing/integration/watch-dependency.spec.js +0 -33
- package/dist/testing/integration/watch.spec.js +0 -45
- package/dist/testing/requires-kubernetes.js +0 -18
- package/dist/testing/requires-linux-containers.js +0 -18
- package/dist/testing/requires-windows-containers.js +0 -18
- package/dist/testing/test-case.js +0 -75
- package/dist/testing/test-streams.js +0 -28
- package/dist/testing/test-suite-setup.js +0 -3
- package/dist/testing/test-suite.js +0 -3
- package/dist/testing/testing-timeout.js +0 -32
- package/dist/utils/abort-event.spec.js +0 -46
- package/dist/utils/buffer-context.spec.js +0 -38
- package/dist/utils/ci.spec.js +0 -53
- package/dist/utils/debouncer.spec.js +0 -58
- package/dist/utils/emitter.spec.js +0 -34
- package/dist/utils/empty-writable.spec.js +0 -18
- package/dist/utils/environment-config.spec.js +0 -26
- package/dist/utils/fail-never.spec.js +0 -9
- package/dist/utils/sleep.spec.js +0 -22
- package/dist/version.spec.js +0 -12
- package/specs/build-file/caches/spec.md +0 -114
- package/specs/build-file/environment-variables/spec.md +0 -82
- package/specs/build-file/includes/spec.md +0 -60
- package/specs/build-file/references/spec.md +0 -56
- package/specs/build-file/spec.md +0 -62
- package/specs/cli/clean/spec.md +0 -85
- package/specs/cli/down/spec.md +0 -85
- package/specs/cli/execute/spec.md +0 -101
- package/specs/cli/init/spec.md +0 -64
- package/specs/cli/ls/spec.md +0 -66
- package/specs/cli/package/spec.md +0 -110
- package/specs/cli/spec.md +0 -73
- package/specs/cli/store-restore/spec.md +0 -74
- package/specs/cli/up/spec.md +0 -80
- package/specs/cli/validate/spec.md +0 -70
- package/specs/labels/spec.md +0 -91
- package/specs/service/container/spec.md +0 -120
- package/specs/service/kubernetes/spec.md +0 -97
- package/specs/service/spec.md +0 -105
- package/specs/task/caching/spec.md +0 -107
- package/specs/task/container/spec.md +0 -118
- package/specs/task/dependencies/spec.md +0 -70
- package/specs/task/extending/spec.md +0 -74
- package/specs/task/kubernetes/spec.md +0 -125
- package/specs/task/needs/spec.md +0 -59
- package/specs/task/spec.md +0 -87
- package/specs/task/watching/spec.md +0 -69
|
@@ -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
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const requires_kubernetes_1 = require("../requires-kubernetes");
|
|
4
|
-
const test_case_1 = require("../test-case");
|
|
5
|
-
const client_node_1 = require("@kubernetes/client-node");
|
|
6
|
-
const http_1 = require("http");
|
|
7
|
-
// Exercises src/executer/kubernetes-service.ts end-to-end: hammerkit's
|
|
8
|
-
// `kubernetes-service` type opens a local TCP server (one per published port)
|
|
9
|
-
// that tunnels via the k8s API to a pod. We deploy nginx directly with the k8s
|
|
10
|
-
// client, then point a hammerkit kubernetes-service at it, drive the lifecycle
|
|
11
|
-
// (load kubeconfig -> resolve pod -> listen -> state `running`) and actually
|
|
12
|
-
// HTTP-GET the forwarded port to prove data flows through to the pod.
|
|
13
|
-
const RUN_ID = (process.env.HAMMERKIT_TEST_RUN_ID ?? 'local').slice(0, 30);
|
|
14
|
-
const NS = `hammerkit-k8s-svc-${RUN_ID}`;
|
|
15
|
-
const CTX = process.env.CLUSTER_NAME || 'docker-desktop';
|
|
16
|
-
const HOST_PORT = 28080;
|
|
17
|
-
const DEPLOY_NAME = 'nginx';
|
|
18
|
-
function makeClients() {
|
|
19
|
-
const kc = new client_node_1.KubeConfig();
|
|
20
|
-
kc.loadFromDefault();
|
|
21
|
-
kc.setCurrentContext(CTX);
|
|
22
|
-
return {
|
|
23
|
-
coreApi: kc.makeApiClient(client_node_1.CoreV1Api),
|
|
24
|
-
appsApi: kc.makeApiClient(client_node_1.AppsV1Api),
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
async function ensureNamespace(coreApi) {
|
|
28
|
-
try {
|
|
29
|
-
await coreApi.readNamespace(NS);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
catch {
|
|
33
|
-
/* missing */
|
|
34
|
-
}
|
|
35
|
-
try {
|
|
36
|
-
await coreApi.createNamespace({ metadata: { name: NS } });
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
/* racing creator */
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
async function applyNginx(coreApi, appsApi) {
|
|
43
|
-
await appsApi.deleteNamespacedDeployment(DEPLOY_NAME, NS).catch(() => undefined);
|
|
44
|
-
await appsApi.createNamespacedDeployment(NS, {
|
|
45
|
-
metadata: { name: DEPLOY_NAME, labels: { app: DEPLOY_NAME } },
|
|
46
|
-
spec: {
|
|
47
|
-
replicas: 1,
|
|
48
|
-
selector: { matchLabels: { app: DEPLOY_NAME } },
|
|
49
|
-
template: {
|
|
50
|
-
metadata: { labels: { app: DEPLOY_NAME } },
|
|
51
|
-
spec: {
|
|
52
|
-
containers: [{ name: DEPLOY_NAME, image: 'nginx:1.25-alpine', ports: [{ containerPort: 80 }] }],
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
const deadline = Date.now() + 90000;
|
|
58
|
-
while (Date.now() < deadline) {
|
|
59
|
-
const pods = await coreApi.listNamespacedPod(NS, undefined, undefined, undefined, undefined, `app=${DEPLOY_NAME}`);
|
|
60
|
-
const ready = pods.body.items.some((p) => p.status?.conditions?.some((c) => c.type === 'Ready' && c.status === 'True'));
|
|
61
|
-
if (ready)
|
|
62
|
-
return;
|
|
63
|
-
await new Promise((r) => setTimeout(r, 1000));
|
|
64
|
-
}
|
|
65
|
-
throw new Error(`nginx pod in ${NS} did not become ready in time`);
|
|
66
|
-
}
|
|
67
|
-
async function waitFor(predicate, timeoutMs, intervalMs = 200) {
|
|
68
|
-
const deadline = Date.now() + timeoutMs;
|
|
69
|
-
while (Date.now() < deadline) {
|
|
70
|
-
if (predicate())
|
|
71
|
-
return;
|
|
72
|
-
await new Promise((r) => setTimeout(r, intervalMs));
|
|
73
|
-
}
|
|
74
|
-
throw new Error('waitFor: predicate never became true');
|
|
75
|
-
}
|
|
76
|
-
function httpGet(host, port, path) {
|
|
77
|
-
return new Promise((resolve, reject) => {
|
|
78
|
-
const req = (0, http_1.request)({ host, port, path, method: 'GET', timeout: 5000 }, (res) => {
|
|
79
|
-
let body = '';
|
|
80
|
-
res.on('data', (c) => (body += c));
|
|
81
|
-
res.on('end', () => resolve({ status: res.statusCode ?? 0, body }));
|
|
82
|
-
});
|
|
83
|
-
req.on('error', reject);
|
|
84
|
-
req.on('timeout', () => {
|
|
85
|
-
req.destroy();
|
|
86
|
-
reject(new Error('http timeout'));
|
|
87
|
-
});
|
|
88
|
-
req.end();
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
describe('kubernetes-service (port-forward)', () => {
|
|
92
|
-
const suite = (0, test_case_1.createTestCase)('k8s-service-forward', {
|
|
93
|
-
'.hammerkit.yaml': {
|
|
94
|
-
services: {
|
|
95
|
-
nginx: {
|
|
96
|
-
context: CTX,
|
|
97
|
-
namespace: NS,
|
|
98
|
-
selector: { type: 'deployment', name: DEPLOY_NAME },
|
|
99
|
-
ports: [`${HOST_PORT}:80`],
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
environments: {
|
|
103
|
-
default: {
|
|
104
|
-
kubernetes: { context: CTX, namespace: NS },
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
});
|
|
109
|
-
beforeAll((0, requires_kubernetes_1.requiresKubernetes)(async () => {
|
|
110
|
-
const { coreApi, appsApi } = makeClients();
|
|
111
|
-
await ensureNamespace(coreApi);
|
|
112
|
-
await applyNginx(coreApi, appsApi);
|
|
113
|
-
}), 120000);
|
|
114
|
-
afterAll(async () => {
|
|
115
|
-
try {
|
|
116
|
-
const { coreApi } = makeClients();
|
|
117
|
-
await coreApi.deleteNamespace(NS).catch(() => undefined);
|
|
118
|
-
}
|
|
119
|
-
catch {
|
|
120
|
-
/* no cluster available */
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
it('forwards a kubernetes-service to a pod and tears down on abort', (0, requires_kubernetes_1.requiresKubernetes)(async () => {
|
|
124
|
-
await suite.cli({}, async (cli, env) => {
|
|
125
|
-
const exec = cli.up({ logMode: 'live' });
|
|
126
|
-
const done = exec.start();
|
|
127
|
-
try {
|
|
128
|
-
// state transitions to `running` only after the forward server's
|
|
129
|
-
// listen() resolves — proves loadKubeConfig + resolvePodName + the
|
|
130
|
-
// TCP listener setup all completed against a live cluster.
|
|
131
|
-
await waitFor(() => exec.state.current.services['nginx']?.state.current.type === 'running', 30000);
|
|
132
|
-
// and an actual byte round-trip through the forward confirms the
|
|
133
|
-
// per-connection portForward path (createServer callback) works too.
|
|
134
|
-
const res = await httpGet('127.0.0.1', HOST_PORT, '/');
|
|
135
|
-
expect(res.status).toBe(200);
|
|
136
|
-
expect(res.body).toMatch(/nginx/i);
|
|
137
|
-
}
|
|
138
|
-
finally {
|
|
139
|
-
env.abortCtrl.abort();
|
|
140
|
-
await done;
|
|
141
|
-
}
|
|
142
|
-
// abort triggers the finally block in kubernetesService: forwards close,
|
|
143
|
-
// state advances to `end`.
|
|
144
|
-
expect(exec.state.current.services['nginx']?.state.current.type).toBe('end');
|
|
145
|
-
});
|
|
146
|
-
}), 120000);
|
|
147
|
-
});
|
|
148
|
-
//# sourceMappingURL=kubernetes-service.spec.js.map
|