@aifabrix/builder 2.43.0 → 2.44.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/anchor-docs.mdc +15 -0
- package/.cursor/rules/cli-layout.mdc +75 -0
- package/.cursor/rules/project-rules.mdc +8 -0
- package/.npmrc.token +1 -0
- package/.nyc_output/55e9d034-ddab-4579-a706-e02a91d75c91.json +1 -0
- package/.nyc_output/processinfo/55e9d034-ddab-4579-a706-e02a91d75c91.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -0
- package/README.md +1 -1
- package/anchor-docs/README.md +10 -0
- package/anchor-docs/_TEMPLATE +24 -0
- package/bin/aifabrix.js +13 -4
- package/integration/hubspot-test/README.md +31 -0
- package/integration/hubspot-test/create-hubspot.js +5 -5
- package/integration/hubspot-test/hubspot-test-datasource-company.json +58 -462
- package/integration/hubspot-test/hubspot-test-datasource-contact.json +61 -555
- package/integration/hubspot-test/hubspot-test-datasource-deal.json +63 -506
- package/integration/hubspot-test/hubspot-test-datasource-users.json +42 -83
- package/integration/hubspot-test/hubspot-test-deploy.json +3 -3
- package/integration/hubspot-test/test-dataplane-down-tests.js +1 -7
- package/integration/hubspot-test/test-dataplane-down.js +3 -3
- package/integration/hubspot-test/test.js +35 -43
- package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +23 -0
- package/integration/roundtrip-test-local/README.md +144 -0
- package/integration/roundtrip-test-local/application.yaml +13 -0
- package/integration/roundtrip-test-local/env.template +15 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +14 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +61 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +25 -0
- package/integration/roundtrip-test-local2/README.md +144 -0
- package/integration/roundtrip-test-local2/application.yaml +13 -0
- package/integration/roundtrip-test-local2/env.template +15 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +31 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +86 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +25 -0
- package/integration/test/wizard.yaml +8 -0
- package/jest.config.default.js +10 -0
- package/jest.config.integration.fixtures.js +22 -0
- package/jest.config.integration.js +21 -18
- package/jest.config.isolated.js +10 -0
- package/jest.projects.js +301 -0
- package/lib/api/certificates.api.js +62 -0
- package/lib/api/datasources-core.api.js +3 -3
- package/lib/api/dev-mtls-request.js +110 -0
- package/lib/api/dev-server-https.js +145 -0
- package/lib/api/dev.api.js +133 -144
- package/lib/api/index.js +11 -3
- package/lib/api/pipeline.api.js +67 -20
- package/lib/api/types/certificates.types.js +48 -0
- package/lib/api/types/dev.types.js +4 -3
- package/lib/api/types/pipeline.types.js +8 -5
- package/lib/api/types/validation-run.types.js +56 -0
- package/lib/api/validation-run.api.js +111 -0
- package/lib/api/validation-runner.js +109 -0
- package/lib/app/certification-show-enrich.js +129 -0
- package/lib/app/certification-verify-rows.js +60 -0
- package/lib/app/config.js +1 -1
- package/lib/app/deploy-status-display.js +2 -2
- package/lib/app/deploy.js +7 -6
- package/lib/app/display.js +2 -1
- package/lib/app/dockerfile.js +3 -2
- package/lib/app/down.js +2 -1
- package/lib/app/helpers.js +6 -5
- package/lib/app/index.js +27 -8
- package/lib/app/list.js +7 -6
- package/lib/app/push.js +4 -3
- package/lib/app/register.js +16 -7
- package/lib/app/rotate-secret.js +14 -13
- package/lib/app/run-container-start.js +184 -0
- package/lib/app/run-docker-fallback.js +108 -0
- package/lib/app/run-env-compose.js +30 -42
- package/lib/app/run-helpers.js +49 -126
- package/lib/app/run-infra-requirements.js +30 -0
- package/lib/app/run-resolve-image.js +21 -0
- package/lib/app/run.js +74 -21
- package/lib/app/show-display.js +44 -1
- package/lib/app/show.js +93 -9
- package/lib/build/index.js +13 -10
- package/lib/certification/cli-cert-sync-skip.js +21 -0
- package/lib/certification/merge-certification-from-artifact.js +185 -0
- package/lib/certification/post-unified-cert-sync.js +33 -0
- package/lib/certification/sync-after-external-command.js +52 -0
- package/lib/certification/sync-system-certification.js +197 -0
- package/lib/cli/index.js +2 -0
- package/lib/cli/setup-app.help.js +67 -0
- package/lib/cli/setup-app.js +61 -121
- package/lib/cli/setup-app.test-commands.js +195 -0
- package/lib/cli/setup-auth.js +19 -5
- package/lib/cli/setup-credential-deployment.js +22 -8
- package/lib/cli/setup-dev-path-commands.js +124 -0
- package/lib/cli/setup-dev.js +170 -113
- package/lib/cli/setup-environment.js +7 -1
- package/lib/cli/setup-external-system.js +84 -23
- package/lib/cli/setup-infra.js +126 -47
- package/lib/cli/setup-parameters.js +32 -0
- package/lib/cli/setup-secrets.js +137 -18
- package/lib/cli/setup-service-user.js +1 -1
- package/lib/cli/setup-utility.js +54 -22
- package/lib/commands/app-down.js +5 -7
- package/lib/commands/app-install.js +14 -7
- package/lib/commands/app-logs.js +13 -10
- package/lib/commands/app-shell.js +4 -1
- package/lib/commands/app-test.js +25 -19
- package/lib/commands/app.js +32 -11
- package/lib/commands/auth-config.js +6 -6
- package/lib/commands/auth-status.js +4 -3
- package/lib/commands/credential-env.js +4 -3
- package/lib/commands/credential-list.js +5 -4
- package/lib/commands/credential-push.js +4 -3
- package/lib/commands/datasource-unified-test-cli.js +428 -0
- package/lib/commands/datasource-unified-test-cli.options.js +191 -0
- package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +106 -0
- package/lib/commands/datasource-validation-cli.js +143 -0
- package/lib/commands/datasource.js +125 -95
- package/lib/commands/deployment-list.js +6 -5
- package/lib/commands/dev-cli-handlers.js +122 -18
- package/lib/commands/dev-down.js +4 -3
- package/lib/commands/dev-init.js +231 -116
- package/lib/commands/dev-show-display.js +473 -0
- package/lib/commands/login-credentials.js +3 -2
- package/lib/commands/login-device.js +4 -3
- package/lib/commands/login.js +5 -4
- package/lib/commands/logout.js +8 -7
- package/lib/commands/parameters-validate.js +54 -0
- package/lib/commands/repair-datasource.js +314 -68
- package/lib/commands/repair-env-template.js +2 -2
- package/lib/commands/repair.js +21 -3
- package/lib/commands/secrets-list.js +23 -12
- package/lib/commands/secrets-remove-all.js +220 -0
- package/lib/commands/secrets-remove.js +21 -12
- package/lib/commands/secrets-set.js +21 -12
- package/lib/commands/secrets-validate.js +4 -4
- package/lib/commands/secure.js +10 -9
- package/lib/commands/service-user.js +26 -25
- package/lib/commands/test-e2e-external.js +27 -1
- package/lib/commands/up-common.js +3 -2
- package/lib/commands/up-dataplane.js +29 -16
- package/lib/commands/up-miso.js +19 -29
- package/lib/commands/upload.js +149 -39
- package/lib/commands/wizard-core-helpers.js +1 -1
- package/lib/commands/wizard-dataplane.js +4 -3
- package/lib/commands/wizard-helpers.js +3 -3
- package/lib/commands/wizard.js +2 -2
- package/lib/core/admin-secrets.js +14 -5
- package/lib/core/audit-logger.js +12 -4
- package/lib/core/config-attach-extensions.js +46 -0
- package/lib/core/config-runtime-paths.js +29 -0
- package/lib/core/config.js +55 -56
- package/lib/core/diff.js +3 -2
- package/lib/core/ensure-encryption-key.js +1 -1
- package/lib/core/secrets-ensure-infra.js +77 -0
- package/lib/core/secrets-ensure.js +120 -64
- package/lib/core/secrets-env-write.js +35 -7
- package/lib/core/secrets-infra-placeholder-sync.js +61 -0
- package/lib/core/secrets.js +200 -37
- package/lib/core/templates-env.js +4 -3
- package/lib/datasource/abac-validator.js +1 -10
- package/lib/datasource/deploy.js +75 -53
- package/lib/datasource/field-reference-validator.js +9 -6
- package/lib/datasource/integration-context.js +63 -0
- package/lib/datasource/list.js +8 -7
- package/lib/datasource/log-viewer.js +189 -67
- package/lib/datasource/resolve-app.js +4 -4
- package/lib/datasource/test-e2e.js +113 -146
- package/lib/datasource/test-integration.js +114 -122
- package/lib/datasource/unified-validation-run-body.js +68 -0
- package/lib/datasource/unified-validation-run-post.js +23 -0
- package/lib/datasource/unified-validation-run-resolve.js +43 -0
- package/lib/datasource/unified-validation-run.js +93 -0
- package/lib/datasource/validate.js +157 -13
- package/lib/deployment/deployer.js +4 -3
- package/lib/deployment/environment.js +7 -6
- package/lib/deployment/push.js +17 -8
- package/lib/external-system/delete.js +4 -3
- package/lib/external-system/deploy.js +166 -53
- package/lib/external-system/download-helpers.js +1 -1
- package/lib/external-system/download.js +7 -6
- package/lib/external-system/generator.js +92 -6
- package/lib/external-system/integration-test-dispatch.js +26 -0
- package/lib/external-system/test-execution.js +5 -1
- package/lib/external-system/test-helpers.js +0 -4
- package/lib/external-system/test-system-level-helpers.js +110 -0
- package/lib/external-system/test-system-level.js +83 -44
- package/lib/external-system/test.js +59 -8
- package/lib/generator/builders.js +23 -11
- package/lib/generator/deploy-manifest-azure-kv.js +81 -0
- package/lib/generator/external.js +16 -4
- package/lib/generator/helpers.js +58 -3
- package/lib/generator/index.js +4 -0
- package/lib/generator/split-readme.js +12 -7
- package/lib/generator/split-variables.js +2 -1
- package/lib/generator/split.js +1 -1
- package/lib/generator/wizard-readme.js +3 -3
- package/lib/generator/wizard.js +8 -8
- package/lib/infrastructure/compose.js +70 -7
- package/lib/infrastructure/helpers-docker-check.js +67 -0
- package/lib/infrastructure/helpers.js +203 -42
- package/lib/infrastructure/index.js +31 -18
- package/lib/infrastructure/services.js +21 -67
- package/lib/internal/fs-real-sync.js +104 -0
- package/lib/internal/node-fs.js +98 -0
- package/lib/parameters/database-secret-values.js +173 -0
- package/lib/parameters/infra-kv-discovery.js +121 -0
- package/lib/parameters/infra-parameter-catalog.js +458 -0
- package/lib/parameters/infra-parameter-validate.js +64 -0
- package/lib/schema/application-schema.json +37 -17
- package/lib/schema/datasource-test-run.schema.json +493 -0
- package/lib/schema/deployment-rules.yaml +102 -63
- package/lib/schema/external-datasource.schema.json +1200 -442
- package/lib/schema/external-system.schema.json +203 -5
- package/lib/schema/flag-map-validation-run.json +31 -0
- package/lib/schema/infra-parameter.schema.json +106 -0
- package/lib/schema/infra.parameter.yaml +421 -0
- package/lib/schema/type/credential-auth-templates.json +40 -0
- package/lib/schema/type/document-storage.json +226 -0
- package/lib/schema/type/message-service.json +123 -0
- package/lib/schema/type/vector-store.json +88 -0
- package/lib/utils/aifabrix-runtime-config-dir.js +132 -0
- package/lib/utils/api-error-handler.js +2 -2
- package/lib/utils/api.js +77 -17
- package/lib/utils/app-register-api.js +3 -2
- package/lib/utils/app-register-auth.js +1 -1
- package/lib/utils/app-register-config.js +4 -4
- package/lib/utils/app-register-display.js +3 -2
- package/lib/utils/app-register-validator.js +3 -2
- package/lib/utils/app-run-containers.js +26 -22
- package/lib/utils/app-scoped-config.js +31 -0
- package/lib/utils/app-service-env-from-builder.js +164 -0
- package/lib/utils/build-copy.js +1 -1
- package/lib/utils/build-helpers.js +20 -20
- package/lib/utils/build-resolve-image.js +165 -0
- package/lib/utils/cli-layout-chalk.js +8 -0
- package/lib/utils/cli-test-layout-chalk.js +267 -0
- package/lib/utils/cli-utils.js +88 -11
- package/lib/utils/compose-db-passwords.js +138 -0
- package/lib/utils/compose-generate-docker-compose.js +216 -0
- package/lib/utils/compose-generator.js +197 -291
- package/lib/utils/compose-miso-env.js +18 -0
- package/lib/utils/compose-traefik-ingress-base.js +158 -0
- package/lib/utils/config-paths.js +166 -7
- package/lib/utils/config-scoped-resources-preference.js +41 -0
- package/lib/utils/configuration-env-resolver.js +11 -8
- package/lib/utils/controller-deployment-outcome.js +68 -0
- package/lib/utils/credential-display.js +2 -2
- package/lib/utils/credential-secrets-env.js +5 -5
- package/lib/utils/dataplane-pipeline-warning.js +4 -3
- package/lib/utils/datasource-test-run-capability-scope.js +43 -0
- package/lib/utils/datasource-test-run-certificate-tty.js +82 -0
- package/lib/utils/datasource-test-run-debug-display.js +137 -0
- package/lib/utils/datasource-test-run-debug-slice.js +93 -0
- package/lib/utils/datasource-test-run-display.js +459 -0
- package/lib/utils/datasource-test-run-exit.js +83 -0
- package/lib/utils/datasource-test-run-legacy-adapter.js +93 -0
- package/lib/utils/datasource-test-run-report-version.js +51 -0
- package/lib/utils/datasource-test-run-schema-sync.js +59 -0
- package/lib/utils/datasource-test-run-tty-log.js +81 -0
- package/lib/utils/datasource-validation-watch.js +266 -0
- package/lib/utils/declarative-url-ports.js +47 -0
- package/lib/utils/derive-env-key-from-client-id.js +41 -0
- package/lib/utils/dev-ca-install.js +185 -23
- package/lib/utils/dev-cert-helper.js +266 -17
- package/lib/utils/dev-hosts-helper.js +307 -0
- package/lib/utils/dev-init-cert-hints.js +37 -0
- package/lib/utils/dev-init-health-messages.js +52 -0
- package/lib/utils/dev-init-resolve.js +86 -0
- package/lib/utils/dev-init-ssh-merge.js +65 -0
- package/lib/utils/dev-ssh-config-helper.js +196 -0
- package/lib/utils/dev-user-groups.js +93 -0
- package/lib/utils/docker-build.js +42 -17
- package/lib/utils/docker-exec.js +28 -0
- package/lib/utils/docker-manifest-public-port.js +116 -0
- package/lib/utils/docker-not-running-hint.js +52 -0
- package/lib/utils/docker.js +98 -11
- package/lib/utils/ensure-dev-certs-for-remote-docker.js +192 -0
- package/lib/utils/env-config-loader.js +10 -91
- package/lib/utils/env-copy.js +19 -10
- package/lib/utils/env-map.js +35 -8
- package/lib/utils/env-template.js +2 -2
- package/lib/utils/environment-scoped-resources.js +144 -0
- package/lib/utils/error-formatter.js +92 -13
- package/lib/utils/error-formatters/http-status-errors.js +6 -5
- package/lib/utils/error-formatters/network-errors.js +2 -1
- package/lib/utils/error-formatters/permission-errors.js +2 -1
- package/lib/utils/error-formatters/validation-errors.js +2 -1
- package/lib/utils/external-readme.js +8 -1
- package/lib/utils/external-system-display.js +242 -136
- package/lib/utils/external-system-local-test-tty.js +389 -0
- package/lib/utils/external-system-readiness-core.js +377 -0
- package/lib/utils/external-system-readiness-deploy-display.js +270 -0
- package/lib/utils/external-system-readiness-display-internals.js +150 -0
- package/lib/utils/external-system-readiness-display.js +186 -0
- package/lib/utils/external-system-system-test-tty-overview.js +120 -0
- package/lib/utils/external-system-system-test-tty.js +417 -0
- package/lib/utils/external-system-test-helpers.js +24 -6
- package/lib/utils/external-system-validators.js +30 -12
- package/lib/utils/health-check-url.js +119 -0
- package/lib/utils/health-check.js +59 -25
- package/lib/utils/help-builder.js +11 -8
- package/lib/utils/image-version.js +4 -8
- package/lib/utils/infra-containers.js +4 -7
- package/lib/utils/infra-env-defaults.js +162 -0
- package/lib/utils/infra-status-display.js +167 -0
- package/lib/utils/infra-status.js +16 -8
- package/lib/utils/local-secrets.js +3 -4
- package/lib/utils/paths.js +148 -47
- package/lib/utils/port-resolver.js +10 -23
- package/lib/utils/redis-env-scope.js +62 -0
- package/lib/utils/register-aifabrix-shell-env.js +204 -0
- package/lib/utils/remote-builder-validation.js +99 -0
- package/lib/utils/remote-dev-auth.js +117 -21
- package/lib/utils/remote-docker-env.js +67 -15
- package/lib/utils/remote-secrets-loader.js +13 -4
- package/lib/utils/resolve-docker-image-ref.js +124 -0
- package/lib/utils/schema-loader.js +22 -9
- package/lib/utils/secrets-bash-kv.js +25 -0
- package/lib/utils/secrets-generator.js +169 -49
- package/lib/utils/secrets-helpers.js +70 -59
- package/lib/utils/secrets-kv-scope.js +60 -0
- package/lib/utils/secrets-utils.js +32 -38
- package/lib/utils/secrets-validation.js +3 -1
- package/lib/utils/secrets-yaml-preserve.js +109 -0
- package/lib/utils/ssh-key-helper.js +4 -2
- package/lib/utils/template-helpers.js +2 -2
- package/lib/utils/test-log-writer.js +3 -3
- package/lib/utils/token-manager.js +1 -2
- package/lib/utils/url-declarative-public-base.js +188 -0
- package/lib/utils/url-declarative-resolve-build.js +493 -0
- package/lib/utils/url-declarative-resolve-load-doc.js +51 -0
- package/lib/utils/url-declarative-resolve.js +220 -0
- package/lib/utils/url-declarative-token-parse.js +74 -0
- package/lib/utils/url-declarative-url-flags.js +50 -0
- package/lib/utils/url-declarative-vdir-inactive-env.js +99 -0
- package/lib/utils/url-public-path-prefix.js +34 -0
- package/lib/utils/urls-local-registry.js +220 -0
- package/lib/utils/validation-report-tty-kit.js +77 -0
- package/lib/utils/validation-run-poll.js +112 -0
- package/lib/utils/validation-run-post-retry.js +85 -0
- package/lib/utils/validation-run-request.js +116 -0
- package/lib/utils/variable-transformer.js +21 -4
- package/lib/utils/yaml-preserve.js +33 -14
- package/lib/validation/datasource-warnings.js +56 -0
- package/lib/validation/env-template-auth.js +1 -1
- package/lib/validation/external-manifest-validator.js +27 -7
- package/lib/validation/validate-display.js +37 -31
- package/lib/validation/validate-external-cert-sync.js +23 -0
- package/lib/validation/validate.js +8 -14
- package/lib/validation/validator-unresolved-placeholders.js +98 -0
- package/lib/validation/validator.js +22 -65
- package/lib/validation/wizard-config-validator.js +2 -1
- package/package.json +9 -4
- package/scripts/check-datasource-test-run-schema-sync.js +34 -0
- package/scripts/diagnose-cli.js +150 -0
- package/scripts/install-local.js +307 -55
- package/scripts/pnpm-global-remove.js +48 -0
- package/templates/README.md +15 -2
- package/templates/applications/dataplane/application.yaml +52 -2
- package/templates/applications/dataplane/env.template +79 -17
- package/templates/applications/dataplane/rbac.yaml +8 -0
- package/templates/applications/keycloak/application.yaml +9 -1
- package/templates/applications/keycloak/env.template +15 -6
- package/templates/applications/miso-controller/application.yaml +10 -2
- package/templates/applications/miso-controller/env.template +42 -12
- package/templates/applications/miso-controller/rbac.yaml +5 -0
- package/templates/external-system/README.md.hbs +20 -7
- package/templates/external-system/deploy.js.hbs +5 -5
- package/templates/external-system/external-datasource.yaml.hbs +197 -118
- package/templates/infra/compose.yaml.hbs +33 -16
- package/templates/infra/servers.json.hbs +3 -1
- package/templates/python/docker-compose.hbs +16 -0
- package/templates/typescript/docker-compose.hbs +16 -0
- package/lib/api/external-test.api.js +0 -111
- package/lib/schema/env-config.yaml +0 -60
package/lib/cli/setup-utility.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* CLI utility command setup (resolve, json, split-json, show, validate, diff).
|
|
3
4
|
*
|
|
@@ -15,6 +16,20 @@ const logger = require('../utils/logger');
|
|
|
15
16
|
const { handleCommandError, logOfflinePathWhenType } = require('../utils/cli-utils');
|
|
16
17
|
const { detectAppType, getDeployJsonPath, getResolveAppPath } = require('../utils/paths');
|
|
17
18
|
|
|
19
|
+
const JSON_HELP_AFTER = `
|
|
20
|
+
Example:
|
|
21
|
+
$ aifabrix json myapp
|
|
22
|
+
Generates *-deploy.json (or application-schema.json) for commit before deploy.
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
const VALIDATE_HELP_AFTER = `
|
|
26
|
+
Examples:
|
|
27
|
+
$ aifabrix validate myapp
|
|
28
|
+
$ aifabrix validate myapp --cert-sync
|
|
29
|
+
$ aifabrix validate --integration
|
|
30
|
+
$ aifabrix validate --builder
|
|
31
|
+
`;
|
|
32
|
+
|
|
18
33
|
/**
|
|
19
34
|
* Resolve app path and type for split-json (integration first, then builder).
|
|
20
35
|
*
|
|
@@ -67,7 +82,7 @@ async function handleSplitJsonCommand(appName, options) {
|
|
|
67
82
|
* @returns {void}
|
|
68
83
|
*/
|
|
69
84
|
function logSplitJsonResult(result) {
|
|
70
|
-
logger.log(
|
|
85
|
+
logger.log(formatSuccessParagraph('Successfully split deployment JSON into component files:'));
|
|
71
86
|
logger.log(` • env.template: ${result.envTemplate}`);
|
|
72
87
|
logger.log(` • application.yaml: ${result.variables}`);
|
|
73
88
|
if (result.systemFile) {
|
|
@@ -88,7 +103,7 @@ function logSplitJsonResult(result) {
|
|
|
88
103
|
|
|
89
104
|
function setupResolveCommand(program) {
|
|
90
105
|
program.command('resolve <app>')
|
|
91
|
-
.description('Generate .env
|
|
106
|
+
.description('Generate .env from template; optional validate after')
|
|
92
107
|
.option('-f, --force', 'Generate missing secret keys in secrets file')
|
|
93
108
|
.option('--skip-validation', 'Skip file validation after generating .env')
|
|
94
109
|
.action(async(appName, options) => {
|
|
@@ -101,7 +116,7 @@ function setupResolveCommand(program) {
|
|
|
101
116
|
options.force,
|
|
102
117
|
{ appPath, envOnly, skipOutputPath: false, preserveFromPath: null }
|
|
103
118
|
);
|
|
104
|
-
logger.log(
|
|
119
|
+
logger.log(`✔ Generated .env file: ${envPath}`);
|
|
105
120
|
if (envOnly) {
|
|
106
121
|
logger.log(chalk.gray(' (env-only mode: validation skipped; no application.yaml)'));
|
|
107
122
|
} else if (!options.skipValidation) {
|
|
@@ -109,7 +124,7 @@ function setupResolveCommand(program) {
|
|
|
109
124
|
const result = await validate.validateAppOrFile(appName);
|
|
110
125
|
validate.displayValidationResults(result);
|
|
111
126
|
if (!result.valid) {
|
|
112
|
-
logger.log(chalk.yellow('\n
|
|
127
|
+
logger.log(chalk.yellow('\n⚠ Validation found errors. Fix them before deploying.'));
|
|
113
128
|
process.exit(1);
|
|
114
129
|
}
|
|
115
130
|
}
|
|
@@ -122,19 +137,20 @@ function setupResolveCommand(program) {
|
|
|
122
137
|
|
|
123
138
|
function setupJsonCommand(program) {
|
|
124
139
|
program.command('json <app>')
|
|
125
|
-
.description('
|
|
140
|
+
.description('Write deployment JSON to disk for version control')
|
|
141
|
+
.addHelpText('after', JSON_HELP_AFTER)
|
|
126
142
|
.action(async(appName, options) => {
|
|
127
143
|
try {
|
|
128
144
|
const result = await generator.generateDeployJsonWithValidation(appName, options);
|
|
129
145
|
if (result.success) {
|
|
130
146
|
const fileName = result.path.includes('application-schema.json') ? 'application-schema.json' : 'deployment JSON';
|
|
131
|
-
logger.log(
|
|
147
|
+
logger.log(`✔ Generated ${fileName}: ${result.path}`);
|
|
132
148
|
if (result.validation.warnings && result.validation.warnings.length > 0) {
|
|
133
|
-
logger.log('\n
|
|
149
|
+
logger.log('\n⚠ Warnings:');
|
|
134
150
|
result.validation.warnings.forEach(w => logger.log(` • ${w}`));
|
|
135
151
|
}
|
|
136
152
|
} else {
|
|
137
|
-
logger.log('
|
|
153
|
+
logger.log('✖ Validation failed:');
|
|
138
154
|
(result.validation.errors || []).forEach(e => logger.log(` • ${e}`));
|
|
139
155
|
process.exit(1);
|
|
140
156
|
}
|
|
@@ -147,7 +163,7 @@ function setupJsonCommand(program) {
|
|
|
147
163
|
|
|
148
164
|
function setupSplitJsonCommand(program) {
|
|
149
165
|
program.command('split-json <app>')
|
|
150
|
-
.description('Split
|
|
166
|
+
.description('Split deploy JSON into env.template, application.yaml, rbac, README, …')
|
|
151
167
|
.option('-o, --output <dir>', 'Output directory for component files (defaults to same directory as JSON)')
|
|
152
168
|
.action(async(appName, options) => {
|
|
153
169
|
try {
|
|
@@ -160,13 +176,13 @@ function setupSplitJsonCommand(program) {
|
|
|
160
176
|
}
|
|
161
177
|
|
|
162
178
|
function setupRepairCommand(program) {
|
|
163
|
-
program.command('repair <
|
|
164
|
-
.description('
|
|
179
|
+
program.command('repair <systemKey>')
|
|
180
|
+
.description('Fix external integration drift (files, RBAC, manifest, …)')
|
|
165
181
|
.option('--auth <method>', 'Set authentication method (oauth2, aad, apikey, basic, queryParam, oidc, hmac, none); updates system file and env.template')
|
|
166
182
|
.option('--doc', 'Regenerate README.md from deployment manifest')
|
|
167
183
|
.option('--dry-run', 'Report changes only; do not write')
|
|
168
184
|
.option('--rbac', 'Ensure RBAC permissions per datasource and add default Admin/Reader roles if none exist')
|
|
169
|
-
.option('--expose', 'Set exposed.
|
|
185
|
+
.option('--expose', 'Set exposed.schema on each datasource from all fieldMappings.attributes keys (metadata.<key>); removes deprecated exposed.attributes if present')
|
|
170
186
|
.option('--sync', 'Add default sync section to datasources that lack it')
|
|
171
187
|
.option('--test', 'Generate testPayload.payloadTemplate and testPayload.expectedResult from attributes')
|
|
172
188
|
.action(async(appName, options) => {
|
|
@@ -196,9 +212,9 @@ function setupRepairCommand(program) {
|
|
|
196
212
|
logger.log(chalk.yellow('\nWould apply:'));
|
|
197
213
|
result.changes.forEach(c => logger.log(chalk.gray(` ${c}`)));
|
|
198
214
|
} else if (result.updated) {
|
|
199
|
-
logger.log(
|
|
215
|
+
logger.log(formatSuccessParagraph('Repaired external integration config.'));
|
|
200
216
|
} else if (result.readmeRegenerated) {
|
|
201
|
-
logger.log(
|
|
217
|
+
logger.log(formatSuccessParagraph('Regenerated README.md from deployment manifest.'));
|
|
202
218
|
} else {
|
|
203
219
|
logger.log(chalk.gray('No changes needed; config already matches files on disk.'));
|
|
204
220
|
}
|
|
@@ -211,7 +227,7 @@ function setupRepairCommand(program) {
|
|
|
211
227
|
|
|
212
228
|
function setupConvertCommand(program) {
|
|
213
229
|
program.command('convert <app>')
|
|
214
|
-
.description('Convert integration
|
|
230
|
+
.description('Convert integration config files between JSON and YAML')
|
|
215
231
|
.option('--format <format>', 'Target format: json | yaml (required unless config format is set)')
|
|
216
232
|
.option('-f, --force', 'Skip confirmation prompt')
|
|
217
233
|
.action(async(appName, options) => {
|
|
@@ -229,7 +245,7 @@ function setupConvertCommand(program) {
|
|
|
229
245
|
}
|
|
230
246
|
const { runConvert } = require('../commands/convert');
|
|
231
247
|
const { converted, deleted } = await runConvert(appName, { format: normalized, force: options.force });
|
|
232
|
-
logger.log(
|
|
248
|
+
logger.log(formatSuccessParagraph('Convert complete.'));
|
|
233
249
|
converted.forEach(p => logger.log(` • ${p}`));
|
|
234
250
|
if (deleted.length > 0) {
|
|
235
251
|
logger.log(chalk.gray(' Removed old files:'));
|
|
@@ -243,14 +259,22 @@ function setupConvertCommand(program) {
|
|
|
243
259
|
}
|
|
244
260
|
|
|
245
261
|
function setupShowCommand(program) {
|
|
246
|
-
program.command('show <
|
|
247
|
-
.description('Show
|
|
262
|
+
program.command('show <app>')
|
|
263
|
+
.description('Show app from local tree (default) or controller (--online)')
|
|
248
264
|
.option('--online', 'Fetch application data from the controller')
|
|
249
265
|
.option('--json', 'Output as JSON')
|
|
266
|
+
.option(
|
|
267
|
+
'--verify-cert',
|
|
268
|
+
'For external integrations, verify trust state on the dataplane when logged in (with --online uses current session; offline attempts the same if a controller URL is configured)'
|
|
269
|
+
)
|
|
250
270
|
.action(async(appKey, options) => {
|
|
251
271
|
try {
|
|
252
272
|
const { showApp } = require('../app/show');
|
|
253
|
-
await showApp(appKey, {
|
|
273
|
+
await showApp(appKey, {
|
|
274
|
+
online: options.online,
|
|
275
|
+
json: options.json,
|
|
276
|
+
verifyCert: options.verifyCert === true
|
|
277
|
+
});
|
|
254
278
|
} catch (error) {
|
|
255
279
|
logger.error(chalk.red(`Error: ${error.message}`));
|
|
256
280
|
process.exit(1);
|
|
@@ -292,7 +316,10 @@ async function runValidateCommand(appOrFile, options) {
|
|
|
292
316
|
process.exit(1);
|
|
293
317
|
}
|
|
294
318
|
|
|
295
|
-
const result = await validate.validateAppOrFile(appOrFile,
|
|
319
|
+
const result = await validate.validateAppOrFile(appOrFile, {
|
|
320
|
+
...opts,
|
|
321
|
+
certSync: opts.certSync === true
|
|
322
|
+
});
|
|
296
323
|
if (outFormat === 'json') {
|
|
297
324
|
logger.log(JSON.stringify(result, null, 2));
|
|
298
325
|
} else {
|
|
@@ -303,10 +330,15 @@ async function runValidateCommand(appOrFile, options) {
|
|
|
303
330
|
|
|
304
331
|
function setupValidateDiffCommands(program) {
|
|
305
332
|
program.command('validate [appOrFile]')
|
|
306
|
-
.description('Validate
|
|
333
|
+
.description('Validate one app/file or all under integration/ or builder/')
|
|
334
|
+
.addHelpText('after', VALIDATE_HELP_AFTER)
|
|
307
335
|
.option('--format <format>', 'Output format: json | default (human-readable)')
|
|
308
336
|
.option('--integration', 'Validate all applications under integration/')
|
|
309
337
|
.option('--builder', 'Validate all applications under builder/')
|
|
338
|
+
.option(
|
|
339
|
+
'--cert-sync',
|
|
340
|
+
'After successful validation of an external integration, refresh the system file certification block from the dataplane (requires login)'
|
|
341
|
+
)
|
|
310
342
|
.action((appOrFile, options) => {
|
|
311
343
|
runValidateCommand(appOrFile, options).catch((error) => {
|
|
312
344
|
handleCommandError(error, 'validate');
|
|
@@ -315,7 +347,7 @@ function setupValidateDiffCommands(program) {
|
|
|
315
347
|
});
|
|
316
348
|
|
|
317
349
|
program.command('diff <file1> <file2>')
|
|
318
|
-
.description('
|
|
350
|
+
.description('Diff two config files (optional schema validate)')
|
|
319
351
|
.option('--no-validate', 'Skip schema validation (type check still applied)')
|
|
320
352
|
.action(async(file1, file2, cmd) => {
|
|
321
353
|
try {
|
package/lib/commands/app-down.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* Down-app command – stop container, optionally volumes, then remove image if unused
|
|
3
4
|
*
|
|
@@ -7,14 +8,11 @@
|
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
const chalk = require('chalk');
|
|
10
|
-
const { exec } = require('child_process');
|
|
11
|
-
const { promisify } = require('util');
|
|
12
11
|
const logger = require('../utils/logger');
|
|
13
12
|
const config = require('../core/config');
|
|
14
13
|
const containerHelpers = require('../utils/app-run-containers');
|
|
15
14
|
const { downApp } = require('../app/down');
|
|
16
|
-
|
|
17
|
-
const execAsync = promisify(exec);
|
|
15
|
+
const { execWithDockerEnv } = require('../utils/docker-exec');
|
|
18
16
|
|
|
19
17
|
/**
|
|
20
18
|
* Get image ID of a running container (sha or name:tag)
|
|
@@ -24,7 +22,7 @@ const execAsync = promisify(exec);
|
|
|
24
22
|
*/
|
|
25
23
|
async function getContainerImageId(containerName) {
|
|
26
24
|
try {
|
|
27
|
-
const { stdout } = await
|
|
25
|
+
const { stdout } = await execWithDockerEnv(
|
|
28
26
|
`docker inspect --format='{{.Image}}' ${containerName}`,
|
|
29
27
|
{ encoding: 'utf8' }
|
|
30
28
|
);
|
|
@@ -43,8 +41,8 @@ async function getContainerImageId(containerName) {
|
|
|
43
41
|
async function removeImageIfUnused(imageId) {
|
|
44
42
|
if (!imageId) return;
|
|
45
43
|
try {
|
|
46
|
-
await
|
|
47
|
-
logger.log(
|
|
44
|
+
await execWithDockerEnv(`docker rmi ${imageId}`);
|
|
45
|
+
logger.log(formatSuccessLine(`Image ${imageId} removed`));
|
|
48
46
|
} catch (err) {
|
|
49
47
|
const msg = (err && err.message) || '';
|
|
50
48
|
if (msg.includes('in use') || msg.includes('is being used')) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* Install command – run install (dependencies) inside app container (dev: running; tst: ephemeral with .env).
|
|
3
4
|
*
|
|
@@ -81,7 +82,7 @@ async function runInstallInDev(appName, developerId, installCmd) {
|
|
|
81
82
|
logger.log(chalk.blue(`Running install in container ${containerName}: ${installCmd}\n`));
|
|
82
83
|
const cmd = installCommandForReadOnlyApp(installCmd);
|
|
83
84
|
const envFilePath = await secretsEnvWrite.resolveAndWriteEnvFile(appName, {});
|
|
84
|
-
return runDockerExec(containerName, cmd, envFilePath);
|
|
85
|
+
return await runDockerExec(containerName, cmd, envFilePath);
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
/**
|
|
@@ -92,7 +93,9 @@ async function runInstallInDev(appName, developerId, installCmd) {
|
|
|
92
93
|
* @param {string|null} [envFilePath] - Path to resolved .env for --env-file (optional; when set, install has registry tokens)
|
|
93
94
|
* @returns {Promise<number>} Exit code
|
|
94
95
|
*/
|
|
95
|
-
function runDockerExec(containerName, cmd, envFilePath = null) {
|
|
96
|
+
async function runDockerExec(containerName, cmd, envFilePath = null) {
|
|
97
|
+
const { getDockerExecEnv } = require('../utils/remote-docker-env');
|
|
98
|
+
const dockerEnv = await getDockerExecEnv();
|
|
96
99
|
return new Promise((resolve) => {
|
|
97
100
|
const args = [
|
|
98
101
|
'exec',
|
|
@@ -106,7 +109,8 @@ function runDockerExec(containerName, cmd, envFilePath = null) {
|
|
|
106
109
|
args.push(containerName, 'sh', '-c', cmd);
|
|
107
110
|
const proc = spawn('docker', args, {
|
|
108
111
|
stdio: 'inherit',
|
|
109
|
-
shell: false
|
|
112
|
+
shell: false,
|
|
113
|
+
env: dockerEnv
|
|
110
114
|
});
|
|
111
115
|
proc.on('close', code => resolve(code !== null ? code : 1));
|
|
112
116
|
proc.on('error', () => resolve(1));
|
|
@@ -120,7 +124,9 @@ function runDockerExec(containerName, cmd, envFilePath = null) {
|
|
|
120
124
|
* @param {string|null} [envFilePath] - Path to .env file for --env-file (optional)
|
|
121
125
|
* @returns {Promise<number>} Exit code
|
|
122
126
|
*/
|
|
123
|
-
function runDockerRunEphemeral(fullImage, cmd, envFilePath = null) {
|
|
127
|
+
async function runDockerRunEphemeral(fullImage, cmd, envFilePath = null) {
|
|
128
|
+
const { getDockerExecEnv } = require('../utils/remote-docker-env');
|
|
129
|
+
const dockerEnv = await getDockerExecEnv();
|
|
124
130
|
return new Promise((resolve) => {
|
|
125
131
|
const args = ['run', '--rm', '-e', `TMPDIR=${TMPDIR_VALUE}`, '-e', `npm_config_store_dir=${PNPM_STORE_DIR}`, '-e', 'CI=true'];
|
|
126
132
|
if (envFilePath) {
|
|
@@ -129,7 +135,8 @@ function runDockerRunEphemeral(fullImage, cmd, envFilePath = null) {
|
|
|
129
135
|
args.push(fullImage, 'sh', '-c', cmd);
|
|
130
136
|
const proc = spawn('docker', args, {
|
|
131
137
|
stdio: 'inherit',
|
|
132
|
-
shell: false
|
|
138
|
+
shell: false,
|
|
139
|
+
env: dockerEnv
|
|
133
140
|
});
|
|
134
141
|
proc.on('close', code => resolve(code !== null ? code : 1));
|
|
135
142
|
proc.on('error', () => resolve(1));
|
|
@@ -157,7 +164,7 @@ async function runAppInstall(appName, options = {}) {
|
|
|
157
164
|
if (env === 'dev') {
|
|
158
165
|
const code = await runInstallInDev(appName, developerId, installCmd);
|
|
159
166
|
if (code !== 0) process.exit(code);
|
|
160
|
-
logger.log(
|
|
167
|
+
logger.log(formatSuccessLine('Install completed'));
|
|
161
168
|
return;
|
|
162
169
|
}
|
|
163
170
|
|
|
@@ -166,7 +173,7 @@ async function runAppInstall(appName, options = {}) {
|
|
|
166
173
|
const cmd = installCommandForReadOnlyApp(installCmd);
|
|
167
174
|
const code = await runDockerRunEphemeral(fullImage, cmd, envFilePath);
|
|
168
175
|
if (code !== 0) process.exit(code);
|
|
169
|
-
logger.log(
|
|
176
|
+
logger.log(formatSuccessLine('Install completed'));
|
|
170
177
|
}
|
|
171
178
|
|
|
172
179
|
module.exports = { runAppInstall, getInstallCommand };
|
package/lib/commands/app-logs.js
CHANGED
|
@@ -7,15 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const chalk = require('chalk');
|
|
10
|
-
const {
|
|
10
|
+
const { spawn } = require('child_process');
|
|
11
11
|
const readline = require('readline');
|
|
12
|
-
const { promisify } = require('util');
|
|
13
12
|
const logger = require('../utils/logger');
|
|
14
13
|
const config = require('../core/config');
|
|
15
14
|
const containerHelpers = require('../utils/app-run-containers');
|
|
16
15
|
const { validateAppName } = require('../app/push');
|
|
17
16
|
|
|
18
|
-
const
|
|
17
|
+
const { execWithDockerEnv } = require('../utils/docker-exec');
|
|
19
18
|
|
|
20
19
|
/** Default number of log lines */
|
|
21
20
|
const DEFAULT_TAIL_LINES = 100;
|
|
@@ -132,7 +131,7 @@ function passesLevelFilter(lineLevel, minLevel) {
|
|
|
132
131
|
*/
|
|
133
132
|
async function dumpMaskedEnv(containerName) {
|
|
134
133
|
try {
|
|
135
|
-
const { stdout } = await
|
|
134
|
+
const { stdout } = await execWithDockerEnv(`docker exec ${containerName} env`, { encoding: 'utf8', timeout: 5000 });
|
|
136
135
|
const lines = stdout.split('\n').filter((l) => l.trim());
|
|
137
136
|
if (lines.length === 0) return;
|
|
138
137
|
logger.log(chalk.bold('\n--- Environment (sensitive values masked) ---\n'));
|
|
@@ -156,6 +155,8 @@ async function dumpMaskedEnv(containerName) {
|
|
|
156
155
|
* @returns {Promise<void>}
|
|
157
156
|
*/
|
|
158
157
|
async function runDockerLogs(containerName, options) {
|
|
158
|
+
const { getDockerExecEnv } = require('../utils/remote-docker-env');
|
|
159
|
+
const dockerEnv = await getDockerExecEnv();
|
|
159
160
|
const args = options.tail === 0 ? ['logs', containerName] : ['logs', '--tail', String(options.tail), containerName];
|
|
160
161
|
const minLevel =
|
|
161
162
|
options.level !== undefined && options.level !== null && options.level !== ''
|
|
@@ -164,14 +165,14 @@ async function runDockerLogs(containerName, options) {
|
|
|
164
165
|
|
|
165
166
|
if (minLevel === null || minLevel === undefined || !LOG_LEVELS.includes(minLevel)) {
|
|
166
167
|
return new Promise((resolve, reject) => {
|
|
167
|
-
const proc = spawn('docker', args, { stdio: 'inherit' });
|
|
168
|
+
const proc = spawn('docker', args, { stdio: 'inherit', env: dockerEnv });
|
|
168
169
|
proc.on('error', reject);
|
|
169
170
|
proc.on('close', (code) => (code === 0 ? resolve() : reject(new Error(`docker logs exited with ${code}`))));
|
|
170
171
|
});
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
return new Promise((resolve, reject) => {
|
|
174
|
-
const proc = spawn('docker', args, { stdio: ['inherit', 'pipe', 'pipe'] });
|
|
175
|
+
const proc = spawn('docker', args, { stdio: ['inherit', 'pipe', 'pipe'], env: dockerEnv });
|
|
175
176
|
proc.on('error', reject);
|
|
176
177
|
|
|
177
178
|
function onLine(line) {
|
|
@@ -213,7 +214,9 @@ async function runDockerLogs(containerName, options) {
|
|
|
213
214
|
* @param {number} [tail] - Lines to show (0 = full, omit --tail)
|
|
214
215
|
* @param {string|null} [minLevel] - Minimum log level to show (debug|info|warn|error)
|
|
215
216
|
*/
|
|
216
|
-
function runDockerLogsFollow(containerName, tail, minLevel) {
|
|
217
|
+
async function runDockerLogsFollow(containerName, tail, minLevel) {
|
|
218
|
+
const { getDockerExecEnv } = require('../utils/remote-docker-env');
|
|
219
|
+
const dockerEnv = await getDockerExecEnv();
|
|
217
220
|
const args = tail === 0 ? ['logs', '-f', containerName] : ['logs', '-f', '--tail', String(tail), containerName];
|
|
218
221
|
const level =
|
|
219
222
|
minLevel !== undefined && minLevel !== null && minLevel !== ''
|
|
@@ -222,7 +225,7 @@ function runDockerLogsFollow(containerName, tail, minLevel) {
|
|
|
222
225
|
const useFilter = level !== null && level !== undefined && LOG_LEVELS.includes(level);
|
|
223
226
|
|
|
224
227
|
if (!useFilter) {
|
|
225
|
-
const proc = spawn('docker', args, { stdio: 'inherit' });
|
|
228
|
+
const proc = spawn('docker', args, { stdio: 'inherit', env: dockerEnv });
|
|
226
229
|
proc.on('error', (err) => {
|
|
227
230
|
logger.log(chalk.red(`Error: ${err.message}`));
|
|
228
231
|
process.exit(1);
|
|
@@ -233,7 +236,7 @@ function runDockerLogsFollow(containerName, tail, minLevel) {
|
|
|
233
236
|
return;
|
|
234
237
|
}
|
|
235
238
|
|
|
236
|
-
const proc = spawn('docker', args, { stdio: ['inherit', 'pipe', 'pipe'] });
|
|
239
|
+
const proc = spawn('docker', args, { stdio: ['inherit', 'pipe', 'pipe'], env: dockerEnv });
|
|
237
240
|
proc.on('error', (err) => {
|
|
238
241
|
logger.log(chalk.red(`Error: ${err.message}`));
|
|
239
242
|
process.exit(1);
|
|
@@ -286,7 +289,7 @@ async function runAppLogs(appKey, options = {}) {
|
|
|
286
289
|
}
|
|
287
290
|
|
|
288
291
|
if (follow) {
|
|
289
|
-
runDockerLogsFollow(containerName, tail, level);
|
|
292
|
+
await runDockerLogsFollow(containerName, tail, level);
|
|
290
293
|
return;
|
|
291
294
|
}
|
|
292
295
|
|
|
@@ -48,6 +48,8 @@ async function runAppShell(appName, _options = {}) {
|
|
|
48
48
|
|
|
49
49
|
logger.log(chalk.blue(`Opening shell in ${containerName} (exit with 'exit' or Ctrl+D)...\n`));
|
|
50
50
|
|
|
51
|
+
const { getDockerExecEnv } = require('../utils/remote-docker-env');
|
|
52
|
+
const dockerEnv = await getDockerExecEnv();
|
|
51
53
|
const envFilePath = await secretsEnvWrite.resolveAndWriteEnvFile(appName, {});
|
|
52
54
|
const proc = spawn('docker', [
|
|
53
55
|
'exec', '-it',
|
|
@@ -57,7 +59,8 @@ async function runAppShell(appName, _options = {}) {
|
|
|
57
59
|
'sh'
|
|
58
60
|
], {
|
|
59
61
|
stdio: 'inherit',
|
|
60
|
-
shell: false
|
|
62
|
+
shell: false,
|
|
63
|
+
env: dockerEnv
|
|
61
64
|
});
|
|
62
65
|
|
|
63
66
|
return new Promise((resolve, reject) => {
|
package/lib/commands/app-test.js
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const { spawn } = require('child_process');
|
|
10
|
-
const chalk = require('chalk');
|
|
11
10
|
const logger = require('../utils/logger');
|
|
11
|
+
const { infoLine, formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
12
12
|
const config = require('../core/config');
|
|
13
13
|
const containerHelpers = require('../utils/app-run-containers');
|
|
14
14
|
const composeGenerator = require('../utils/compose-generator');
|
|
@@ -97,9 +97,9 @@ async function runTestsInDev(appName, developerId, testCmd) {
|
|
|
97
97
|
`Container ${containerName} is not running.\nRun 'aifabrix run ${appName}' first.`
|
|
98
98
|
);
|
|
99
99
|
}
|
|
100
|
-
logger.log(
|
|
100
|
+
logger.log(infoLine(`ℹ Running tests in container ${containerName}: ${testCmd}\n`));
|
|
101
101
|
const envFilePath = await secretsEnvWrite.resolveAndWriteEnvFile(appName, {});
|
|
102
|
-
return runDockerExec(containerName, testCmd, envFilePath);
|
|
102
|
+
return await runDockerExec(containerName, testCmd, envFilePath);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
/**
|
|
@@ -123,14 +123,14 @@ async function runAppTest(appName, options = {}) {
|
|
|
123
123
|
if (env === 'dev') {
|
|
124
124
|
const code = await runTestsInDev(appName, developerId, testCmd);
|
|
125
125
|
if (code !== 0) process.exit(code);
|
|
126
|
-
logger.log(
|
|
126
|
+
logger.log(formatSuccessLine('Tests completed.'));
|
|
127
127
|
return;
|
|
128
128
|
}
|
|
129
|
-
logger.log(
|
|
129
|
+
logger.log(infoLine(`ℹ Running tests in ephemeral container (${fullImage}): ${testCmd}\n`));
|
|
130
130
|
const envFilePath = await secretsEnvWrite.resolveAndWriteEnvFile(appName, {});
|
|
131
131
|
const code = await runDockerRunEphemeral(fullImage, testCmd, envFilePath);
|
|
132
132
|
if (code !== 0) process.exit(code);
|
|
133
|
-
logger.log(
|
|
133
|
+
logger.log(formatSuccessLine('Tests completed.'));
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
/**
|
|
@@ -141,14 +141,17 @@ async function runAppTest(appName, options = {}) {
|
|
|
141
141
|
* @param {string|null} [envFilePath] - Path to resolved .env for --env-file (optional)
|
|
142
142
|
* @returns {Promise<number>} Exit code
|
|
143
143
|
*/
|
|
144
|
-
function runDockerExec(containerName, testCmd, envFilePath = null) {
|
|
144
|
+
async function runDockerExec(containerName, testCmd, envFilePath = null) {
|
|
145
|
+
const { getDockerExecEnv } = require('../utils/remote-docker-env');
|
|
146
|
+
const dockerEnv = await getDockerExecEnv();
|
|
145
147
|
return new Promise((resolve) => {
|
|
146
148
|
const args = ['exec'];
|
|
147
149
|
if (envFilePath) args.push('--env-file', envFilePath);
|
|
148
150
|
args.push(containerName, 'sh', '-c', testCmd);
|
|
149
151
|
const proc = spawn('docker', args, {
|
|
150
152
|
stdio: 'inherit',
|
|
151
|
-
shell: false
|
|
153
|
+
shell: false,
|
|
154
|
+
env: dockerEnv
|
|
152
155
|
});
|
|
153
156
|
proc.on('close', code => resolve(code !== null ? code : 1));
|
|
154
157
|
proc.on('error', () => resolve(1));
|
|
@@ -162,14 +165,17 @@ function runDockerExec(containerName, testCmd, envFilePath = null) {
|
|
|
162
165
|
* @param {string|null} [envFilePath] - Path to .env for docker run --env-file (optional)
|
|
163
166
|
* @returns {Promise<number>} Exit code
|
|
164
167
|
*/
|
|
165
|
-
function runDockerRunEphemeral(fullImage, testCmd, envFilePath = null) {
|
|
168
|
+
async function runDockerRunEphemeral(fullImage, testCmd, envFilePath = null) {
|
|
169
|
+
const { getDockerExecEnv } = require('../utils/remote-docker-env');
|
|
170
|
+
const dockerEnv = await getDockerExecEnv();
|
|
166
171
|
return new Promise((resolve) => {
|
|
167
172
|
const args = ['run', '--rm'];
|
|
168
173
|
if (envFilePath) args.push('--env-file', envFilePath);
|
|
169
174
|
args.push(fullImage, 'sh', '-c', testCmd);
|
|
170
175
|
const proc = spawn('docker', args, {
|
|
171
176
|
stdio: 'inherit',
|
|
172
|
-
shell: false
|
|
177
|
+
shell: false,
|
|
178
|
+
env: dockerEnv
|
|
173
179
|
});
|
|
174
180
|
proc.on('close', code => resolve(code !== null ? code : 1));
|
|
175
181
|
proc.on('error', () => resolve(1));
|
|
@@ -197,14 +203,14 @@ async function runAppTestE2e(appName, options = {}) {
|
|
|
197
203
|
if (env === 'dev') {
|
|
198
204
|
const code = await runTestsInDev(appName, developerId, cmd);
|
|
199
205
|
if (code !== 0) process.exit(code);
|
|
200
|
-
logger.log(
|
|
206
|
+
logger.log(formatSuccessLine('Test-e2e completed.'));
|
|
201
207
|
return;
|
|
202
208
|
}
|
|
203
|
-
logger.log(
|
|
209
|
+
logger.log(infoLine(`ℹ Running test-e2e in ephemeral container (${fullImage}): ${cmd}\n`));
|
|
204
210
|
const envFilePath = await secretsEnvWrite.resolveAndWriteEnvFile(appName, {});
|
|
205
211
|
const code = await runDockerRunEphemeral(fullImage, cmd, envFilePath);
|
|
206
212
|
if (code !== 0) process.exit(code);
|
|
207
|
-
logger.log(
|
|
213
|
+
logger.log(formatSuccessLine('Test-e2e completed.'));
|
|
208
214
|
}
|
|
209
215
|
|
|
210
216
|
/**
|
|
@@ -229,14 +235,14 @@ async function runAppTestIntegration(appName, options = {}) {
|
|
|
229
235
|
if (env === 'dev') {
|
|
230
236
|
const code = await runTestsInDev(appName, developerId, cmd);
|
|
231
237
|
if (code !== 0) process.exit(code);
|
|
232
|
-
logger.log(
|
|
238
|
+
logger.log(formatSuccessLine('Test-integration completed.'));
|
|
233
239
|
return;
|
|
234
240
|
}
|
|
235
|
-
logger.log(
|
|
241
|
+
logger.log(infoLine(`ℹ Running test-integration in ephemeral container (${fullImage}): ${cmd}\n`));
|
|
236
242
|
const envFilePath = await secretsEnvWrite.resolveAndWriteEnvFile(appName, {});
|
|
237
243
|
const code = await runDockerRunEphemeral(fullImage, cmd, envFilePath);
|
|
238
244
|
if (code !== 0) process.exit(code);
|
|
239
|
-
logger.log(
|
|
245
|
+
logger.log(formatSuccessLine('Test-integration completed.'));
|
|
240
246
|
}
|
|
241
247
|
|
|
242
248
|
/**
|
|
@@ -260,14 +266,14 @@ async function runAppLint(appName, options = {}) {
|
|
|
260
266
|
if (env === 'dev') {
|
|
261
267
|
const code = await runTestsInDev(appName, developerId, cmd);
|
|
262
268
|
if (code !== 0) process.exit(code);
|
|
263
|
-
logger.log(
|
|
269
|
+
logger.log(formatSuccessLine('Lint completed.'));
|
|
264
270
|
return;
|
|
265
271
|
}
|
|
266
|
-
logger.log(
|
|
272
|
+
logger.log(infoLine(`ℹ Running lint in ephemeral container (${fullImage}): ${cmd}\n`));
|
|
267
273
|
const envFilePath = await secretsEnvWrite.resolveAndWriteEnvFile(appName, {});
|
|
268
274
|
const code = await runDockerRunEphemeral(fullImage, cmd, envFilePath);
|
|
269
275
|
if (code !== 0) process.exit(code);
|
|
270
|
-
logger.log(
|
|
276
|
+
logger.log(formatSuccessLine('Lint completed.'));
|
|
271
277
|
}
|
|
272
278
|
|
|
273
279
|
module.exports = {
|