@aifabrix/builder 2.43.0 → 2.44.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/.cursor/rules/anchor-docs.mdc +15 -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 +288 -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 +0 -1
- package/lib/api/pipeline.api.js +67 -20
- 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 +99 -0
- package/lib/api/validation-runner.js +99 -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 +1 -1
- package/lib/app/show.js +1 -1
- package/lib/build/index.js +13 -10
- package/lib/cli/index.js +2 -0
- package/lib/cli/setup-app.help.js +67 -0
- package/lib/cli/setup-app.js +57 -121
- package/lib/cli/setup-app.test-commands.js +179 -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 +62 -22
- package/lib/cli/setup-infra.js +126 -47
- package/lib/cli/setup-parameters.js +32 -0
- package/lib/cli/setup-secrets.js +106 -8
- package/lib/cli/setup-service-user.js +1 -1
- package/lib/cli/setup-utility.js +36 -20
- 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 +22 -10
- 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 +495 -0
- package/lib/commands/datasource-unified-test-cli.options.js +149 -0
- package/lib/commands/datasource-validation-cli.js +129 -0
- package/lib/commands/datasource.js +105 -98
- 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 +138 -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 +84 -53
- package/lib/datasource/resolve-app.js +4 -4
- package/lib/datasource/test-e2e.js +95 -146
- package/lib/datasource/test-integration.js +114 -122
- package/lib/datasource/unified-validation-run-body.js +65 -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 +92 -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 +131 -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 +60 -6
- package/lib/infrastructure/helpers.js +201 -29
- package/lib/infrastructure/index.js +28 -17
- package/lib/infrastructure/services.js +21 -15
- 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 +181 -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 +213 -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 +49 -14
- 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/controller-deployment-outcome.js +68 -0
- package/lib/utils/credential-display.js +2 -2
- 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-debug-display.js +137 -0
- package/lib/utils/datasource-test-run-debug-slice.js +93 -0
- package/lib/utils/datasource-test-run-display.js +442 -0
- package/lib/utils/datasource-test-run-exit.js +58 -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 +234 -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-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 +134 -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 +89 -0
- package/lib/utils/validation-run-post-retry.js +73 -0
- package/lib/utils/validation-run-request.js +98 -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.js +4 -13
- 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 +7 -3
- package/scripts/check-datasource-test-run-schema-sync.js +34 -0
- package/scripts/diagnose-cli.js +150 -0
- package/scripts/install-local.js +304 -55
- package/templates/README.md +15 -2
- package/templates/applications/dataplane/application.yaml +52 -2
- package/templates/applications/dataplane/env.template +75 -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 +20 -4
- 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/app/run-helpers.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessLine, formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* AI Fabrix Builder - App Run Helpers
|
|
3
4
|
*
|
|
@@ -13,24 +14,20 @@ const fs = require('fs').promises;
|
|
|
13
14
|
const fsSync = require('fs');
|
|
14
15
|
const path = require('path');
|
|
15
16
|
const chalk = require('chalk');
|
|
16
|
-
const { exec } = require('child_process');
|
|
17
17
|
const { loadConfigFile } = require('../utils/config-format');
|
|
18
|
-
const { promisify } = require('util');
|
|
19
18
|
const validator = require('../validation/validator');
|
|
20
19
|
const config = require('../core/config');
|
|
21
20
|
const buildCopy = require('../utils/build-copy');
|
|
22
21
|
const logger = require('../utils/logger');
|
|
23
|
-
const { waitForHealthCheck } = require('../utils/health-check');
|
|
24
22
|
const composeGenerator = require('../utils/compose-generator');
|
|
25
|
-
const dockerUtils = require('../utils/docker');
|
|
26
23
|
const containerHelpers = require('../utils/app-run-containers');
|
|
27
24
|
const pathsUtil = require('../utils/paths');
|
|
28
25
|
const runEnvCompose = require('./run-env-compose');
|
|
26
|
+
const { getAppInfraRequirements } = require('./run-infra-requirements');
|
|
27
|
+
const { resolveRunImage } = require('./run-resolve-image');
|
|
28
|
+
const { startContainer } = require('./run-container-start');
|
|
29
29
|
const { resolveEnvOutputPath, writeEnvOutputForReload, writeEnvOutputForLocal } = require('../utils/env-copy');
|
|
30
30
|
const { resolveVersionForApp } = require('../utils/image-version');
|
|
31
|
-
const { parseImageOverride } = require('../utils/parse-image-ref');
|
|
32
|
-
|
|
33
|
-
const execAsync = promisify(exec);
|
|
34
31
|
|
|
35
32
|
/** Template apps (keycloak, miso-controller, dataplane) - never update application config when running */
|
|
36
33
|
const TEMPLATE_APP_KEYS = ['keycloak', 'miso-controller', 'dataplane'];
|
|
@@ -123,6 +120,9 @@ async function validateAppConfiguration(appName) {
|
|
|
123
120
|
throw new Error('Application name is required');
|
|
124
121
|
}
|
|
125
122
|
|
|
123
|
+
const { assertRemoteBuilderDeveloperId } = require('../utils/remote-builder-validation');
|
|
124
|
+
assertRemoteBuilderDeveloperId(await config.getRemoteServer(), await config.getDeveloperId());
|
|
125
|
+
|
|
126
126
|
// Check if running from builder directory
|
|
127
127
|
checkBuilderDirectory(appName);
|
|
128
128
|
|
|
@@ -161,28 +161,6 @@ async function resolveAndUpdateVersion(appName, appConfig, debug) {
|
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
/**
|
|
165
|
-
* Resolve image name and tag from app config and optional run override.
|
|
166
|
-
* @param {string} appName - Application name
|
|
167
|
-
* @param {Object} appConfig - Application configuration
|
|
168
|
-
* @param {Object} runOptions - Run options; runOptions.image overrides config
|
|
169
|
-
* @returns {{ imageName: string, imageTag: string }} imageName and imageTag
|
|
170
|
-
*/
|
|
171
|
-
function resolveRunImage(appName, appConfig, runOptions) {
|
|
172
|
-
const imageOverride = runOptions && runOptions.image;
|
|
173
|
-
if (imageOverride) {
|
|
174
|
-
const parsed = parseImageOverride(imageOverride);
|
|
175
|
-
return {
|
|
176
|
-
imageName: parsed ? parsed.name : composeGenerator.getImageName(appConfig, appName),
|
|
177
|
-
imageTag: parsed ? parsed.tag : (appConfig.image && appConfig.image.tag) || 'latest'
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
return {
|
|
181
|
-
imageName: composeGenerator.getImageName(appConfig, appName),
|
|
182
|
-
imageTag: (appConfig.image && appConfig.image.tag) || 'latest'
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
|
|
186
164
|
/**
|
|
187
165
|
* Checks prerequisites: Docker image and (optionally) infrastructure
|
|
188
166
|
* @async
|
|
@@ -210,12 +188,12 @@ async function checkPrerequisites(appName, appConfig, debug = false, skipInfraCh
|
|
|
210
188
|
: `Run 'aifabrix build ${appName}' first`;
|
|
211
189
|
throw new Error(`Docker image ${fullImageName} not found\n${hint}`);
|
|
212
190
|
}
|
|
213
|
-
logger.log(
|
|
191
|
+
logger.log(formatSuccessLine(`Image ${fullImageName} found`));
|
|
214
192
|
|
|
215
193
|
await resolveAndUpdateVersion(appName, appConfig, debug);
|
|
216
194
|
|
|
217
195
|
if (!skipInfraCheck) {
|
|
218
|
-
await checkInfraHealthOrThrow(debug);
|
|
196
|
+
await checkInfraHealthOrThrow(debug, appConfig);
|
|
219
197
|
}
|
|
220
198
|
}
|
|
221
199
|
|
|
@@ -223,12 +201,28 @@ async function checkPrerequisites(appName, appConfig, debug = false, skipInfraCh
|
|
|
223
201
|
* Checks infrastructure health and throws if unhealthy
|
|
224
202
|
* @async
|
|
225
203
|
* @param {boolean} debug - Enable debug logging
|
|
204
|
+
* @param {Object} [appConfig] - Application configuration (for selective infra checks)
|
|
226
205
|
* @throws {Error} If infrastructure is not healthy
|
|
227
206
|
*/
|
|
228
|
-
async function checkInfraHealthOrThrow(debug) {
|
|
207
|
+
async function checkInfraHealthOrThrow(debug, appConfig) {
|
|
208
|
+
const requirements = getAppInfraRequirements(appConfig);
|
|
209
|
+
if (requirements && !requirements.needsPostgres && !requirements.needsRedis) {
|
|
210
|
+
logger.log(
|
|
211
|
+
chalk.blue('Skipping infrastructure check (application does not require database or redis)...')
|
|
212
|
+
);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
229
216
|
logger.log(chalk.blue('Checking infrastructure health...'));
|
|
230
217
|
const infra = require('../infrastructure');
|
|
231
|
-
const
|
|
218
|
+
const healthOptions =
|
|
219
|
+
requirements === null
|
|
220
|
+
? {}
|
|
221
|
+
: {
|
|
222
|
+
postgres: requirements.needsPostgres,
|
|
223
|
+
redis: requirements.needsRedis
|
|
224
|
+
};
|
|
225
|
+
const infraHealth = await infra.checkInfraHealth(null, healthOptions);
|
|
232
226
|
if (debug) {
|
|
233
227
|
logger.log(chalk.gray(`[DEBUG] Infrastructure health: ${JSON.stringify(infraHealth, null, 2)}`));
|
|
234
228
|
}
|
|
@@ -239,7 +233,7 @@ async function checkInfraHealthOrThrow(debug) {
|
|
|
239
233
|
if (unhealthyServices.length > 0) {
|
|
240
234
|
throw new Error(`Infrastructure services not healthy: ${unhealthyServices.join(', ')}\nRun 'aifabrix up-infra' first`);
|
|
241
235
|
}
|
|
242
|
-
logger.log(
|
|
236
|
+
logger.log(formatSuccessLine('Infrastructure is running'));
|
|
243
237
|
}
|
|
244
238
|
|
|
245
239
|
/**
|
|
@@ -334,15 +328,31 @@ async function writeEnvOutputIfConfigured(appName, appConfig, runEnvPath, option
|
|
|
334
328
|
async function prepareEnvironment(appName, appConfig, options) {
|
|
335
329
|
const developerId = await config.getDeveloperId();
|
|
336
330
|
const devDir = await ensureDevDirectory(appName, developerId);
|
|
331
|
+
const runEnvKey = (options.env || 'dev').toLowerCase();
|
|
332
|
+
const userCfg = await config.getConfig();
|
|
333
|
+
const { computeEffectiveEnvironmentScopedResources } = require('../utils/environment-scoped-resources');
|
|
334
|
+
const effectiveEnvironmentScopedResources = computeEffectiveEnvironmentScopedResources(
|
|
335
|
+
Boolean(userCfg.useEnvironmentScopedResources),
|
|
336
|
+
appConfig.environmentScopedResources === true,
|
|
337
|
+
runEnvKey
|
|
338
|
+
);
|
|
337
339
|
|
|
338
340
|
runEnvCompose.cleanApplicationsDir(developerId);
|
|
339
341
|
logger.log(chalk.blue('Building merged .env (admin + app secrets)...'));
|
|
340
|
-
const { runEnvPath, runEnvAdminPath } = await runEnvCompose.buildMergedRunEnvAndWrite(
|
|
342
|
+
const { runEnvPath, runEnvAdminPath } = await runEnvCompose.buildMergedRunEnvAndWrite(
|
|
343
|
+
appName,
|
|
344
|
+
appConfig,
|
|
345
|
+
devDir,
|
|
346
|
+
developerId,
|
|
347
|
+
{ runEnvKey, effectiveEnvironmentScopedResources }
|
|
348
|
+
);
|
|
341
349
|
|
|
342
350
|
const composeOptions = {
|
|
343
351
|
...options,
|
|
344
352
|
envFilePath: runEnvPath,
|
|
345
|
-
dbInitEnvFilePath: runEnvAdminPath
|
|
353
|
+
dbInitEnvFilePath: runEnvAdminPath,
|
|
354
|
+
effectiveEnvironmentScopedResources,
|
|
355
|
+
env: runEnvKey
|
|
346
356
|
};
|
|
347
357
|
composeOptions.port = calculateComposePort(composeOptions, appConfig, developerId);
|
|
348
358
|
const composePath = await generateComposeFile(appName, appConfig, composeOptions, devDir);
|
|
@@ -352,105 +362,18 @@ async function prepareEnvironment(appName, appConfig, options) {
|
|
|
352
362
|
return { composePath, runEnvPath, runEnvAdminPath };
|
|
353
363
|
}
|
|
354
364
|
|
|
355
|
-
/**
|
|
356
|
-
* Prepare environment variables for docker compose (no secrets in host env; compose uses env_file).
|
|
357
|
-
* @async
|
|
358
|
-
* @param {boolean} debug - Enable debug logging
|
|
359
|
-
* @returns {Promise<Object>} Environment variables object for child process
|
|
360
|
-
*/
|
|
361
|
-
async function prepareContainerEnv(debug) {
|
|
362
|
-
const env = { ...process.env };
|
|
363
|
-
|
|
364
|
-
if (typeof process.getuid === 'function' && typeof process.getgid === 'function') {
|
|
365
|
-
env.AIFABRIX_UID = String(process.getuid());
|
|
366
|
-
env.AIFABRIX_GID = String(process.getgid());
|
|
367
|
-
} else {
|
|
368
|
-
env.AIFABRIX_UID = '1000';
|
|
369
|
-
env.AIFABRIX_GID = '1000';
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
const { getRemoteDockerEnv } = require('../utils/remote-docker-env');
|
|
373
|
-
const remoteDocker = await getRemoteDockerEnv();
|
|
374
|
-
Object.assign(env, remoteDocker);
|
|
375
|
-
|
|
376
|
-
if (debug) {
|
|
377
|
-
logger.log(chalk.gray('[DEBUG] Container env prepared (secrets via env_file)'));
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
return env;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
/**
|
|
384
|
-
* Execute docker-compose up command. Services get env from env_file in the compose (e.g. .env.run).
|
|
385
|
-
* @async
|
|
386
|
-
* @param {string} composeCmdBase - Base compose command
|
|
387
|
-
* @param {string} composePath - Path to compose file
|
|
388
|
-
* @param {Object} env - Environment variables for the child process
|
|
389
|
-
* @param {boolean} debug - Enable debug logging
|
|
390
|
-
*/
|
|
391
|
-
async function executeComposeUp(composeCmdBase, composePath, env, debug) {
|
|
392
|
-
const composeCmd = `${composeCmdBase} -f "${composePath}" up -d`;
|
|
393
|
-
if (debug) {
|
|
394
|
-
logger.log(chalk.gray(`[DEBUG] Executing: ${composeCmd}`));
|
|
395
|
-
logger.log(chalk.gray(`[DEBUG] Compose file: ${composePath}`));
|
|
396
|
-
}
|
|
397
|
-
await execAsync(composeCmd, { env });
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
/**
|
|
401
|
-
* Starts the container and waits for health check. Deletes run .env files after success (ISO 27K).
|
|
402
|
-
* @async
|
|
403
|
-
* @param {string} appName - Application name
|
|
404
|
-
* @param {string} composePath - Path to Docker Compose file
|
|
405
|
-
* @param {number} port - Application port
|
|
406
|
-
* @param {Object} appConfig - Application configuration
|
|
407
|
-
* @param {Object} [opts] - Options
|
|
408
|
-
* @param {boolean} [opts.debug=false] - Enable debug logging
|
|
409
|
-
* @param {string|null} [opts.runEnvPath=null] - Path to .env.run (app-only) to delete after successful start
|
|
410
|
-
* @param {string|null} [opts.runEnvAdminPath=null] - Path to .env.run.admin (start-only) to delete after successful start
|
|
411
|
-
* @throws {Error} If container fails to start or become healthy
|
|
412
|
-
*/
|
|
413
|
-
async function startContainer(appName, composePath, port, appConfig = null, opts = {}) {
|
|
414
|
-
const { debug = false, runEnvPath = null, runEnvAdminPath = null } = opts;
|
|
415
|
-
logger.log(chalk.blue(`Starting ${appName}...`));
|
|
416
|
-
|
|
417
|
-
const composeCmdBase = await dockerUtils.ensureDockerAndCompose().then(() => dockerUtils.getComposeCommand());
|
|
418
|
-
const env = await prepareContainerEnv(debug);
|
|
419
|
-
await executeComposeUp(composeCmdBase, composePath, env, debug);
|
|
420
|
-
|
|
421
|
-
const idNum = typeof appConfig.developerId === 'string' ? parseInt(appConfig.developerId, 10) : appConfig.developerId;
|
|
422
|
-
const containerName = idNum === 0 ? `aifabrix-${appName}` : `aifabrix-dev${appConfig.developerId}-${appName}`;
|
|
423
|
-
logger.log(chalk.green(`✓ Container ${containerName} started`));
|
|
424
|
-
await containerHelpers.logContainerStatus(containerName, debug);
|
|
425
|
-
|
|
426
|
-
const healthCheckPath = appConfig?.healthCheck?.path || '/health';
|
|
427
|
-
logger.log(chalk.blue(`Waiting for application to be healthy at http://localhost:${port}${healthCheckPath}...`));
|
|
428
|
-
await waitForHealthCheck(appName, 90, port, appConfig, debug);
|
|
429
|
-
|
|
430
|
-
for (const p of [runEnvPath, runEnvAdminPath]) {
|
|
431
|
-
if (p && typeof p === 'string') {
|
|
432
|
-
try {
|
|
433
|
-
await fs.unlink(p);
|
|
434
|
-
} catch (err) {
|
|
435
|
-
if (err.code !== 'ENOENT') logger.log(chalk.yellow(`Warning: could not remove run .env: ${err.message}`));
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
|
|
441
365
|
/**
|
|
442
366
|
* Displays run status after successful start
|
|
443
367
|
* @param {string} appName - Application name
|
|
444
368
|
* @param {number} port - Application port
|
|
445
369
|
* @param {Object} appConfig - Application configuration (with developerId property)
|
|
446
370
|
*/
|
|
447
|
-
async function displayRunStatus(appName, port, appConfig) {
|
|
448
|
-
const
|
|
449
|
-
const containerName = idNum === 0 ? `aifabrix-${appName}` : `aifabrix-dev${appConfig.developerId}-${appName}`;
|
|
371
|
+
async function displayRunStatus(appName, port, appConfig, runScopeOpts = null) {
|
|
372
|
+
const containerName = containerHelpers.getContainerName(appName, appConfig.developerId, runScopeOpts);
|
|
450
373
|
const healthCheckPath = appConfig?.healthCheck?.path || '/health';
|
|
451
374
|
const healthCheckUrl = `http://localhost:${port}${healthCheckPath}`;
|
|
452
375
|
|
|
453
|
-
logger.log(
|
|
376
|
+
logger.log(formatSuccessParagraph(`App running at http://localhost:${port}`));
|
|
454
377
|
logger.log(chalk.blue(`Health check: ${healthCheckUrl}`));
|
|
455
378
|
logger.log(chalk.gray(`Container: ${containerName}`));
|
|
456
379
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derives local infra (Postgres/Redis) needs from application.yaml for `run`.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Shared by infra health skip and docker-run-without-compose fallback
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 2.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Reads application.yaml `requires` to decide which local infra services apply.
|
|
13
|
+
* Missing `requires` → null (legacy: assume Postgres + Redis may be required).
|
|
14
|
+
*
|
|
15
|
+
* @param {Object} appConfig - Application configuration from application.yaml
|
|
16
|
+
* @returns {null|{ needsPostgres: boolean, needsRedis: boolean }}
|
|
17
|
+
*/
|
|
18
|
+
function getAppInfraRequirements(appConfig) {
|
|
19
|
+
const r = appConfig && appConfig.requires;
|
|
20
|
+
if (!r || typeof r !== 'object') {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const needsPostgres =
|
|
24
|
+
r.database === true ||
|
|
25
|
+
(Array.isArray(r.databases) && r.databases.length > 0);
|
|
26
|
+
const needsRedis = r.redis === true;
|
|
27
|
+
return { needsPostgres, needsRedis };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = { getAppInfraRequirements };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve Docker image name/tag for run (config + optional --image / --registry overrides).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Shared by checkPrerequisites and container start / docker run fallback
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { resolveDockerImageRef } = require('../utils/resolve-docker-image-ref');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {string} appName
|
|
13
|
+
* @param {Object} appConfig
|
|
14
|
+
* @param {Object} runOptions - runOptions.image / runOptions.registry override config
|
|
15
|
+
* @returns {{ imageName: string, imageTag: string }}
|
|
16
|
+
*/
|
|
17
|
+
function resolveRunImage(appName, appConfig, runOptions) {
|
|
18
|
+
return resolveDockerImageRef(appName, appConfig, runOptions);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = { resolveRunImage };
|
package/lib/app/run.js
CHANGED
|
@@ -10,8 +10,6 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
const chalk = require('chalk');
|
|
13
|
-
const { exec } = require('child_process');
|
|
14
|
-
const { promisify } = require('util');
|
|
15
13
|
const config = require('../core/config');
|
|
16
14
|
const logger = require('../utils/logger');
|
|
17
15
|
const pathsUtil = require('../utils/paths');
|
|
@@ -21,8 +19,7 @@ const containerHelpers = require('../utils/app-run-containers');
|
|
|
21
19
|
const mutagen = require('../utils/mutagen');
|
|
22
20
|
// Helper functions extracted to reduce file size and complexity
|
|
23
21
|
const helpers = require('./run-helpers');
|
|
24
|
-
|
|
25
|
-
const execAsync = promisify(exec);
|
|
22
|
+
const { execWithDockerEnv } = require('../utils/docker-exec');
|
|
26
23
|
|
|
27
24
|
/**
|
|
28
25
|
* True if host is localhost or 127.0.0.1 (case-insensitive).
|
|
@@ -76,7 +73,7 @@ async function validateAppForRun(appName, _debug) {
|
|
|
76
73
|
try {
|
|
77
74
|
const { isExternal, baseDir } = await detectAppType(appName);
|
|
78
75
|
if (baseDir !== 'builder' || isExternal) {
|
|
79
|
-
logger.log(chalk.yellow('
|
|
76
|
+
logger.log(chalk.yellow('⚠ External systems don\'t run as Docker containers.'));
|
|
80
77
|
logger.log(chalk.blue('Use "aifabrix build" to deploy to dataplane, then test via OpenAPI endpoints.'));
|
|
81
78
|
return false;
|
|
82
79
|
}
|
|
@@ -98,17 +95,27 @@ async function validateAppForRun(appName, _debug) {
|
|
|
98
95
|
* @param {boolean} debug - Debug flag
|
|
99
96
|
* @returns {Promise<void>}
|
|
100
97
|
*/
|
|
101
|
-
async function checkAndStopContainer(appName,
|
|
102
|
-
const
|
|
98
|
+
async function checkAndStopContainer(appName, appConfig, options, debug) {
|
|
99
|
+
const developerId = appConfig.developerId;
|
|
100
|
+
const runEnvKey = (options.env || 'dev').toLowerCase();
|
|
101
|
+
const userCfg = await config.getConfig();
|
|
102
|
+
const { computeEffectiveEnvironmentScopedResources } = require('../utils/environment-scoped-resources');
|
|
103
|
+
const effectiveEnvironmentScopedResources = computeEffectiveEnvironmentScopedResources(
|
|
104
|
+
Boolean(userCfg.useEnvironmentScopedResources),
|
|
105
|
+
appConfig.environmentScopedResources === true,
|
|
106
|
+
runEnvKey
|
|
107
|
+
);
|
|
108
|
+
const scopeOpts = effectiveEnvironmentScopedResources
|
|
109
|
+
? { effectiveEnvironmentScopedResources: true, env: runEnvKey }
|
|
110
|
+
: null;
|
|
111
|
+
const containerRunning = await helpers.checkContainerRunning(appName, developerId, debug, scopeOpts);
|
|
103
112
|
if (!containerRunning) {
|
|
104
113
|
return;
|
|
105
114
|
}
|
|
106
115
|
|
|
107
|
-
|
|
108
|
-
const idNum = typeof developerId === 'string' ? parseInt(developerId, 10) : developerId;
|
|
109
|
-
const containerName = idNum === 0 ? `aifabrix-${appName}` : `aifabrix-dev${developerId}-${appName}`;
|
|
116
|
+
const containerName = containerHelpers.getContainerName(appName, developerId, scopeOpts);
|
|
110
117
|
logger.log(chalk.yellow(`Container ${containerName} is already running`));
|
|
111
|
-
await helpers.stopAndRemoveContainer(appName, developerId, debug);
|
|
118
|
+
await helpers.stopAndRemoveContainer(appName, developerId, debug, scopeOpts);
|
|
112
119
|
}
|
|
113
120
|
|
|
114
121
|
/**
|
|
@@ -214,10 +221,24 @@ async function loadAndConfigureApp(appName, debug) {
|
|
|
214
221
|
* @throws {Error} If container start fails
|
|
215
222
|
*/
|
|
216
223
|
async function startAppContainer(appName, tempComposePath, hostPort, appConfig, opts) {
|
|
217
|
-
const {
|
|
224
|
+
const {
|
|
225
|
+
debug,
|
|
226
|
+
runEnvPath = null,
|
|
227
|
+
runEnvAdminPath = null,
|
|
228
|
+
runOptions = {},
|
|
229
|
+
devMountPath = null
|
|
230
|
+
} = opts;
|
|
231
|
+
const misoEnvironment = opts.misoEnvironment ?? composeGenerator.resolveMisoEnvironment(runOptions);
|
|
218
232
|
try {
|
|
219
|
-
await helpers.startContainer(appName, tempComposePath, hostPort, appConfig, {
|
|
220
|
-
|
|
233
|
+
await helpers.startContainer(appName, tempComposePath, hostPort, appConfig, {
|
|
234
|
+
debug,
|
|
235
|
+
runEnvPath,
|
|
236
|
+
runEnvAdminPath,
|
|
237
|
+
runOptions,
|
|
238
|
+
devMountPath,
|
|
239
|
+
misoEnvironment
|
|
240
|
+
});
|
|
241
|
+
await helpers.displayRunStatus(appName, hostPort, appConfig, opts.runScopeOpts || null);
|
|
221
242
|
} catch (error) {
|
|
222
243
|
logger.log(chalk.yellow(`\n⚠️ Compose file preserved at: ${tempComposePath}`));
|
|
223
244
|
logger.log(chalk.yellow(' Review the file to debug issues'));
|
|
@@ -240,8 +261,12 @@ async function startAppContainer(appName, tempComposePath, hostPort, appConfig,
|
|
|
240
261
|
* @param {boolean} debug - Debug flag
|
|
241
262
|
* @returns {Promise<Object>} Run options with optional devMountPath
|
|
242
263
|
*/
|
|
243
|
-
async function resolveRunOptions(appName, appConfig, options, envKey, debug) {
|
|
244
|
-
const runOptions = {
|
|
264
|
+
async function resolveRunOptions(appName, appConfig, options, envKey, debug, effectiveEnvironmentScopedResources) {
|
|
265
|
+
const runOptions = {
|
|
266
|
+
...options,
|
|
267
|
+
env: envKey,
|
|
268
|
+
effectiveEnvironmentScopedResources: Boolean(effectiveEnvironmentScopedResources)
|
|
269
|
+
};
|
|
245
270
|
const builderPath = pathsUtil.getBuilderPath(appName);
|
|
246
271
|
const codePath = pathsUtil.resolveBuildContext(builderPath, appConfig.build?.context || '.');
|
|
247
272
|
if (options.reload && envKey === 'dev') {
|
|
@@ -269,12 +294,37 @@ async function prepareAppRun(appName, options, debug) {
|
|
|
269
294
|
return null;
|
|
270
295
|
}
|
|
271
296
|
const appConfig = await loadAndConfigureApp(appName, debug);
|
|
297
|
+
const userCfg = await config.getConfig();
|
|
298
|
+
const { computeEffectiveEnvironmentScopedResources } = require('../utils/environment-scoped-resources');
|
|
299
|
+
const effectiveEnvironmentScopedResources = computeEffectiveEnvironmentScopedResources(
|
|
300
|
+
Boolean(userCfg.useEnvironmentScopedResources),
|
|
301
|
+
appConfig.environmentScopedResources === true,
|
|
302
|
+
envKey
|
|
303
|
+
);
|
|
304
|
+
const runScopeOpts = effectiveEnvironmentScopedResources
|
|
305
|
+
? { effectiveEnvironmentScopedResources: true, env: envKey }
|
|
306
|
+
: null;
|
|
272
307
|
await helpers.checkPrerequisites(appName, appConfig, debug, options.skipInfraCheck === true, options);
|
|
273
|
-
await checkAndStopContainer(appName, appConfig
|
|
308
|
+
await checkAndStopContainer(appName, appConfig, options, debug);
|
|
274
309
|
const hostPort = await calculateHostPort(appConfig, options, debug);
|
|
275
|
-
const runOptions = await resolveRunOptions(
|
|
310
|
+
const runOptions = await resolveRunOptions(
|
|
311
|
+
appName,
|
|
312
|
+
appConfig,
|
|
313
|
+
options,
|
|
314
|
+
envKey,
|
|
315
|
+
debug,
|
|
316
|
+
effectiveEnvironmentScopedResources
|
|
317
|
+
);
|
|
276
318
|
const { composePath: tempComposePath, runEnvPath, runEnvAdminPath } = await helpers.prepareEnvironment(appName, appConfig, runOptions);
|
|
277
|
-
const result = {
|
|
319
|
+
const result = {
|
|
320
|
+
appConfig,
|
|
321
|
+
tempComposePath,
|
|
322
|
+
hostPort,
|
|
323
|
+
runEnvPath,
|
|
324
|
+
runEnvAdminPath,
|
|
325
|
+
runScopeOpts,
|
|
326
|
+
mergedRunOptions: runOptions
|
|
327
|
+
};
|
|
278
328
|
if (runOptions.devMountPath) result.devMountPath = runOptions.devMountPath;
|
|
279
329
|
return result;
|
|
280
330
|
}
|
|
@@ -317,7 +367,10 @@ async function runApp(appName, options = {}) {
|
|
|
317
367
|
await startAppContainer(appName, prepared.tempComposePath, prepared.hostPort, prepared.appConfig, {
|
|
318
368
|
debug,
|
|
319
369
|
runEnvPath: prepared.runEnvPath,
|
|
320
|
-
runEnvAdminPath: prepared.runEnvAdminPath
|
|
370
|
+
runEnvAdminPath: prepared.runEnvAdminPath,
|
|
371
|
+
runOptions: prepared.mergedRunOptions,
|
|
372
|
+
devMountPath: prepared.devMountPath,
|
|
373
|
+
runScopeOpts: prepared.runScopeOpts
|
|
321
374
|
});
|
|
322
375
|
} catch (error) {
|
|
323
376
|
if (debug) {
|
|
@@ -347,7 +400,7 @@ async function restartApp(appName) {
|
|
|
347
400
|
const developerId = await config.getDeveloperId();
|
|
348
401
|
const containerName = containerHelpers.getContainerName(appName, developerId);
|
|
349
402
|
try {
|
|
350
|
-
await
|
|
403
|
+
await execWithDockerEnv(`docker restart ${containerName}`);
|
|
351
404
|
} catch (error) {
|
|
352
405
|
const msg = (error.stderr || error.stdout || error.message || '').toLowerCase();
|
|
353
406
|
if (msg.includes('no such container') || msg.includes('is not running')) {
|
package/lib/app/show-display.js
CHANGED
|
@@ -81,7 +81,7 @@ function logApplicationExternalIntegration(ei, options = {}) {
|
|
|
81
81
|
logger.log(` systems: [${(ei.systems || []).join(', ')}]`);
|
|
82
82
|
logger.log(` dataSources: [${(ei.dataSources || []).join(', ')}]`);
|
|
83
83
|
if (!options.skipHint) {
|
|
84
|
-
logger.log(chalk.gray('\n For external system data as on dataplane, run: aifabrix show <
|
|
84
|
+
logger.log(chalk.gray('\n For external system data as on dataplane, run: aifabrix show <app> --online or aifabrix app show <app>.'));
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
package/lib/app/show.js
CHANGED
|
@@ -440,7 +440,7 @@ function formatBuildForDisplay(build) {
|
|
|
440
440
|
if (!build) return '—';
|
|
441
441
|
const parts = [];
|
|
442
442
|
if (build.language) parts.push(build.language);
|
|
443
|
-
const port = build.port
|
|
443
|
+
const port = build.port;
|
|
444
444
|
if (port !== undefined && port !== null) parts.push(`port ${port}`);
|
|
445
445
|
if (build.dockerfile) parts.push('dockerfile');
|
|
446
446
|
if (build.envOutputPath) parts.push(`envOutputPath: ${build.envOutputPath}`);
|
package/lib/build/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessLine, formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* AI Fabrix Builder Build Functions
|
|
3
4
|
*
|
|
@@ -127,7 +128,9 @@ async function generateDockerfile(appNameOrPath, language, config, buildConfig =
|
|
|
127
128
|
|
|
128
129
|
const template = dockerfileUtils.loadDockerfileTemplate(language);
|
|
129
130
|
const isAppFlag = buildConfig.context === '../..';
|
|
130
|
-
|
|
131
|
+
// Use "./" (not ".") so Dockerfile lines are "COPY ./requirements*.txt" — a bare "."
|
|
132
|
+
// concatenates with "requirements" and becomes ".requirements*.txt", which matches nothing.
|
|
133
|
+
const appSourcePath = isAppFlag ? `apps/${appName}/` : './';
|
|
131
134
|
|
|
132
135
|
const templateVars = {
|
|
133
136
|
port: config.port || 3000,
|
|
@@ -185,11 +188,11 @@ async function generateDockerfile(appNameOrPath, language, config, buildConfig =
|
|
|
185
188
|
async function postBuildTasks(appName, buildConfig) {
|
|
186
189
|
try {
|
|
187
190
|
const envPath = await secrets.generateEnvFile(appName, buildConfig.secrets, 'docker');
|
|
188
|
-
logger.log(
|
|
191
|
+
logger.log(formatSuccessLine(`Generated .env file: ${envPath}`));
|
|
189
192
|
// Note: processEnvVariables is already called by generateEnvFile to generate local .env
|
|
190
193
|
// at the envOutputPath, so we don't need to manually copy the docker .env file
|
|
191
194
|
} catch (error) {
|
|
192
|
-
logger.log(chalk.yellow(
|
|
195
|
+
logger.log(chalk.yellow(`⚠ Warning: Could not generate .env file: ${error.message}`));
|
|
193
196
|
}
|
|
194
197
|
}
|
|
195
198
|
|
|
@@ -229,7 +232,7 @@ async function copyApplicationSourceFiles(appName, devDir) {
|
|
|
229
232
|
const appsPath = path.join(process.cwd(), 'apps', appName);
|
|
230
233
|
if (fsSync.existsSync(appsPath)) {
|
|
231
234
|
await buildCopy.copyAppSourceFiles(appsPath, devDir);
|
|
232
|
-
logger.log(
|
|
235
|
+
logger.log(formatSuccessLine(`Copied application source files from apps/${appName}`));
|
|
233
236
|
return true;
|
|
234
237
|
}
|
|
235
238
|
return false;
|
|
@@ -253,12 +256,12 @@ async function copyTemplateFilesIfNeeded(devDir, language, buildConfig, options)
|
|
|
253
256
|
const projectRoot = getProjectRoot();
|
|
254
257
|
const templatePath = path.join(projectRoot, 'templates', 'typescript');
|
|
255
258
|
await buildCopy.copyTemplateFilesToDevDir(templatePath, devDir, detectedLanguage);
|
|
256
|
-
logger.log(
|
|
259
|
+
logger.log(formatSuccessLine(`Generated application files from ${detectedLanguage} template`));
|
|
257
260
|
} else if (detectedLanguage === 'python' && !fsSync.existsSync(requirementsPath)) {
|
|
258
261
|
const projectRoot = getProjectRoot();
|
|
259
262
|
const templatePath = path.join(projectRoot, 'templates', 'python');
|
|
260
263
|
await buildCopy.copyTemplateFilesToDevDir(templatePath, devDir, detectedLanguage);
|
|
261
|
-
logger.log(
|
|
264
|
+
logger.log(formatSuccessLine(`Generated application files from ${detectedLanguage} template`));
|
|
262
265
|
}
|
|
263
266
|
}
|
|
264
267
|
|
|
@@ -268,7 +271,7 @@ async function prepareDevDirectory(appName, buildConfig, options) {
|
|
|
268
271
|
const directoryName = idNum === 0 ? 'applications' : `dev-${developerId}`;
|
|
269
272
|
logger.log(chalk.blue(`Copying files to developer-specific directory (${directoryName})...`));
|
|
270
273
|
const devDir = await buildCopy.copyBuilderToDevDirectory(appName, developerId);
|
|
271
|
-
logger.log(
|
|
274
|
+
logger.log(formatSuccessLine(`Files copied to: ${devDir}`));
|
|
272
275
|
|
|
273
276
|
const { config: appConfig, imageName } = await buildHelpers.loadAndValidateConfig(appName);
|
|
274
277
|
const effectiveImageName = buildDevImageName(imageName, developerId);
|
|
@@ -294,7 +297,7 @@ function prepareBuildContext(buildConfig, devDir) {
|
|
|
294
297
|
// Check if context is using old format (../appName) - these are incompatible with dev directory structure
|
|
295
298
|
if (buildConfig.context && buildConfig.context.startsWith('../') && buildConfig.context !== '../..') {
|
|
296
299
|
// Old format detected - always use devDir instead
|
|
297
|
-
logger.log(chalk.yellow(
|
|
300
|
+
logger.log(chalk.yellow(`⚠ Warning: Build context uses old format: ${buildConfig.context}`));
|
|
298
301
|
logger.log(chalk.yellow(` Using dev directory instead: ${devDir}`));
|
|
299
302
|
contextPath = devDir;
|
|
300
303
|
} else if (buildConfig.context && buildConfig.context !== '../..') {
|
|
@@ -353,7 +356,7 @@ async function handleDockerfileGeneration(appName, params, options, buildHelpers
|
|
|
353
356
|
language = 'typescript';
|
|
354
357
|
}
|
|
355
358
|
if (!hasExistingDockerfile) {
|
|
356
|
-
logger.log(
|
|
359
|
+
logger.log(formatSuccessLine(`Detected language: ${language}`));
|
|
357
360
|
}
|
|
358
361
|
|
|
359
362
|
// Determine Dockerfile (needs context path to generate in correct location)
|
|
@@ -425,7 +428,7 @@ async function buildApp(appName, options = {}) {
|
|
|
425
428
|
// 7. Post-build tasks
|
|
426
429
|
await postBuildTasks(appName, buildConfig);
|
|
427
430
|
|
|
428
|
-
logger.log(
|
|
431
|
+
logger.log(formatSuccessParagraph('Build completed successfully!'));
|
|
429
432
|
return `${imageName}:${tag}`;
|
|
430
433
|
|
|
431
434
|
} catch (error) {
|
package/lib/cli/index.js
CHANGED
|
@@ -17,6 +17,7 @@ const { setupEnvironmentCommands } = require('./setup-environment');
|
|
|
17
17
|
const { setupUtilityCommands } = require('./setup-utility');
|
|
18
18
|
const { setupDevCommands } = require('./setup-dev');
|
|
19
19
|
const { setupSecretsCommands } = require('./setup-secrets');
|
|
20
|
+
const { setupParametersCommands } = require('./setup-parameters');
|
|
20
21
|
const { setupExternalSystemCommands } = require('./setup-external-system');
|
|
21
22
|
const { setupAppCommands: setupAppManagementCommands } = require('../commands/app');
|
|
22
23
|
const { setupDatasourceCommands } = require('../commands/datasource');
|
|
@@ -40,6 +41,7 @@ function setupCommands(program) {
|
|
|
40
41
|
setupExternalSystemCommands(program);
|
|
41
42
|
setupDevCommands(program);
|
|
42
43
|
setupSecretsCommands(program);
|
|
44
|
+
setupParametersCommands(program);
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
module.exports = {
|