@factiii/stack 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +420 -0
- package/bin/factiii +229 -0
- package/dist/cli/check-config.d.ts +9 -0
- package/dist/cli/check-config.d.ts.map +1 -0
- package/dist/cli/check-config.js +19 -0
- package/dist/cli/check-config.js.map +1 -0
- package/dist/cli/deploy-secrets.d.ts +16 -0
- package/dist/cli/deploy-secrets.d.ts.map +1 -0
- package/dist/cli/deploy-secrets.js +227 -0
- package/dist/cli/deploy-secrets.js.map +1 -0
- package/dist/cli/deploy.d.ts +30 -0
- package/dist/cli/deploy.d.ts.map +1 -0
- package/dist/cli/deploy.js +306 -0
- package/dist/cli/deploy.js.map +1 -0
- package/dist/cli/deployer.d.ts +13 -0
- package/dist/cli/deployer.d.ts.map +1 -0
- package/dist/cli/deployer.js +21 -0
- package/dist/cli/deployer.js.map +1 -0
- package/dist/cli/dev-sync.d.ts +30 -0
- package/dist/cli/dev-sync.d.ts.map +1 -0
- package/dist/cli/dev-sync.js +500 -0
- package/dist/cli/dev-sync.js.map +1 -0
- package/dist/cli/execute-plugin-command.d.ts +25 -0
- package/dist/cli/execute-plugin-command.d.ts.map +1 -0
- package/dist/cli/execute-plugin-command.js +237 -0
- package/dist/cli/execute-plugin-command.js.map +1 -0
- package/dist/cli/fix.d.ts +22 -0
- package/dist/cli/fix.d.ts.map +1 -0
- package/dist/cli/fix.js +267 -0
- package/dist/cli/fix.js.map +1 -0
- package/dist/cli/index.d.ts +17 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +31 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +9 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +190 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/plugin-commands.d.ts +22 -0
- package/dist/cli/plugin-commands.d.ts.map +1 -0
- package/dist/cli/plugin-commands.js +121 -0
- package/dist/cli/plugin-commands.js.map +1 -0
- package/dist/cli/scan.d.ts +66 -0
- package/dist/cli/scan.d.ts.map +1 -0
- package/dist/cli/scan.js +511 -0
- package/dist/cli/scan.js.map +1 -0
- package/dist/cli/secrets.d.ts +19 -0
- package/dist/cli/secrets.d.ts.map +1 -0
- package/dist/cli/secrets.js +318 -0
- package/dist/cli/secrets.js.map +1 -0
- package/dist/cli/undeploy.d.ts +9 -0
- package/dist/cli/undeploy.d.ts.map +1 -0
- package/dist/cli/undeploy.js +95 -0
- package/dist/cli/undeploy.js.map +1 -0
- package/dist/cli/upgrade.d.ts +9 -0
- package/dist/cli/upgrade.d.ts.map +1 -0
- package/dist/cli/upgrade.js +24 -0
- package/dist/cli/upgrade.js.map +1 -0
- package/dist/cli/validate.d.ts +9 -0
- package/dist/cli/validate.d.ts.map +1 -0
- package/dist/cli/validate.js +20 -0
- package/dist/cli/validate.js.map +1 -0
- package/dist/generators/generate-factiii-auto.d.ts +31 -0
- package/dist/generators/generate-factiii-auto.d.ts.map +1 -0
- package/dist/generators/generate-factiii-auto.js +251 -0
- package/dist/generators/generate-factiii-auto.js.map +1 -0
- package/dist/generators/generate-factiii-yml.d.ts +23 -0
- package/dist/generators/generate-factiii-yml.d.ts.map +1 -0
- package/dist/generators/generate-factiii-yml.js +228 -0
- package/dist/generators/generate-factiii-yml.js.map +1 -0
- package/dist/generators/index.d.ts +8 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +14 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +90 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/addons/server-mode/index.d.ts +57 -0
- package/dist/plugins/addons/server-mode/index.d.ts.map +1 -0
- package/dist/plugins/addons/server-mode/index.js +136 -0
- package/dist/plugins/addons/server-mode/index.js.map +1 -0
- package/dist/plugins/addons/server-mode/scanfix/mac.d.ts +17 -0
- package/dist/plugins/addons/server-mode/scanfix/mac.d.ts.map +1 -0
- package/dist/plugins/addons/server-mode/scanfix/mac.js +461 -0
- package/dist/plugins/addons/server-mode/scanfix/mac.js.map +1 -0
- package/dist/plugins/addons/server-mode/scanfix/ubuntu.d.ts +12 -0
- package/dist/plugins/addons/server-mode/scanfix/ubuntu.d.ts.map +1 -0
- package/dist/plugins/addons/server-mode/scanfix/ubuntu.js +246 -0
- package/dist/plugins/addons/server-mode/scanfix/ubuntu.js.map +1 -0
- package/dist/plugins/addons/server-mode/scanfix/windows.d.ts +14 -0
- package/dist/plugins/addons/server-mode/scanfix/windows.d.ts.map +1 -0
- package/dist/plugins/addons/server-mode/scanfix/windows.js +113 -0
- package/dist/plugins/addons/server-mode/scanfix/windows.js.map +1 -0
- package/dist/plugins/approved.json +13 -0
- package/dist/plugins/frameworks/prisma-trpc/index.d.ts +65 -0
- package/dist/plugins/frameworks/prisma-trpc/index.d.ts.map +1 -0
- package/dist/plugins/frameworks/prisma-trpc/index.js +668 -0
- package/dist/plugins/frameworks/prisma-trpc/index.js.map +1 -0
- package/dist/plugins/index.d.ts +101 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +411 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/interfaces/addon.d.ts +43 -0
- package/dist/plugins/interfaces/addon.d.ts.map +1 -0
- package/dist/plugins/interfaces/addon.js +53 -0
- package/dist/plugins/interfaces/addon.js.map +1 -0
- package/dist/plugins/interfaces/framework.d.ts +43 -0
- package/dist/plugins/interfaces/framework.d.ts.map +1 -0
- package/dist/plugins/interfaces/framework.js +53 -0
- package/dist/plugins/interfaces/framework.js.map +1 -0
- package/dist/plugins/interfaces/index.d.ts +10 -0
- package/dist/plugins/interfaces/index.d.ts.map +1 -0
- package/dist/plugins/interfaces/index.js +17 -0
- package/dist/plugins/interfaces/index.js.map +1 -0
- package/dist/plugins/interfaces/pipeline.d.ts +78 -0
- package/dist/plugins/interfaces/pipeline.d.ts.map +1 -0
- package/dist/plugins/interfaces/pipeline.js +82 -0
- package/dist/plugins/interfaces/pipeline.js.map +1 -0
- package/dist/plugins/interfaces/server.d.ts +65 -0
- package/dist/plugins/interfaces/server.d.ts.map +1 -0
- package/dist/plugins/interfaces/server.js +72 -0
- package/dist/plugins/interfaces/server.js.map +1 -0
- package/dist/plugins/pipelines/aws/configs/ec2.d.ts +9 -0
- package/dist/plugins/pipelines/aws/configs/ec2.d.ts.map +1 -0
- package/dist/plugins/pipelines/aws/configs/ec2.js +34 -0
- package/dist/plugins/pipelines/aws/configs/ec2.js.map +1 -0
- package/dist/plugins/pipelines/aws/configs/free-tier.d.ts +13 -0
- package/dist/plugins/pipelines/aws/configs/free-tier.d.ts.map +1 -0
- package/dist/plugins/pipelines/aws/configs/free-tier.js +86 -0
- package/dist/plugins/pipelines/aws/configs/free-tier.js.map +1 -0
- package/dist/plugins/pipelines/aws/configs/index.d.ts +14 -0
- package/dist/plugins/pipelines/aws/configs/index.d.ts.map +1 -0
- package/dist/plugins/pipelines/aws/configs/index.js +21 -0
- package/dist/plugins/pipelines/aws/configs/index.js.map +1 -0
- package/dist/plugins/pipelines/aws/configs/types.d.ts +36 -0
- package/dist/plugins/pipelines/aws/configs/types.d.ts.map +1 -0
- package/dist/plugins/pipelines/aws/configs/types.js +9 -0
- package/dist/plugins/pipelines/aws/configs/types.js.map +1 -0
- package/dist/plugins/pipelines/aws/dev.d.ts +10 -0
- package/dist/plugins/pipelines/aws/dev.d.ts.map +1 -0
- package/dist/plugins/pipelines/aws/dev.js +70 -0
- package/dist/plugins/pipelines/aws/dev.js.map +1 -0
- package/dist/plugins/pipelines/aws/index.d.ts +118 -0
- package/dist/plugins/pipelines/aws/index.d.ts.map +1 -0
- package/dist/plugins/pipelines/aws/index.js +346 -0
- package/dist/plugins/pipelines/aws/index.js.map +1 -0
- package/dist/plugins/pipelines/aws/prod.d.ts +19 -0
- package/dist/plugins/pipelines/aws/prod.d.ts.map +1 -0
- package/dist/plugins/pipelines/aws/prod.js +362 -0
- package/dist/plugins/pipelines/aws/prod.js.map +1 -0
- package/dist/plugins/pipelines/aws/scanfix/aws-cli.d.ts +7 -0
- package/dist/plugins/pipelines/aws/scanfix/aws-cli.d.ts.map +1 -0
- package/dist/plugins/pipelines/aws/scanfix/aws-cli.js +31 -0
- package/dist/plugins/pipelines/aws/scanfix/aws-cli.js.map +1 -0
- package/dist/plugins/pipelines/aws/scanfix/config.d.ts +7 -0
- package/dist/plugins/pipelines/aws/scanfix/config.d.ts.map +1 -0
- package/dist/plugins/pipelines/aws/scanfix/config.js +134 -0
- package/dist/plugins/pipelines/aws/scanfix/config.js.map +1 -0
- package/dist/plugins/pipelines/factiii/github-secrets-store.d.ts +65 -0
- package/dist/plugins/pipelines/factiii/github-secrets-store.d.ts.map +1 -0
- package/dist/plugins/pipelines/factiii/github-secrets-store.js +221 -0
- package/dist/plugins/pipelines/factiii/github-secrets-store.js.map +1 -0
- package/dist/plugins/pipelines/factiii/index.d.ts +195 -0
- package/dist/plugins/pipelines/factiii/index.d.ts.map +1 -0
- package/dist/plugins/pipelines/factiii/index.js +862 -0
- package/dist/plugins/pipelines/factiii/index.js.map +1 -0
- package/dist/plugins/pipelines/factiii/prod.d.ts +17 -0
- package/dist/plugins/pipelines/factiii/prod.d.ts.map +1 -0
- package/dist/plugins/pipelines/factiii/prod.js +282 -0
- package/dist/plugins/pipelines/factiii/prod.js.map +1 -0
- package/dist/plugins/pipelines/factiii/scanfix/config.d.ts +7 -0
- package/dist/plugins/pipelines/factiii/scanfix/config.d.ts.map +1 -0
- package/dist/plugins/pipelines/factiii/scanfix/config.js +80 -0
- package/dist/plugins/pipelines/factiii/scanfix/config.js.map +1 -0
- package/dist/plugins/pipelines/factiii/scanfix/github-cli.d.ts +7 -0
- package/dist/plugins/pipelines/factiii/scanfix/github-cli.d.ts.map +1 -0
- package/dist/plugins/pipelines/factiii/scanfix/github-cli.js +43 -0
- package/dist/plugins/pipelines/factiii/scanfix/github-cli.js.map +1 -0
- package/dist/plugins/pipelines/factiii/scanfix/secrets.d.ts +7 -0
- package/dist/plugins/pipelines/factiii/scanfix/secrets.d.ts.map +1 -0
- package/dist/plugins/pipelines/factiii/scanfix/secrets.js +237 -0
- package/dist/plugins/pipelines/factiii/scanfix/secrets.js.map +1 -0
- package/dist/plugins/pipelines/factiii/scanfix/workflows.d.ts +7 -0
- package/dist/plugins/pipelines/factiii/scanfix/workflows.d.ts.map +1 -0
- package/dist/plugins/pipelines/factiii/scanfix/workflows.js +169 -0
- package/dist/plugins/pipelines/factiii/scanfix/workflows.js.map +1 -0
- package/dist/plugins/pipelines/factiii/staging.d.ts +25 -0
- package/dist/plugins/pipelines/factiii/staging.d.ts.map +1 -0
- package/dist/plugins/pipelines/factiii/staging.js +223 -0
- package/dist/plugins/pipelines/factiii/staging.js.map +1 -0
- package/dist/plugins/pipelines/factiii/utils/detection.d.ts +36 -0
- package/dist/plugins/pipelines/factiii/utils/detection.d.ts.map +1 -0
- package/dist/plugins/pipelines/factiii/utils/detection.js +140 -0
- package/dist/plugins/pipelines/factiii/utils/detection.js.map +1 -0
- package/dist/plugins/pipelines/factiii/utils/workflows.d.ts +16 -0
- package/dist/plugins/pipelines/factiii/utils/workflows.d.ts.map +1 -0
- package/dist/plugins/pipelines/factiii/utils/workflows.js +129 -0
- package/dist/plugins/pipelines/factiii/utils/workflows.js.map +1 -0
- package/dist/plugins/pipelines/factiii/workflows/factiii-cicd-prod.yml +112 -0
- package/dist/plugins/pipelines/factiii/workflows/factiii-cicd-staging.yml +112 -0
- package/dist/plugins/pipelines/factiii/workflows/factiii-command.yml +130 -0
- package/dist/plugins/pipelines/factiii/workflows/factiii-deploy.yml +198 -0
- package/dist/plugins/pipelines/factiii/workflows/factiii-dev-sync.yml +179 -0
- package/dist/plugins/pipelines/factiii/workflows/factiii-fix.yml +176 -0
- package/dist/plugins/pipelines/factiii/workflows/factiii-scan.yml +176 -0
- package/dist/plugins/pipelines/factiii/workflows/factiii-undeploy.yml +95 -0
- package/dist/plugins/servers/amazon-linux/index.d.ts +93 -0
- package/dist/plugins/servers/amazon-linux/index.d.ts.map +1 -0
- package/dist/plugins/servers/amazon-linux/index.js +217 -0
- package/dist/plugins/servers/amazon-linux/index.js.map +1 -0
- package/dist/plugins/servers/mac/dev.d.ts +10 -0
- package/dist/plugins/servers/mac/dev.d.ts.map +1 -0
- package/dist/plugins/servers/mac/dev.js +71 -0
- package/dist/plugins/servers/mac/dev.js.map +1 -0
- package/dist/plugins/servers/mac/index.d.ts +101 -0
- package/dist/plugins/servers/mac/index.d.ts.map +1 -0
- package/dist/plugins/servers/mac/index.js +257 -0
- package/dist/plugins/servers/mac/index.js.map +1 -0
- package/dist/plugins/servers/mac/scanfix/config.d.ts +7 -0
- package/dist/plugins/servers/mac/scanfix/config.d.ts.map +1 -0
- package/dist/plugins/servers/mac/scanfix/config.js +168 -0
- package/dist/plugins/servers/mac/scanfix/config.js.map +1 -0
- package/dist/plugins/servers/mac/scanfix/containers.d.ts +7 -0
- package/dist/plugins/servers/mac/scanfix/containers.d.ts.map +1 -0
- package/dist/plugins/servers/mac/scanfix/containers.js +167 -0
- package/dist/plugins/servers/mac/scanfix/containers.js.map +1 -0
- package/dist/plugins/servers/mac/scanfix/system.d.ts +7 -0
- package/dist/plugins/servers/mac/scanfix/system.d.ts.map +1 -0
- package/dist/plugins/servers/mac/scanfix/system.js +144 -0
- package/dist/plugins/servers/mac/scanfix/system.js.map +1 -0
- package/dist/plugins/servers/mac/staging.d.ts +21 -0
- package/dist/plugins/servers/mac/staging.d.ts.map +1 -0
- package/dist/plugins/servers/mac/staging.js +708 -0
- package/dist/plugins/servers/mac/staging.js.map +1 -0
- package/dist/plugins/servers/ubuntu/index.d.ts +93 -0
- package/dist/plugins/servers/ubuntu/index.d.ts.map +1 -0
- package/dist/plugins/servers/ubuntu/index.js +224 -0
- package/dist/plugins/servers/ubuntu/index.js.map +1 -0
- package/dist/plugins/servers/windows/index.d.ts +90 -0
- package/dist/plugins/servers/windows/index.d.ts.map +1 -0
- package/dist/plugins/servers/windows/index.js +205 -0
- package/dist/plugins/servers/windows/index.js.map +1 -0
- package/dist/scanfix/commands/index.d.ts +27 -0
- package/dist/scanfix/commands/index.d.ts.map +1 -0
- package/dist/scanfix/commands/index.js +97 -0
- package/dist/scanfix/commands/index.js.map +1 -0
- package/dist/scanfix/commands/mac.d.ts +11 -0
- package/dist/scanfix/commands/mac.d.ts.map +1 -0
- package/dist/scanfix/commands/mac.js +31 -0
- package/dist/scanfix/commands/mac.js.map +1 -0
- package/dist/scanfix/commands/ubuntu.d.ts +11 -0
- package/dist/scanfix/commands/ubuntu.d.ts.map +1 -0
- package/dist/scanfix/commands/ubuntu.js +30 -0
- package/dist/scanfix/commands/ubuntu.js.map +1 -0
- package/dist/scanfix/fixes/certbot.d.ts +25 -0
- package/dist/scanfix/fixes/certbot.d.ts.map +1 -0
- package/dist/scanfix/fixes/certbot.js +136 -0
- package/dist/scanfix/fixes/certbot.js.map +1 -0
- package/dist/scanfix/fixes/docker.d.ts +29 -0
- package/dist/scanfix/fixes/docker.d.ts.map +1 -0
- package/dist/scanfix/fixes/docker.js +149 -0
- package/dist/scanfix/fixes/docker.js.map +1 -0
- package/dist/scanfix/fixes/git.d.ts +20 -0
- package/dist/scanfix/fixes/git.d.ts.map +1 -0
- package/dist/scanfix/fixes/git.js +71 -0
- package/dist/scanfix/fixes/git.js.map +1 -0
- package/dist/scanfix/fixes/index.d.ts +11 -0
- package/dist/scanfix/fixes/index.d.ts.map +1 -0
- package/dist/scanfix/fixes/index.js +27 -0
- package/dist/scanfix/fixes/index.js.map +1 -0
- package/dist/scanfix/fixes/node.d.ts +20 -0
- package/dist/scanfix/fixes/node.d.ts.map +1 -0
- package/dist/scanfix/fixes/node.js +71 -0
- package/dist/scanfix/fixes/node.js.map +1 -0
- package/dist/scanfix/fixes/pnpm.d.ts +20 -0
- package/dist/scanfix/fixes/pnpm.d.ts.map +1 -0
- package/dist/scanfix/fixes/pnpm.js +122 -0
- package/dist/scanfix/fixes/pnpm.js.map +1 -0
- package/dist/scanfix/index.d.ts +23 -0
- package/dist/scanfix/index.d.ts.map +1 -0
- package/dist/scanfix/index.js +44 -0
- package/dist/scanfix/index.js.map +1 -0
- package/dist/scanfix/platform.d.ts +20 -0
- package/dist/scanfix/platform.d.ts.map +1 -0
- package/dist/scanfix/platform.js +48 -0
- package/dist/scanfix/platform.js.map +1 -0
- package/dist/scanfix/ssl-cert-helper.d.ts +27 -0
- package/dist/scanfix/ssl-cert-helper.d.ts.map +1 -0
- package/dist/scanfix/ssl-cert-helper.js +117 -0
- package/dist/scanfix/ssl-cert-helper.js.map +1 -0
- package/dist/scanfix/types.d.ts +27 -0
- package/dist/scanfix/types.d.ts.map +1 -0
- package/dist/scanfix/types.js +8 -0
- package/dist/scanfix/types.js.map +1 -0
- package/dist/scripts/check-existing-secrets.d.ts +6 -0
- package/dist/scripts/check-existing-secrets.d.ts.map +1 -0
- package/dist/scripts/check-existing-secrets.js +86 -0
- package/dist/scripts/check-existing-secrets.js.map +1 -0
- package/dist/scripts/generate-all.d.ts +40 -0
- package/dist/scripts/generate-all.d.ts.map +1 -0
- package/dist/scripts/generate-all.js +373 -0
- package/dist/scripts/generate-all.js.map +1 -0
- package/dist/scripts/get-repo-name.d.ts +6 -0
- package/dist/scripts/get-repo-name.d.ts.map +1 -0
- package/dist/scripts/get-repo-name.js +54 -0
- package/dist/scripts/get-repo-name.js.map +1 -0
- package/dist/scripts/index.d.ts +7 -0
- package/dist/scripts/index.d.ts.map +1 -0
- package/dist/scripts/index.js +14 -0
- package/dist/scripts/index.js.map +1 -0
- package/dist/scripts/validate-env-files.d.ts +6 -0
- package/dist/scripts/validate-env-files.d.ts.map +1 -0
- package/dist/scripts/validate-env-files.js +126 -0
- package/dist/scripts/validate-env-files.js.map +1 -0
- package/dist/scripts/validate-example-values.d.ts +8 -0
- package/dist/scripts/validate-example-values.d.ts.map +1 -0
- package/dist/scripts/validate-example-values.js +88 -0
- package/dist/scripts/validate-example-values.js.map +1 -0
- package/dist/scripts/validate-factiii-yml.d.ts +6 -0
- package/dist/scripts/validate-factiii-yml.d.ts.map +1 -0
- package/dist/scripts/validate-factiii-yml.js +71 -0
- package/dist/scripts/validate-factiii-yml.js.map +1 -0
- package/dist/types/cli.d.ts +138 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/cli.js +8 -0
- package/dist/types/cli.js.map +1 -0
- package/dist/types/config.d.ts +113 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +8 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +25 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/plugin.d.ts +352 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/plugin.js +8 -0
- package/dist/types/plugin.js.map +1 -0
- package/dist/utils/ansible-vault-secrets.d.ts +95 -0
- package/dist/utils/ansible-vault-secrets.d.ts.map +1 -0
- package/dist/utils/ansible-vault-secrets.js +406 -0
- package/dist/utils/ansible-vault-secrets.js.map +1 -0
- package/dist/utils/config-helpers.d.ts +72 -0
- package/dist/utils/config-helpers.d.ts.map +1 -0
- package/dist/utils/config-helpers.js +171 -0
- package/dist/utils/config-helpers.js.map +1 -0
- package/dist/utils/config-schema.d.ts +17 -0
- package/dist/utils/config-schema.d.ts.map +1 -0
- package/dist/utils/config-schema.js +100 -0
- package/dist/utils/config-schema.js.map +1 -0
- package/dist/utils/config-validator.d.ts +29 -0
- package/dist/utils/config-validator.d.ts.map +1 -0
- package/dist/utils/config-validator.js +146 -0
- package/dist/utils/config-validator.js.map +1 -0
- package/dist/utils/deployment-report.d.ts +100 -0
- package/dist/utils/deployment-report.d.ts.map +1 -0
- package/dist/utils/deployment-report.js +225 -0
- package/dist/utils/deployment-report.js.map +1 -0
- package/dist/utils/dns-validator.d.ts +19 -0
- package/dist/utils/dns-validator.d.ts.map +1 -0
- package/dist/utils/dns-validator.js +94 -0
- package/dist/utils/dns-validator.js.map +1 -0
- package/dist/utils/env-validator.d.ts +108 -0
- package/dist/utils/env-validator.d.ts.map +1 -0
- package/dist/utils/env-validator.js +342 -0
- package/dist/utils/env-validator.js.map +1 -0
- package/dist/utils/github-workflow-monitor.d.ts +49 -0
- package/dist/utils/github-workflow-monitor.d.ts.map +1 -0
- package/dist/utils/github-workflow-monitor.js +145 -0
- package/dist/utils/github-workflow-monitor.js.map +1 -0
- package/dist/utils/index.d.ts +18 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +48 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/secret-prompts.d.ts +67 -0
- package/dist/utils/secret-prompts.d.ts.map +1 -0
- package/dist/utils/secret-prompts.js +369 -0
- package/dist/utils/secret-prompts.js.map +1 -0
- package/dist/utils/server-check.d.ts +43 -0
- package/dist/utils/server-check.d.ts.map +1 -0
- package/dist/utils/server-check.js +397 -0
- package/dist/utils/server-check.js.map +1 -0
- package/dist/utils/ssh-deploy.d.ts +70 -0
- package/dist/utils/ssh-deploy.d.ts.map +1 -0
- package/dist/utils/ssh-deploy.js +268 -0
- package/dist/utils/ssh-deploy.js.map +1 -0
- package/dist/utils/ssh-helper.d.ts +40 -0
- package/dist/utils/ssh-helper.d.ts.map +1 -0
- package/dist/utils/ssh-helper.js +221 -0
- package/dist/utils/ssh-helper.js.map +1 -0
- package/dist/utils/template-generator.d.ts +42 -0
- package/dist/utils/template-generator.d.ts.map +1 -0
- package/dist/utils/template-generator.js +223 -0
- package/dist/utils/template-generator.js.map +1 -0
- package/dist/utils/version-check.d.ts +69 -0
- package/dist/utils/version-check.d.ts.map +1 -0
- package/dist/utils/version-check.js +211 -0
- package/dist/utils/version-check.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,862 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Factiii Pipeline Plugin
|
|
4
|
+
*
|
|
5
|
+
* The default pipeline plugin for Factiii Stack.
|
|
6
|
+
* Uses GitHub Actions for CI/CD with thin workflows that SSH to servers
|
|
7
|
+
* and call the Factiii CLI to do the actual work.
|
|
8
|
+
*
|
|
9
|
+
* ============================================================
|
|
10
|
+
* PLUGIN STRUCTURE STANDARD
|
|
11
|
+
* ============================================================
|
|
12
|
+
*
|
|
13
|
+
* This plugin follows a standardized structure for clarity and maintainability:
|
|
14
|
+
*
|
|
15
|
+
* **scanfix/** - Scan/fix operations organized by concern
|
|
16
|
+
* - Each file exports an array of Fix[] objects
|
|
17
|
+
* - Files group related fixes together (config, github-cli, workflows, secrets)
|
|
18
|
+
* - All fixes are combined in the main plugin class
|
|
19
|
+
*
|
|
20
|
+
* **utils/** - Utility methods
|
|
21
|
+
* - detection.ts - Config detection methods (package manager, Node.js version, etc.)
|
|
22
|
+
* - workflows.ts - Workflow generation and triggering
|
|
23
|
+
*
|
|
24
|
+
* **index.ts** - Main plugin class
|
|
25
|
+
* - Static metadata (id, name, category, version)
|
|
26
|
+
* - shouldLoad() - Determines if plugin should load
|
|
27
|
+
* - canReach() - Determines how to reach each stage (critical routing method)
|
|
28
|
+
* - Imports and combines all scanfix arrays
|
|
29
|
+
* - Imports and uses utility methods
|
|
30
|
+
* - Core pipeline logic: deployStage(), runLocalDeploy()
|
|
31
|
+
* - Maintains public API compatibility
|
|
32
|
+
*
|
|
33
|
+
* **Key Differences from Server Plugins:**
|
|
34
|
+
* - Environment-specific files (staging.ts, prod.ts) are in plugin root - standard pattern
|
|
35
|
+
* - Core routing logic stays in index.ts - canReach() and deployStage() are the main entry points
|
|
36
|
+
* - Utils folder for static helpers - Detection and workflow generation are utilities, not core logic
|
|
37
|
+
* - scanfix organized by concern, not environment - Fixes are grouped by what they check (config, workflows, secrets)
|
|
38
|
+
*
|
|
39
|
+
* **When each scanfix file is used:**
|
|
40
|
+
* - config.ts: When checking/generating factiii.yml
|
|
41
|
+
* - github-cli.ts: When checking GitHub CLI installation (dev)
|
|
42
|
+
* - workflows.ts: When checking/generating GitHub workflows (dev)
|
|
43
|
+
* - secrets.ts: When checking GitHub Secrets (secrets stage)
|
|
44
|
+
* ============================================================
|
|
45
|
+
*/
|
|
46
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
47
|
+
if (k2 === undefined) k2 = k;
|
|
48
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
49
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
50
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
51
|
+
}
|
|
52
|
+
Object.defineProperty(o, k2, desc);
|
|
53
|
+
}) : (function(o, m, k, k2) {
|
|
54
|
+
if (k2 === undefined) k2 = k;
|
|
55
|
+
o[k2] = m[k];
|
|
56
|
+
}));
|
|
57
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
58
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
59
|
+
}) : function(o, v) {
|
|
60
|
+
o["default"] = v;
|
|
61
|
+
});
|
|
62
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
63
|
+
var ownKeys = function(o) {
|
|
64
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
65
|
+
var ar = [];
|
|
66
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
67
|
+
return ar;
|
|
68
|
+
};
|
|
69
|
+
return ownKeys(o);
|
|
70
|
+
};
|
|
71
|
+
return function (mod) {
|
|
72
|
+
if (mod && mod.__esModule) return mod;
|
|
73
|
+
var result = {};
|
|
74
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
75
|
+
__setModuleDefault(result, mod);
|
|
76
|
+
return result;
|
|
77
|
+
};
|
|
78
|
+
})();
|
|
79
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
80
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
81
|
+
};
|
|
82
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
83
|
+
const fs = __importStar(require("fs"));
|
|
84
|
+
const path = __importStar(require("path"));
|
|
85
|
+
const child_process_1 = require("child_process");
|
|
86
|
+
const index_js_1 = require("../../index.js");
|
|
87
|
+
const github_workflow_monitor_js_1 = __importDefault(require("../../../utils/github-workflow-monitor.js"));
|
|
88
|
+
const github_secrets_store_js_1 = require("./github-secrets-store.js");
|
|
89
|
+
const ssh_helper_js_1 = require("../../../utils/ssh-helper.js");
|
|
90
|
+
// Import scanfix arrays
|
|
91
|
+
const config_js_1 = require("./scanfix/config.js");
|
|
92
|
+
const github_cli_js_1 = require("./scanfix/github-cli.js");
|
|
93
|
+
const workflows_js_1 = require("./scanfix/workflows.js");
|
|
94
|
+
const secrets_js_1 = require("./scanfix/secrets.js");
|
|
95
|
+
// Import utility methods
|
|
96
|
+
const detectionUtils = __importStar(require("./utils/detection.js"));
|
|
97
|
+
const workflowUtils = __importStar(require("./utils/workflows.js"));
|
|
98
|
+
const stagingUtils = __importStar(require("./staging.js"));
|
|
99
|
+
const prodUtils = __importStar(require("./prod.js"));
|
|
100
|
+
class FactiiiPipeline {
|
|
101
|
+
// ============================================================
|
|
102
|
+
// STATIC METADATA
|
|
103
|
+
// ============================================================
|
|
104
|
+
static id = 'factiii';
|
|
105
|
+
static name = 'Factiii Pipeline';
|
|
106
|
+
static category = 'pipeline';
|
|
107
|
+
static version = '1.0.0';
|
|
108
|
+
// Env vars this plugin requires (none - pipeline doesn't need app env vars)
|
|
109
|
+
static requiredEnvVars = [];
|
|
110
|
+
// Schema for factiii.yml (user-editable)
|
|
111
|
+
static configSchema = {
|
|
112
|
+
// No user config - workflows are auto-generated
|
|
113
|
+
};
|
|
114
|
+
// Schema for factiiiAuto.yml (auto-detected)
|
|
115
|
+
static autoConfigSchema = {
|
|
116
|
+
package_manager: 'string',
|
|
117
|
+
node_version: 'string',
|
|
118
|
+
pnpm_version: 'string',
|
|
119
|
+
dockerfile: 'string',
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Determine if this plugin should be loaded for this project
|
|
123
|
+
* Pipeline plugin always loads - it's the default CI/CD system
|
|
124
|
+
*/
|
|
125
|
+
static async shouldLoad(_rootDir, _config) {
|
|
126
|
+
return true; // Always load - this is the default pipeline
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Whether this environment requires the full repo cloned on the server
|
|
130
|
+
*/
|
|
131
|
+
static requiresFullRepo(environment) {
|
|
132
|
+
// Staging: needs full repo for local building from source
|
|
133
|
+
// Prod: pulls pre-built images from ECR, only needs factiii.yml + env file
|
|
134
|
+
return environment === 'staging';
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Check if this pipeline can reach a specific stage
|
|
138
|
+
*
|
|
139
|
+
* ============================================================
|
|
140
|
+
* PIPELINE AUTHORS: This method controls stage reachability
|
|
141
|
+
* ============================================================
|
|
142
|
+
*
|
|
143
|
+
* Return values:
|
|
144
|
+
* { reachable: true, via: 'local' } - Run fixes on this machine
|
|
145
|
+
* { reachable: true, via: 'ssh' } - SSH directly to the server
|
|
146
|
+
* { reachable: true, via: 'workflow' } - Trigger workflow to run fixes
|
|
147
|
+
* { reachable: false, reason: '...' } - Cannot reach, show error
|
|
148
|
+
*
|
|
149
|
+
* For the Factiii pipeline:
|
|
150
|
+
* - dev: always local
|
|
151
|
+
* - secrets: needs vault password
|
|
152
|
+
* - staging/prod:
|
|
153
|
+
* - If GITHUB_ACTIONS=true → local (we're on the server)
|
|
154
|
+
* - If SSH key exists → ssh (direct SSH from dev machine)
|
|
155
|
+
* - If GITHUB_TOKEN → workflow (fallback to GitHub Actions)
|
|
156
|
+
* - Otherwise → not reachable
|
|
157
|
+
*
|
|
158
|
+
* CRITICAL: When SSHing to a server, the command MUST include
|
|
159
|
+
* --staging or --prod to prevent infinite loops.
|
|
160
|
+
* ============================================================
|
|
161
|
+
*/
|
|
162
|
+
static canReach(stage, config) {
|
|
163
|
+
switch (stage) {
|
|
164
|
+
case 'dev':
|
|
165
|
+
// Dev is always reachable locally
|
|
166
|
+
return { reachable: true, via: 'local' };
|
|
167
|
+
case 'secrets':
|
|
168
|
+
// Need Ansible Vault configuration
|
|
169
|
+
if (!config.ansible?.vault_path) {
|
|
170
|
+
return {
|
|
171
|
+
reachable: false,
|
|
172
|
+
reason: 'ansible.vault_path not configured in factiii.yml',
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
// Check if vault password is available (file or env)
|
|
176
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
177
|
+
const os = require('os');
|
|
178
|
+
const vaultPasswordFile = config.ansible.vault_password_file?.replace(/^~/, os.homedir());
|
|
179
|
+
const hasPasswordFile = vaultPasswordFile && fs.existsSync(vaultPasswordFile);
|
|
180
|
+
const hasPasswordEnv = !!process.env.ANSIBLE_VAULT_PASSWORD || !!process.env.ANSIBLE_VAULT_PASSWORD_FILE;
|
|
181
|
+
if (!hasPasswordFile && !hasPasswordEnv) {
|
|
182
|
+
return {
|
|
183
|
+
reachable: false,
|
|
184
|
+
reason: 'Vault password required. Set ansible.vault_password_file in factiii.yml, or ANSIBLE_VAULT_PASSWORD / ANSIBLE_VAULT_PASSWORD_FILE env.',
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return { reachable: true, via: 'local' };
|
|
188
|
+
case 'staging':
|
|
189
|
+
case 'prod':
|
|
190
|
+
// If GITHUB_ACTIONS is set, we're running inside a workflow on the server
|
|
191
|
+
// Return 'local' so fixes run directly without triggering another workflow
|
|
192
|
+
if (process.env.GITHUB_ACTIONS || process.env.FACTIII_ON_SERVER) {
|
|
193
|
+
return { reachable: true, via: 'local' };
|
|
194
|
+
}
|
|
195
|
+
// On dev machine: check for SSH key to reach server directly
|
|
196
|
+
// This is the primary path - direct SSH is faster than GitHub workflows
|
|
197
|
+
{
|
|
198
|
+
const sshKey = (0, ssh_helper_js_1.findSshKeyForStage)(stage);
|
|
199
|
+
if (sshKey) {
|
|
200
|
+
return { reachable: true, via: 'ssh' };
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Fallback: use GitHub workflow if GITHUB_TOKEN is available
|
|
204
|
+
if (process.env.GITHUB_TOKEN) {
|
|
205
|
+
return {
|
|
206
|
+
reachable: true,
|
|
207
|
+
via: 'workflow',
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
// No SSH key and no GITHUB_TOKEN
|
|
211
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
212
|
+
const osForPath = require('os');
|
|
213
|
+
const expectedKeyPath = require('path').join(osForPath.homedir(), '.ssh', stage + '_deploy_key');
|
|
214
|
+
return {
|
|
215
|
+
reachable: false,
|
|
216
|
+
reason: 'No SSH key found at ' + expectedKeyPath + '. Run: npx factiii secrets write-ssh-keys\n' +
|
|
217
|
+
' Fallback: set GITHUB_TOKEN for GitHub Actions workflows.',
|
|
218
|
+
};
|
|
219
|
+
default:
|
|
220
|
+
return { reachable: false, reason: `Unknown stage: ${stage}` };
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// ============================================================
|
|
224
|
+
// FIXES - All issues this plugin can detect and resolve
|
|
225
|
+
// ============================================================
|
|
226
|
+
// Combined from scanfix/ folder files
|
|
227
|
+
// ============================================================
|
|
228
|
+
static fixes = [
|
|
229
|
+
...config_js_1.configFixes,
|
|
230
|
+
...github_cli_js_1.githubCliFixes,
|
|
231
|
+
...workflows_js_1.workflowFixes,
|
|
232
|
+
...secrets_js_1.secretsFixes,
|
|
233
|
+
];
|
|
234
|
+
// ============================================================
|
|
235
|
+
// COMMANDS - Plugin commands for maintenance operations
|
|
236
|
+
// ============================================================
|
|
237
|
+
/**
|
|
238
|
+
* Get the env file for a stage
|
|
239
|
+
* - dev: .env
|
|
240
|
+
* - staging: .env.staging
|
|
241
|
+
* - prod: .env.prod
|
|
242
|
+
*/
|
|
243
|
+
static getEnvFile(stage) {
|
|
244
|
+
if (stage === 'dev')
|
|
245
|
+
return '.env';
|
|
246
|
+
return '.env.' + stage;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Load environment variables from a file
|
|
250
|
+
*/
|
|
251
|
+
static loadEnvFile(rootDir, envFile) {
|
|
252
|
+
const envPath = path.join(rootDir, envFile);
|
|
253
|
+
const env = {};
|
|
254
|
+
if (fs.existsSync(envPath)) {
|
|
255
|
+
const content = fs.readFileSync(envPath, 'utf8');
|
|
256
|
+
for (const line of content.split('\n')) {
|
|
257
|
+
const trimmed = line.trim();
|
|
258
|
+
if (trimmed && !trimmed.startsWith('#')) {
|
|
259
|
+
const eqIndex = trimmed.indexOf('=');
|
|
260
|
+
if (eqIndex > 0) {
|
|
261
|
+
const key = trimmed.substring(0, eqIndex);
|
|
262
|
+
const value = trimmed.substring(eqIndex + 1);
|
|
263
|
+
env[key] = value;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return env;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Find the directory containing Prisma (for db commands)
|
|
272
|
+
* Checks common monorepo locations
|
|
273
|
+
*/
|
|
274
|
+
static findDbDir(rootDir) {
|
|
275
|
+
const locations = [
|
|
276
|
+
'.',
|
|
277
|
+
'apps/server',
|
|
278
|
+
'packages/db',
|
|
279
|
+
'packages/database',
|
|
280
|
+
'server',
|
|
281
|
+
'backend',
|
|
282
|
+
];
|
|
283
|
+
for (const loc of locations) {
|
|
284
|
+
const dir = path.join(rootDir, loc);
|
|
285
|
+
// Check for prisma.config.ts or prisma/schema.prisma
|
|
286
|
+
if (fs.existsSync(path.join(dir, 'prisma.config.ts')) ||
|
|
287
|
+
fs.existsSync(path.join(dir, 'prisma', 'schema.prisma'))) {
|
|
288
|
+
return dir;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
// Default to root if nothing found
|
|
292
|
+
return rootDir;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Run a database command - uses docker exec for staging/prod
|
|
296
|
+
* @param command - The command to run (e.g., 'prisma migrate status' or 'pnpm db:seed')
|
|
297
|
+
* @param useNpx - Whether to prefix with npx (false for pnpm commands)
|
|
298
|
+
*/
|
|
299
|
+
static runDbCommand(command, stage, config, rootDir, useNpx = true) {
|
|
300
|
+
const prefix = useNpx ? 'npx ' : '';
|
|
301
|
+
if (stage === 'dev') {
|
|
302
|
+
// Dev: run directly on host
|
|
303
|
+
const dbDir = FactiiiPipeline.findDbDir(rootDir);
|
|
304
|
+
const envFile = FactiiiPipeline.getEnvFile(stage);
|
|
305
|
+
const envVars = FactiiiPipeline.loadEnvFile(rootDir, envFile);
|
|
306
|
+
console.log(' Directory: ' + dbDir);
|
|
307
|
+
console.log(' Env file: ' + rootDir + '/' + envFile);
|
|
308
|
+
(0, child_process_1.execSync)(prefix + command, {
|
|
309
|
+
cwd: dbDir,
|
|
310
|
+
stdio: 'inherit',
|
|
311
|
+
env: { ...process.env, ...envVars },
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
// Staging: run inside Docker container
|
|
316
|
+
const containerName = config.name + '-' + stage;
|
|
317
|
+
console.log(' Container: ' + containerName);
|
|
318
|
+
(0, child_process_1.execSync)('docker exec ' + containerName + ' ' + prefix + command, {
|
|
319
|
+
stdio: 'inherit',
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
static commands = [
|
|
324
|
+
// ────────────────────────────────────────────────────────────
|
|
325
|
+
// DATABASE COMMANDS
|
|
326
|
+
// ────────────────────────────────────────────────────────────
|
|
327
|
+
{
|
|
328
|
+
name: 'seed',
|
|
329
|
+
description: 'Seed the database with initial data (dev/staging only)',
|
|
330
|
+
category: 'db',
|
|
331
|
+
stages: ['dev', 'staging'], // No prod - destructive
|
|
332
|
+
prodSafety: 'destructive',
|
|
333
|
+
execute: async (stage, _options, config, rootDir) => {
|
|
334
|
+
try {
|
|
335
|
+
if (stage === 'dev') {
|
|
336
|
+
// Dev: use pnpm
|
|
337
|
+
FactiiiPipeline.runDbCommand('pnpm db:seed', stage, config, rootDir, false);
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
// Staging: use npm run (more commonly available in Docker)
|
|
341
|
+
FactiiiPipeline.runDbCommand('npm run db:seed', stage, config, rootDir, false);
|
|
342
|
+
}
|
|
343
|
+
return { success: true, message: 'Database seeded successfully' };
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
return { success: false, error: String(error) };
|
|
347
|
+
}
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
name: 'migrate',
|
|
352
|
+
description: 'Run pending database migrations',
|
|
353
|
+
category: 'db',
|
|
354
|
+
stages: ['dev', 'staging', 'prod'],
|
|
355
|
+
prodSafety: 'caution',
|
|
356
|
+
execute: async (stage, _options, config, rootDir) => {
|
|
357
|
+
try {
|
|
358
|
+
FactiiiPipeline.runDbCommand('prisma migrate deploy', stage, config, rootDir);
|
|
359
|
+
return { success: true, message: 'Migrations applied successfully' };
|
|
360
|
+
}
|
|
361
|
+
catch (error) {
|
|
362
|
+
return { success: false, error: String(error) };
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
name: 'reset',
|
|
368
|
+
description: 'Reset database and re-run all migrations (dev/staging only)',
|
|
369
|
+
category: 'db',
|
|
370
|
+
stages: ['dev', 'staging'], // No prod - destructive
|
|
371
|
+
prodSafety: 'destructive',
|
|
372
|
+
execute: async (stage, _options, config, rootDir) => {
|
|
373
|
+
try {
|
|
374
|
+
FactiiiPipeline.runDbCommand('prisma migrate reset --force', stage, config, rootDir);
|
|
375
|
+
return { success: true, message: 'Database reset successfully' };
|
|
376
|
+
}
|
|
377
|
+
catch (error) {
|
|
378
|
+
return { success: false, error: String(error) };
|
|
379
|
+
}
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
name: 'status',
|
|
384
|
+
description: 'Check migration status',
|
|
385
|
+
category: 'db',
|
|
386
|
+
stages: ['dev', 'staging', 'prod'],
|
|
387
|
+
prodSafety: 'safe',
|
|
388
|
+
execute: async (stage, _options, config, rootDir) => {
|
|
389
|
+
try {
|
|
390
|
+
FactiiiPipeline.runDbCommand('prisma migrate status', stage, config, rootDir);
|
|
391
|
+
return { success: true };
|
|
392
|
+
}
|
|
393
|
+
catch (error) {
|
|
394
|
+
return { success: false, error: String(error) };
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
},
|
|
398
|
+
// ────────────────────────────────────────────────────────────
|
|
399
|
+
// OPS COMMANDS
|
|
400
|
+
// ────────────────────────────────────────────────────────────
|
|
401
|
+
{
|
|
402
|
+
name: 'logs',
|
|
403
|
+
description: 'View container logs',
|
|
404
|
+
category: 'ops',
|
|
405
|
+
stages: ['staging', 'prod'],
|
|
406
|
+
prodSafety: 'safe',
|
|
407
|
+
options: [
|
|
408
|
+
{ flags: '-f, --follow', description: 'Follow log output' },
|
|
409
|
+
{ flags: '-n, --lines <number>', description: 'Number of lines to show', defaultValue: '100' },
|
|
410
|
+
{ flags: '-s, --service <name>', description: 'Service name (default: app container)' },
|
|
411
|
+
],
|
|
412
|
+
execute: async (stage, options, config, _rootDir) => {
|
|
413
|
+
const serviceName = options.service ?? config.name + '-' + stage;
|
|
414
|
+
const followFlag = options.follow ? '-f' : '';
|
|
415
|
+
const lines = options.lines ?? '100';
|
|
416
|
+
try {
|
|
417
|
+
(0, child_process_1.execSync)('docker logs ' + followFlag + ' --tail ' + lines + ' ' + serviceName, { stdio: 'inherit' });
|
|
418
|
+
return { success: true };
|
|
419
|
+
}
|
|
420
|
+
catch (error) {
|
|
421
|
+
return { success: false, error: String(error) };
|
|
422
|
+
}
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
name: 'restart',
|
|
427
|
+
description: 'Restart application containers',
|
|
428
|
+
category: 'ops',
|
|
429
|
+
stages: ['staging', 'prod'],
|
|
430
|
+
prodSafety: 'caution',
|
|
431
|
+
options: [
|
|
432
|
+
{ flags: '-s, --service <name>', description: 'Service to restart (default: app container)' },
|
|
433
|
+
],
|
|
434
|
+
execute: async (stage, options, config, _rootDir) => {
|
|
435
|
+
const factiiiDir = process.env.HOME + '/.factiii';
|
|
436
|
+
const serviceName = options.service ?? config.name + '-' + stage;
|
|
437
|
+
try {
|
|
438
|
+
(0, child_process_1.execSync)('docker compose -f ' + factiiiDir + '/docker-compose.yml restart ' + serviceName, { stdio: 'inherit' });
|
|
439
|
+
return { success: true, message: 'Restarted ' + serviceName };
|
|
440
|
+
}
|
|
441
|
+
catch (error) {
|
|
442
|
+
return { success: false, error: String(error) };
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
name: 'shell',
|
|
448
|
+
description: 'Open a shell in the application container',
|
|
449
|
+
category: 'ops',
|
|
450
|
+
stages: ['staging', 'prod'],
|
|
451
|
+
prodSafety: 'caution',
|
|
452
|
+
execute: async (stage, _options, config, _rootDir) => {
|
|
453
|
+
const serviceName = config.name + '-' + stage;
|
|
454
|
+
try {
|
|
455
|
+
(0, child_process_1.execSync)('docker exec -it ' + serviceName + ' /bin/sh', { stdio: 'inherit' });
|
|
456
|
+
return { success: true };
|
|
457
|
+
}
|
|
458
|
+
catch (error) {
|
|
459
|
+
return { success: false, error: String(error) };
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
name: 'status',
|
|
465
|
+
description: 'Show container status',
|
|
466
|
+
category: 'ops',
|
|
467
|
+
stages: ['staging', 'prod'],
|
|
468
|
+
prodSafety: 'safe',
|
|
469
|
+
execute: async (_stage, _options, _config, _rootDir) => {
|
|
470
|
+
const factiiiDir = process.env.HOME + '/.factiii';
|
|
471
|
+
try {
|
|
472
|
+
(0, child_process_1.execSync)('docker compose -f ' + factiiiDir + '/docker-compose.yml ps', { stdio: 'inherit' });
|
|
473
|
+
return { success: true };
|
|
474
|
+
}
|
|
475
|
+
catch (error) {
|
|
476
|
+
return { success: false, error: String(error) };
|
|
477
|
+
}
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
// ────────────────────────────────────────────────────────────
|
|
481
|
+
// BACKUP COMMANDS
|
|
482
|
+
// ────────────────────────────────────────────────────────────
|
|
483
|
+
{
|
|
484
|
+
name: 'create',
|
|
485
|
+
description: 'Create a database backup',
|
|
486
|
+
category: 'backup',
|
|
487
|
+
stages: ['staging', 'prod'],
|
|
488
|
+
prodSafety: 'safe',
|
|
489
|
+
options: [
|
|
490
|
+
{ flags: '-o, --output <path>', description: 'Output file path' },
|
|
491
|
+
],
|
|
492
|
+
execute: async (stage, options, _config, rootDir) => {
|
|
493
|
+
const envFile = FactiiiPipeline.getEnvFile(stage);
|
|
494
|
+
const envVars = FactiiiPipeline.loadEnvFile(rootDir, envFile); // env file in root
|
|
495
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
496
|
+
const outputPath = options.output ?? 'backup-' + stage + '-' + timestamp + '.sql';
|
|
497
|
+
console.log(' Env file: ' + rootDir + '/' + envFile);
|
|
498
|
+
const dbUrl = envVars.DATABASE_URL || process.env.DATABASE_URL;
|
|
499
|
+
if (!dbUrl) {
|
|
500
|
+
return { success: false, error: 'DATABASE_URL not set in ' + envFile };
|
|
501
|
+
}
|
|
502
|
+
try {
|
|
503
|
+
(0, child_process_1.execSync)('pg_dump "' + dbUrl + '" > ' + outputPath, { stdio: 'inherit' });
|
|
504
|
+
return { success: true, message: 'Backup created: ' + outputPath };
|
|
505
|
+
}
|
|
506
|
+
catch (error) {
|
|
507
|
+
return { success: false, error: String(error) };
|
|
508
|
+
}
|
|
509
|
+
},
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
name: 'restore',
|
|
513
|
+
description: 'Restore database from backup (DATA LOSS!)',
|
|
514
|
+
category: 'backup',
|
|
515
|
+
stages: ['staging', 'prod'],
|
|
516
|
+
prodSafety: 'destructive',
|
|
517
|
+
options: [
|
|
518
|
+
{ flags: '-i, --input <path>', description: 'Backup file to restore' },
|
|
519
|
+
],
|
|
520
|
+
execute: async (stage, options, _config, rootDir) => {
|
|
521
|
+
const inputPath = options.input;
|
|
522
|
+
if (!inputPath) {
|
|
523
|
+
return { success: false, error: 'Input file required (--input)' };
|
|
524
|
+
}
|
|
525
|
+
const envFile = FactiiiPipeline.getEnvFile(stage);
|
|
526
|
+
const envVars = FactiiiPipeline.loadEnvFile(rootDir, envFile); // env file in root
|
|
527
|
+
console.log(' Env file: ' + rootDir + '/' + envFile);
|
|
528
|
+
const dbUrl = envVars.DATABASE_URL || process.env.DATABASE_URL;
|
|
529
|
+
if (!dbUrl) {
|
|
530
|
+
return { success: false, error: 'DATABASE_URL not set in ' + envFile };
|
|
531
|
+
}
|
|
532
|
+
try {
|
|
533
|
+
(0, child_process_1.execSync)('psql "' + dbUrl + '" < ' + inputPath, { stdio: 'inherit' });
|
|
534
|
+
return { success: true, message: 'Database restored from ' + inputPath };
|
|
535
|
+
}
|
|
536
|
+
catch (error) {
|
|
537
|
+
return { success: false, error: String(error) };
|
|
538
|
+
}
|
|
539
|
+
},
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
name: 'health',
|
|
543
|
+
description: 'Check application and database health',
|
|
544
|
+
category: 'backup',
|
|
545
|
+
stages: ['staging', 'prod'],
|
|
546
|
+
prodSafety: 'safe',
|
|
547
|
+
execute: async (stage, _options, config, _rootDir) => {
|
|
548
|
+
const containerName = config.name + '-' + stage;
|
|
549
|
+
const results = [];
|
|
550
|
+
console.log(' Container: ' + containerName);
|
|
551
|
+
// Check container status
|
|
552
|
+
try {
|
|
553
|
+
(0, child_process_1.execSync)('docker ps | grep ' + containerName, { stdio: 'pipe' });
|
|
554
|
+
results.push('Container: Running');
|
|
555
|
+
}
|
|
556
|
+
catch {
|
|
557
|
+
results.push('Container: NOT RUNNING');
|
|
558
|
+
}
|
|
559
|
+
// Check database connectivity (run inside container)
|
|
560
|
+
try {
|
|
561
|
+
(0, child_process_1.execSync)('docker exec ' + containerName + ' npx prisma db execute --stdin <<< "SELECT 1"', { stdio: 'pipe' });
|
|
562
|
+
results.push('Database: Connected');
|
|
563
|
+
}
|
|
564
|
+
catch {
|
|
565
|
+
results.push('Database: NOT CONNECTED');
|
|
566
|
+
}
|
|
567
|
+
console.log('\nHealth Check Results:');
|
|
568
|
+
for (const r of results) {
|
|
569
|
+
const icon = r.includes('NOT') ? 'X' : 'OK';
|
|
570
|
+
console.log(' [' + icon + '] ' + r);
|
|
571
|
+
}
|
|
572
|
+
const allGood = !results.some((r) => r.includes('NOT') || r.includes('not found'));
|
|
573
|
+
return {
|
|
574
|
+
success: allGood,
|
|
575
|
+
message: allGood ? 'All systems healthy' : 'Issues detected',
|
|
576
|
+
};
|
|
577
|
+
},
|
|
578
|
+
},
|
|
579
|
+
];
|
|
580
|
+
// ============================================================
|
|
581
|
+
// STATIC METHODS
|
|
582
|
+
// ============================================================
|
|
583
|
+
/**
|
|
584
|
+
* Auto-detect pipeline configuration
|
|
585
|
+
*/
|
|
586
|
+
static async detectConfig(rootDir) {
|
|
587
|
+
return detectionUtils.detectConfig(rootDir);
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Detect package manager
|
|
591
|
+
*/
|
|
592
|
+
static detectPackageManager(rootDir) {
|
|
593
|
+
return detectionUtils.detectPackageManager(rootDir);
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Detect Node.js version from package.json
|
|
597
|
+
*/
|
|
598
|
+
static detectNodeVersion(rootDir) {
|
|
599
|
+
return detectionUtils.detectNodeVersion(rootDir);
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Detect pnpm version from package.json
|
|
603
|
+
*/
|
|
604
|
+
static detectPnpmVersion(rootDir) {
|
|
605
|
+
return detectionUtils.detectPnpmVersion(rootDir);
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Find Dockerfile
|
|
609
|
+
*/
|
|
610
|
+
static findDockerfile(rootDir) {
|
|
611
|
+
return detectionUtils.findDockerfile(rootDir);
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Generate GitHub workflow files in the target repository
|
|
615
|
+
*/
|
|
616
|
+
static async generateWorkflows(rootDir) {
|
|
617
|
+
return workflowUtils.generateWorkflows(rootDir);
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* Build staging Docker image (linux/arm64) on staging server
|
|
621
|
+
*/
|
|
622
|
+
static async buildStagingImage(config, envConfig) {
|
|
623
|
+
return stagingUtils.buildStagingImage(config, envConfig);
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Build production Docker image (linux/amd64) on staging server and push to ECR
|
|
627
|
+
*/
|
|
628
|
+
static async buildProductionImage(config, stagingConfig) {
|
|
629
|
+
return prodUtils.buildProductionImage(config, stagingConfig);
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Trigger a GitHub Actions workflow
|
|
633
|
+
*/
|
|
634
|
+
static async triggerWorkflow(workflowName, inputs = {}) {
|
|
635
|
+
return workflowUtils.triggerWorkflow(workflowName, inputs);
|
|
636
|
+
}
|
|
637
|
+
// ============================================================
|
|
638
|
+
// INSTANCE METHODS
|
|
639
|
+
// ============================================================
|
|
640
|
+
_config;
|
|
641
|
+
constructor(config) {
|
|
642
|
+
this._config = config;
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Deploy to a stage - handles routing based on canReach()
|
|
646
|
+
*
|
|
647
|
+
* This is the main entry point for deployments. Checks canReach() to determine:
|
|
648
|
+
* - 'local': Execute deployment directly (dev stage, or when running on server)
|
|
649
|
+
* - 'workflow': Trigger GitHub Actions workflow
|
|
650
|
+
* - Not reachable: Return error with reason
|
|
651
|
+
*/
|
|
652
|
+
async deployStage(stage, options = {}) {
|
|
653
|
+
// Ask canReach() how to reach this stage
|
|
654
|
+
// Pipeline plugin decides based on environment (GITHUB_ACTIONS, etc.)
|
|
655
|
+
const reach = FactiiiPipeline.canReach(stage, this._config);
|
|
656
|
+
if (!reach.reachable) {
|
|
657
|
+
console.log(`\n❌ Cannot reach ${stage}: ${reach.reason}`);
|
|
658
|
+
return { success: false, error: reach.reason };
|
|
659
|
+
}
|
|
660
|
+
if (reach.via === 'ssh') {
|
|
661
|
+
// Direct SSH to server - the primary deployment path
|
|
662
|
+
console.log(` Deploying to ${stage} via direct SSH...`);
|
|
663
|
+
const sshResult = (0, ssh_helper_js_1.sshRemoteFactiiiCommand)(stage, this._config, 'deploy --' + stage);
|
|
664
|
+
return {
|
|
665
|
+
success: sshResult.success,
|
|
666
|
+
message: sshResult.success ? 'Deployment complete via SSH' : undefined,
|
|
667
|
+
error: sshResult.success ? undefined : sshResult.stderr || 'SSH deployment failed',
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
if (reach.via === 'workflow') {
|
|
671
|
+
// Fallback: trigger GitHub Actions workflow
|
|
672
|
+
// Only used when SSH keys are not available but GITHUB_TOKEN is
|
|
673
|
+
try {
|
|
674
|
+
const monitor = new github_workflow_monitor_js_1.default();
|
|
675
|
+
const result = await monitor.triggerAndWatch('factiii-deploy.yml', stage);
|
|
676
|
+
return {
|
|
677
|
+
success: result.success,
|
|
678
|
+
message: result.success ? 'Deployment complete' : undefined,
|
|
679
|
+
error: result.error,
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
catch {
|
|
683
|
+
// Fall back to API-based trigger without live monitoring
|
|
684
|
+
console.log(` Triggering ${stage} deployment via GitHub Actions...`);
|
|
685
|
+
try {
|
|
686
|
+
await FactiiiPipeline.triggerWorkflow('factiii-deploy.yml', {
|
|
687
|
+
environment: stage,
|
|
688
|
+
});
|
|
689
|
+
const repoInfo = github_secrets_store_js_1.GitHubSecretsStore.getRepoInfo();
|
|
690
|
+
if (repoInfo) {
|
|
691
|
+
console.log(` Check: https://github.com/${repoInfo.owner}/${repoInfo.repo}/actions\n`);
|
|
692
|
+
}
|
|
693
|
+
return { success: true, message: 'Workflow triggered - check GitHub Actions for progress' };
|
|
694
|
+
}
|
|
695
|
+
catch (error) {
|
|
696
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
697
|
+
return { success: false, error: `Failed to trigger workflow: ${errorMessage}` };
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
// via: 'local' - we can run directly (dev stage, or on-server in workflow)
|
|
702
|
+
return this.runLocalDeploy(stage, options);
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* Scan a stage - handles routing based on canReach()
|
|
706
|
+
*
|
|
707
|
+
* Returns { handled: true } if pipeline ran scan remotely.
|
|
708
|
+
* Returns { handled: false } if caller should run scan locally.
|
|
709
|
+
*/
|
|
710
|
+
async scanStage(stage, _options = {}) {
|
|
711
|
+
const reach = FactiiiPipeline.canReach(stage, this._config);
|
|
712
|
+
if (!reach.reachable) {
|
|
713
|
+
console.log('\n[X] Cannot reach ' + stage + ': ' + reach.reason);
|
|
714
|
+
return { handled: true };
|
|
715
|
+
}
|
|
716
|
+
if (reach.via === 'ssh') {
|
|
717
|
+
console.log(' Scanning ' + stage + ' via direct SSH...');
|
|
718
|
+
const sshResult = (0, ssh_helper_js_1.sshRemoteFactiiiCommand)(stage, this._config, 'scan --' + stage);
|
|
719
|
+
if (!sshResult.success) {
|
|
720
|
+
console.log(' [!] ' + stage + ' scan failed: ' + sshResult.stderr);
|
|
721
|
+
}
|
|
722
|
+
return { handled: true };
|
|
723
|
+
}
|
|
724
|
+
if (reach.via === 'workflow') {
|
|
725
|
+
try {
|
|
726
|
+
const monitor = new github_workflow_monitor_js_1.default();
|
|
727
|
+
console.log(' Triggering ' + stage + ' scan via workflow...');
|
|
728
|
+
const result = await monitor.triggerAndWatch('factiii-scan.yml', stage);
|
|
729
|
+
if (!result.success) {
|
|
730
|
+
console.log(' [!] ' + stage + ' scan failed');
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
catch {
|
|
734
|
+
console.log(' [!] Could not trigger workflow for ' + stage + ' scan');
|
|
735
|
+
}
|
|
736
|
+
return { handled: true };
|
|
737
|
+
}
|
|
738
|
+
// via: 'local' - caller should run locally
|
|
739
|
+
return { handled: false };
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* Fix a stage - handles routing based on canReach()
|
|
743
|
+
*
|
|
744
|
+
* Returns { handled: true } if pipeline ran fix remotely.
|
|
745
|
+
* Returns { handled: false } if caller should run fix locally.
|
|
746
|
+
*/
|
|
747
|
+
async fixStage(stage, _options = {}) {
|
|
748
|
+
const reach = FactiiiPipeline.canReach(stage, this._config);
|
|
749
|
+
if (!reach.reachable) {
|
|
750
|
+
console.log('\n[X] Cannot reach ' + stage + ': ' + reach.reason);
|
|
751
|
+
return { handled: true };
|
|
752
|
+
}
|
|
753
|
+
if (reach.via === 'ssh') {
|
|
754
|
+
console.log(' Fixing ' + stage + ' via direct SSH...');
|
|
755
|
+
const sshResult = (0, ssh_helper_js_1.sshRemoteFactiiiCommand)(stage, this._config, 'fix --' + stage);
|
|
756
|
+
if (!sshResult.success) {
|
|
757
|
+
console.log(' [!] ' + stage + ' fix failed: ' + sshResult.stderr);
|
|
758
|
+
}
|
|
759
|
+
return { handled: true };
|
|
760
|
+
}
|
|
761
|
+
if (reach.via === 'workflow') {
|
|
762
|
+
try {
|
|
763
|
+
const monitor = new github_workflow_monitor_js_1.default();
|
|
764
|
+
console.log(' Triggering ' + stage + ' fix via workflow...');
|
|
765
|
+
const result = await monitor.triggerAndWatch('factiii-fix.yml', stage);
|
|
766
|
+
if (!result.success) {
|
|
767
|
+
console.log(' [!] ' + stage + ' fix failed');
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
catch {
|
|
771
|
+
console.log(' [!] Could not trigger workflow for ' + stage + ' fix');
|
|
772
|
+
}
|
|
773
|
+
return { handled: true };
|
|
774
|
+
}
|
|
775
|
+
// via: 'local' - caller should run locally
|
|
776
|
+
return { handled: false };
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Run deployment locally by delegating to server plugin
|
|
780
|
+
*/
|
|
781
|
+
async runLocalDeploy(stage, options) {
|
|
782
|
+
const rootDir = options.rootDir ?? process.cwd();
|
|
783
|
+
// Load plugins and find server plugin
|
|
784
|
+
const plugins = await (0, index_js_1.loadRelevantPlugins)(rootDir, this._config);
|
|
785
|
+
const ServerPluginClass = plugins.find((p) => p.category === 'server');
|
|
786
|
+
if (!ServerPluginClass) {
|
|
787
|
+
return { success: false, error: 'No server plugin found' };
|
|
788
|
+
}
|
|
789
|
+
try {
|
|
790
|
+
const serverInstance = new ServerPluginClass(this._config);
|
|
791
|
+
// Ensure server is ready (install deps, clone repo, etc.)
|
|
792
|
+
if (serverInstance.ensureServerReady) {
|
|
793
|
+
console.log(' Preparing server...');
|
|
794
|
+
// Get repo URL from environment or config
|
|
795
|
+
const repoUrl = process.env.GITHUB_REPO || this._config.github_repo || '';
|
|
796
|
+
await serverInstance.ensureServerReady(this._config, stage, {
|
|
797
|
+
branch: options.branch ?? 'main',
|
|
798
|
+
commitHash: options.commit ?? '',
|
|
799
|
+
repoUrl: repoUrl,
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
// Build Docker images before deployment
|
|
803
|
+
// Skip if SKIP_BUILD is set (build was already done in workflow)
|
|
804
|
+
if (!process.env.SKIP_BUILD) {
|
|
805
|
+
const { extractEnvironments } = await Promise.resolve().then(() => __importStar(require('../../../utils/config-helpers.js')));
|
|
806
|
+
const environments = extractEnvironments(this._config);
|
|
807
|
+
if (stage === 'staging') {
|
|
808
|
+
const envConfig = environments.staging;
|
|
809
|
+
if (envConfig?.domain) {
|
|
810
|
+
console.log(' 🔨 Building staging image on staging server...');
|
|
811
|
+
console.log(` 📍 Target server: ${envConfig.domain}`);
|
|
812
|
+
const buildResult = await FactiiiPipeline.buildStagingImage(this._config, envConfig);
|
|
813
|
+
if (!buildResult.success) {
|
|
814
|
+
console.error(` ❌ Build failed: ${buildResult.error}`);
|
|
815
|
+
return buildResult;
|
|
816
|
+
}
|
|
817
|
+
console.log(' ✅ Staging image built successfully on staging server');
|
|
818
|
+
}
|
|
819
|
+
else {
|
|
820
|
+
console.log(' ⚠️ Staging domain not configured, skipping build');
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
else if (stage === 'prod') {
|
|
824
|
+
const stagingConfig = environments.staging;
|
|
825
|
+
if (stagingConfig?.domain) {
|
|
826
|
+
console.log(' 🔨 Building production image on staging server...');
|
|
827
|
+
const buildResult = await FactiiiPipeline.buildProductionImage(this._config, stagingConfig);
|
|
828
|
+
if (!buildResult.success) {
|
|
829
|
+
return buildResult;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
else {
|
|
835
|
+
console.log(' ⏭️ Skipping build step (already built in workflow)');
|
|
836
|
+
}
|
|
837
|
+
// Run the actual deployment
|
|
838
|
+
return serverInstance.deploy(this._config, stage);
|
|
839
|
+
}
|
|
840
|
+
catch (error) {
|
|
841
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
842
|
+
return { success: false, error: errorMessage };
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Deploy to an environment
|
|
847
|
+
* @deprecated Use deployStage() which handles routing based on canReach()
|
|
848
|
+
*/
|
|
849
|
+
async deploy(_config, environment) {
|
|
850
|
+
// For backwards compatibility, delegate to deployStage
|
|
851
|
+
return this.deployStage(environment, {});
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Undeploy from an environment
|
|
855
|
+
*/
|
|
856
|
+
async undeploy(_config, environment) {
|
|
857
|
+
console.log(` Pipeline: ${environment} undeploy initiated`);
|
|
858
|
+
return { success: true };
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
exports.default = FactiiiPipeline;
|
|
862
|
+
//# sourceMappingURL=index.js.map
|