@factiii/stack 0.1.24 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/README.md +81 -60
  2. package/bin/{factiii → stack} +12 -12
  3. package/dist/cli/check-config.js +1 -1
  4. package/dist/cli/check-config.js.map +1 -1
  5. package/dist/cli/deploy-secrets.d.ts.map +1 -1
  6. package/dist/cli/deploy-secrets.js +11 -11
  7. package/dist/cli/deploy-secrets.js.map +1 -1
  8. package/dist/cli/deploy.d.ts.map +1 -1
  9. package/dist/cli/deploy.js +19 -9
  10. package/dist/cli/deploy.js.map +1 -1
  11. package/dist/cli/dev-sync.d.ts.map +1 -1
  12. package/dist/cli/dev-sync.js +10 -9
  13. package/dist/cli/dev-sync.js.map +1 -1
  14. package/dist/cli/execute-plugin-command.d.ts.map +1 -1
  15. package/dist/cli/execute-plugin-command.js +7 -7
  16. package/dist/cli/execute-plugin-command.js.map +1 -1
  17. package/dist/cli/fix.d.ts.map +1 -1
  18. package/dist/cli/fix.js +24 -4
  19. package/dist/cli/fix.js.map +1 -1
  20. package/dist/cli/init.d.ts +3 -1
  21. package/dist/cli/init.d.ts.map +1 -1
  22. package/dist/cli/init.js +382 -69
  23. package/dist/cli/init.js.map +1 -1
  24. package/dist/cli/pr-check.d.ts.map +1 -1
  25. package/dist/cli/pr-check.js +5 -4
  26. package/dist/cli/pr-check.js.map +1 -1
  27. package/dist/cli/scan.d.ts +6 -6
  28. package/dist/cli/scan.d.ts.map +1 -1
  29. package/dist/cli/scan.js +46 -30
  30. package/dist/cli/scan.js.map +1 -1
  31. package/dist/cli/secrets.d.ts.map +1 -1
  32. package/dist/cli/secrets.js +17 -16
  33. package/dist/cli/secrets.js.map +1 -1
  34. package/dist/cli/undeploy.d.ts.map +1 -1
  35. package/dist/cli/undeploy.js +4 -4
  36. package/dist/cli/undeploy.js.map +1 -1
  37. package/dist/cli/upgrade.d.ts +1 -1
  38. package/dist/cli/upgrade.js +5 -5
  39. package/dist/cli/upgrade.js.map +1 -1
  40. package/dist/cli/validate.js +1 -1
  41. package/dist/cli/validate.js.map +1 -1
  42. package/dist/constants/config-files.d.ts +23 -0
  43. package/dist/constants/config-files.d.ts.map +1 -0
  44. package/dist/constants/config-files.js +88 -0
  45. package/dist/constants/config-files.js.map +1 -0
  46. package/dist/generators/{generate-factiii-auto.d.ts → generate-stack-auto.d.ts} +4 -4
  47. package/dist/generators/generate-stack-auto.d.ts.map +1 -0
  48. package/dist/generators/{generate-factiii-auto.js → generate-stack-auto.js} +15 -13
  49. package/dist/generators/generate-stack-auto.js.map +1 -0
  50. package/dist/generators/{generate-factiii-yml.d.ts → generate-stack-yml.d.ts} +5 -5
  51. package/dist/generators/generate-stack-yml.d.ts.map +1 -0
  52. package/dist/generators/{generate-factiii-yml.js → generate-stack-yml.js} +16 -15
  53. package/dist/generators/generate-stack-yml.js.map +1 -0
  54. package/dist/generators/index.d.ts +2 -2
  55. package/dist/generators/index.d.ts.map +1 -1
  56. package/dist/generators/index.js +5 -5
  57. package/dist/generators/index.js.map +1 -1
  58. package/dist/plugins/pipelines/aws/index.js +3 -3
  59. package/dist/plugins/pipelines/aws/index.js.map +1 -1
  60. package/dist/plugins/pipelines/aws/scanfix/credentials.d.ts.map +1 -1
  61. package/dist/plugins/pipelines/aws/scanfix/credentials.js +36 -44
  62. package/dist/plugins/pipelines/aws/scanfix/credentials.js.map +1 -1
  63. package/dist/plugins/pipelines/aws/scanfix/ec2.js +1 -1
  64. package/dist/plugins/pipelines/aws/scanfix/ec2.js.map +1 -1
  65. package/dist/plugins/pipelines/aws/scanfix/iam.js +2 -2
  66. package/dist/plugins/pipelines/aws/scanfix/iam.js.map +1 -1
  67. package/dist/plugins/pipelines/aws/scanfix/rds.js +2 -2
  68. package/dist/plugins/pipelines/aws/scanfix/rds.js.map +1 -1
  69. package/dist/plugins/pipelines/factiii/index.d.ts +5 -3
  70. package/dist/plugins/pipelines/factiii/index.d.ts.map +1 -1
  71. package/dist/plugins/pipelines/factiii/index.js +14 -77
  72. package/dist/plugins/pipelines/factiii/index.js.map +1 -1
  73. package/dist/plugins/pipelines/factiii/pr-check.d.ts +1 -1
  74. package/dist/plugins/pipelines/factiii/pr-check.js +1 -1
  75. package/dist/plugins/pipelines/factiii/prod.d.ts.map +1 -1
  76. package/dist/plugins/pipelines/factiii/prod.js +3 -3
  77. package/dist/plugins/pipelines/factiii/prod.js.map +1 -1
  78. package/dist/plugins/pipelines/factiii/scanfix/config.d.ts +1 -1
  79. package/dist/plugins/pipelines/factiii/scanfix/config.d.ts.map +1 -1
  80. package/dist/plugins/pipelines/factiii/scanfix/config.js +10 -11
  81. package/dist/plugins/pipelines/factiii/scanfix/config.js.map +1 -1
  82. package/dist/plugins/pipelines/factiii/scanfix/env-files.d.ts +12 -0
  83. package/dist/plugins/pipelines/factiii/scanfix/env-files.d.ts.map +1 -0
  84. package/dist/plugins/pipelines/factiii/scanfix/env-files.js +310 -0
  85. package/dist/plugins/pipelines/factiii/scanfix/env-files.js.map +1 -0
  86. package/dist/plugins/pipelines/factiii/scanfix/local-config.d.ts +7 -0
  87. package/dist/plugins/pipelines/factiii/scanfix/local-config.d.ts.map +1 -0
  88. package/dist/plugins/pipelines/factiii/scanfix/local-config.js +70 -0
  89. package/dist/plugins/pipelines/factiii/scanfix/local-config.js.map +1 -0
  90. package/dist/plugins/pipelines/factiii/scanfix/secrets.js +6 -6
  91. package/dist/plugins/pipelines/factiii/scanfix/secrets.js.map +1 -1
  92. package/dist/plugins/pipelines/factiii/scanfix/workflows.d.ts.map +1 -1
  93. package/dist/plugins/pipelines/factiii/scanfix/workflows.js +16 -26
  94. package/dist/plugins/pipelines/factiii/scanfix/workflows.js.map +1 -1
  95. package/dist/plugins/pipelines/factiii/staging.d.ts +1 -1
  96. package/dist/plugins/pipelines/factiii/staging.d.ts.map +1 -1
  97. package/dist/plugins/pipelines/factiii/staging.js +3 -2
  98. package/dist/plugins/pipelines/factiii/staging.js.map +1 -1
  99. package/dist/plugins/pipelines/factiii/utils/workflows.d.ts.map +1 -1
  100. package/dist/plugins/pipelines/factiii/utils/workflows.js +6 -21
  101. package/dist/plugins/pipelines/factiii/utils/workflows.js.map +1 -1
  102. package/dist/plugins/pipelines/factiii/workflows/stack-ci.yml +56 -0
  103. package/dist/plugins/pipelines/factiii/workflows/stack-cicd-prod.yml +54 -0
  104. package/dist/plugins/servers/mac/scanfix/containers.js +1 -1
  105. package/dist/plugins/servers/mac/scanfix/containers.js.map +1 -1
  106. package/dist/scanfix/fixes/pnpm.d.ts.map +1 -1
  107. package/dist/scanfix/fixes/pnpm.js +2 -2
  108. package/dist/scanfix/fixes/pnpm.js.map +1 -1
  109. package/dist/scripts/generate-all.d.ts.map +1 -1
  110. package/dist/scripts/generate-all.js +9 -8
  111. package/dist/scripts/generate-all.js.map +1 -1
  112. package/dist/scripts/get-repo-name.d.ts +1 -1
  113. package/dist/scripts/get-repo-name.js +5 -3
  114. package/dist/scripts/get-repo-name.js.map +1 -1
  115. package/dist/scripts/validate-env-files.js +7 -1
  116. package/dist/scripts/validate-env-files.js.map +1 -1
  117. package/dist/scripts/validate-example-values.d.ts +1 -1
  118. package/dist/scripts/validate-example-values.js +3 -2
  119. package/dist/scripts/validate-example-values.js.map +1 -1
  120. package/dist/scripts/validate-stack-yml.d.ts +6 -0
  121. package/dist/scripts/validate-stack-yml.d.ts.map +1 -0
  122. package/dist/scripts/{validate-factiii-yml.js → validate-stack-yml.js} +15 -11
  123. package/dist/scripts/validate-stack-yml.js.map +1 -0
  124. package/dist/utils/config-helpers.d.ts +15 -0
  125. package/dist/utils/config-helpers.d.ts.map +1 -1
  126. package/dist/utils/config-helpers.js +57 -5
  127. package/dist/utils/config-helpers.js.map +1 -1
  128. package/dist/utils/config-validator.d.ts +2 -2
  129. package/dist/utils/config-validator.d.ts.map +1 -1
  130. package/dist/utils/config-validator.js +7 -6
  131. package/dist/utils/config-validator.js.map +1 -1
  132. package/dist/utils/config-writer.d.ts +2 -2
  133. package/dist/utils/config-writer.d.ts.map +1 -1
  134. package/dist/utils/config-writer.js +6 -6
  135. package/dist/utils/config-writer.js.map +1 -1
  136. package/dist/utils/deployment-report.js +4 -4
  137. package/dist/utils/deployment-report.js.map +1 -1
  138. package/dist/utils/ssh-helper.js +6 -6
  139. package/dist/utils/ssh-helper.js.map +1 -1
  140. package/dist/utils/template-generator.js +1 -1
  141. package/dist/utils/version-check.d.ts +1 -1
  142. package/dist/utils/version-check.d.ts.map +1 -1
  143. package/dist/utils/version-check.js +9 -8
  144. package/dist/utils/version-check.js.map +1 -1
  145. package/package.json +8 -2
  146. package/dist/generators/generate-factiii-auto.d.ts.map +0 -1
  147. package/dist/generators/generate-factiii-auto.js.map +0 -1
  148. package/dist/generators/generate-factiii-yml.d.ts.map +0 -1
  149. package/dist/generators/generate-factiii-yml.js.map +0 -1
  150. package/dist/plugins/pipelines/factiii/workflows/factiii-cicd-prod.yml +0 -112
  151. package/dist/plugins/pipelines/factiii/workflows/factiii-cicd-staging.yml +0 -117
  152. package/dist/plugins/pipelines/factiii/workflows/factiii-command.yml +0 -130
  153. package/dist/plugins/pipelines/factiii/workflows/factiii-deploy.yml +0 -198
  154. package/dist/plugins/pipelines/factiii/workflows/factiii-dev-sync.yml +0 -179
  155. package/dist/plugins/pipelines/factiii/workflows/factiii-fix.yml +0 -176
  156. package/dist/plugins/pipelines/factiii/workflows/factiii-pr-check.yml +0 -103
  157. package/dist/plugins/pipelines/factiii/workflows/factiii-scan.yml +0 -176
  158. package/dist/plugins/pipelines/factiii/workflows/factiii-undeploy.yml +0 -95
  159. package/dist/scripts/validate-factiii-yml.d.ts +0 -6
  160. package/dist/scripts/validate-factiii-yml.d.ts.map +0 -1
  161. package/dist/scripts/validate-factiii-yml.js.map +0 -1
@@ -1,198 +0,0 @@
1
- name: Factiii Deploy
2
-
3
- # Generated by @factiii/stack v{VERSION}
4
- # INFRASTRUCTURE: Manual deployment triggered via CLI
5
- # Run: npx factiii deploy --staging or npx factiii deploy --prod
6
- # For auto-deploy on push, see factiii-cicd-staging.yml / factiii-cicd-prod.yml
7
-
8
- on:
9
- workflow_dispatch:
10
- inputs:
11
- environment:
12
- description: 'Environment to deploy'
13
- required: true
14
- type: choice
15
- options:
16
- - staging
17
- - prod
18
-
19
- jobs:
20
- deploy:
21
- runs-on: ubuntu-latest
22
- steps:
23
- - name: Checkout code
24
- uses: actions/checkout@v4
25
-
26
- - name: Install yq
27
- run: |
28
- sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
29
- sudo chmod +x /usr/local/bin/yq
30
-
31
- - name: Read config
32
- id: config
33
- run: |
34
- if [ ! -f "factiii.yml" ]; then
35
- echo "❌ factiii.yml not found"
36
- exit 1
37
- fi
38
-
39
- REPO_NAME=$(yq eval '.name' factiii.yml)
40
-
41
- if [ "${{ inputs.environment }}" == "staging" ]; then
42
- HOST=$(yq eval '.staging.domain // ""' factiii.yml)
43
- SSH_USER=$(yq eval '.staging.ssh_user // "ubuntu"' factiii.yml)
44
- else
45
- HOST=$(yq eval '.prod.domain // ""' factiii.yml)
46
- SSH_USER=$(yq eval '.prod.ssh_user // "ubuntu"' factiii.yml)
47
- fi
48
-
49
- echo "repo_name=$REPO_NAME" >> $GITHUB_OUTPUT
50
- echo "host=$HOST" >> $GITHUB_OUTPUT
51
- echo "ssh_user=$SSH_USER" >> $GITHUB_OUTPUT
52
-
53
- - name: Check if environment configured
54
- id: check_env
55
- run: |
56
- if [ "${{ inputs.environment }}" == "staging" ]; then
57
- HAS_ENV=$(yq eval '.staging != null' factiii.yml)
58
- else
59
- HAS_ENV=$(yq eval '.prod != null' factiii.yml)
60
- fi
61
-
62
- echo "has_env=$HAS_ENV" >> $GITHUB_OUTPUT
63
-
64
- if [ "$HAS_ENV" != "true" ]; then
65
- echo "⏭️ ${{ inputs.environment }} environment not configured in factiii.yml"
66
- exit 1
67
- fi
68
-
69
- - name: Read staging config (for prod builds)
70
- if: steps.check_env.outputs.has_env == 'true' && inputs.environment == 'prod'
71
- id: staging_config
72
- run: |
73
- STAGING_HOST=$(yq eval '.staging.domain // ""' factiii.yml)
74
- STAGING_SSH_USER=$(yq eval '.staging.ssh_user // "ubuntu"' factiii.yml)
75
-
76
- echo "staging_host=$STAGING_HOST" >> $GITHUB_OUTPUT
77
- echo "staging_ssh_user=$STAGING_SSH_USER" >> $GITHUB_OUTPUT
78
-
79
- - name: Setup Node.js
80
- if: steps.check_env.outputs.has_env == 'true'
81
- uses: actions/setup-node@v4
82
- with:
83
- node-version: '20'
84
-
85
- - name: Load SSH keys from Ansible Vault
86
- if: steps.check_env.outputs.has_env == 'true'
87
- env:
88
- ANSIBLE_VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT_PASSWORD }}
89
- run: |
90
- if [ -z "$ANSIBLE_VAULT_PASSWORD" ]; then
91
- echo "❌ Missing ANSIBLE_VAULT_PASSWORD secret (vault password)"
92
- exit 1
93
- fi
94
-
95
- npx factiii secrets write-ssh-keys
96
-
97
- # Create deploy_key symlink for current environment
98
- if [ "${{ inputs.environment }}" == "staging" ]; then
99
- ln -sf ~/.ssh/staging_deploy_key ~/.ssh/deploy_key
100
- else
101
- ln -sf ~/.ssh/prod_deploy_key ~/.ssh/deploy_key
102
- fi
103
-
104
- - name: Build production image on staging (prod only)
105
- if: steps.check_env.outputs.has_env == 'true' && inputs.environment == 'prod'
106
- env:
107
- STAGING_HOST: ${{ steps.staging_config.outputs.staging_host }}
108
- STAGING_USER: ${{ steps.staging_config.outputs.staging_ssh_user }}
109
- REPO_NAME: ${{ steps.config.outputs.repo_name }}
110
- COMMIT_HASH: ${{ github.sha }}
111
- BRANCH: ${{ github.ref_name }}
112
- GITHUB_REPO: ${{ github.repository }}
113
- run: |
114
- if [ -z "$STAGING_HOST" ]; then
115
- echo "⚠️ Staging host not configured, skipping build step"
116
- exit 0
117
- fi
118
-
119
- echo "🔨 Building production image on staging server ($STAGING_HOST)..."
120
-
121
- ssh -i ~/.ssh/staging_deploy_key -o StrictHostKeyChecking=no "$STAGING_USER@$STAGING_HOST" \
122
- "export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
123
- REPO_DIR=\"\$HOME/.factiii/$REPO_NAME\" && \
124
- if [ -d \"\$REPO_DIR\" ]; then \
125
- cd \"\$REPO_DIR\" && \
126
- GITHUB_ACTIONS=true COMMIT_HASH=$COMMIT_HASH BRANCH=$BRANCH GITHUB_REPO=$GITHUB_REPO \
127
- npx factiii deploy --prod --commit $COMMIT_HASH --branch $BRANCH; \
128
- else \
129
- echo \"❌ Repo directory not found at \$REPO_DIR\"; \
130
- exit 1; \
131
- fi"
132
-
133
- BUILD_EXIT_CODE=$?
134
- if [ $BUILD_EXIT_CODE -ne 0 ]; then
135
- echo "❌ Build step failed with exit code $BUILD_EXIT_CODE"
136
- exit $BUILD_EXIT_CODE
137
- fi
138
-
139
- echo "✅ Production image built and pushed to ECR"
140
-
141
- - name: Deploy via CLI
142
- if: steps.check_env.outputs.has_env == 'true'
143
- env:
144
- HOST: ${{ steps.config.outputs.host }}
145
- USER: ${{ steps.config.outputs.ssh_user }}
146
- REPO_NAME: ${{ steps.config.outputs.repo_name }}
147
- ENVIRONMENT: ${{ inputs.environment }}
148
- COMMIT_HASH: ${{ github.sha }}
149
- BRANCH: ${{ github.ref_name }}
150
- GITHUB_REPO: ${{ github.repository }}
151
- STAGING_ENVS: ${{ inputs.environment == 'staging' && secrets.STAGING_ENVS || '' }}
152
- PROD_ENVS: ${{ inputs.environment == 'prod' && secrets.PROD_ENVS || '' }}
153
- run: |
154
- if [ -z "$HOST" ]; then
155
- echo "❌ Missing domain in factiii.yml: $ENVIRONMENT.domain"
156
- exit 1
157
- fi
158
-
159
- echo "🚀 Deploying to $ENVIRONMENT ($HOST)..."
160
-
161
- # For prod, skip build step (already done in previous step)
162
- SKIP_BUILD_FLAG=""
163
- if [ "$ENVIRONMENT" == "prod" ]; then
164
- SKIP_BUILD_FLAG="SKIP_BUILD=true"
165
- fi
166
-
167
- # Prepare environment variables for SSH (base64 encode to handle special characters)
168
- ENV_VARS_EXPORT=""
169
- if [ "$ENVIRONMENT" == "staging" ] && [ -n "$STAGING_ENVS" ]; then
170
- ENV_VARS_B64=$(echo -n "$STAGING_ENVS" | base64 -w 0)
171
- ENV_VARS_EXPORT="STAGING_ENVS=\$(echo '$ENV_VARS_B64' | base64 -d) && export STAGING_ENVS && "
172
- elif [ "$ENVIRONMENT" == "prod" ] && [ -n "$PROD_ENVS" ]; then
173
- ENV_VARS_B64=$(echo -n "$PROD_ENVS" | base64 -w 0)
174
- ENV_VARS_EXPORT="PROD_ENVS=\$(echo '$ENV_VARS_B64' | base64 -d) && export PROD_ENVS && "
175
- fi
176
-
177
- ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no "$USER@$HOST" \
178
- "export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
179
- REPO_DIR=\"\$HOME/.factiii/$REPO_NAME\" && \
180
- if [ -d \"\$REPO_DIR\" ]; then \
181
- cd \"\$REPO_DIR\" && \
182
- $ENV_VARS_EXPORT$SKIP_BUILD_FLAG GITHUB_ACTIONS=true COMMIT_HASH=$COMMIT_HASH BRANCH=$BRANCH GITHUB_REPO=$GITHUB_REPO \
183
- npx factiii deploy --$ENVIRONMENT --commit $COMMIT_HASH --branch $BRANCH; \
184
- else \
185
- echo \"❌ Repo directory not found at \$REPO_DIR\"; \
186
- echo \"Run deployment first to clone the repository\"; \
187
- exit 1; \
188
- fi"
189
-
190
- DEPLOY_EXIT_CODE=$?
191
- rm -f ~/.ssh/deploy_key ~/.ssh/staging_deploy_key ~/.ssh/prod_deploy_key
192
-
193
- if [ $DEPLOY_EXIT_CODE -eq 0 ]; then
194
- echo "✅ Deployment complete!"
195
- else
196
- echo "❌ Deployment failed with exit code $DEPLOY_EXIT_CODE"
197
- exit $DEPLOY_EXIT_CODE
198
- fi
@@ -1,179 +0,0 @@
1
- name: Factiii Dev Sync
2
-
3
- # Generated by @factiii/stack v{VERSION}
4
- # DEV/TESTING ONLY - Deploys locally built infrastructure for testing beta features
5
- # This workflow receives infrastructure changes and deploys them to servers
6
- # Use: npx factiii dev-sync
7
- #
8
- # ⚠️ WARNING: This is for developing @factiii/stack itself, not for app deployments
9
- # Only use this when testing new infrastructure features before releasing them
10
-
11
- on:
12
- workflow_dispatch:
13
- inputs:
14
- environment:
15
- description: 'Environment to sync'
16
- required: true
17
- type: choice
18
- options:
19
- - staging
20
- - prod
21
- release_id:
22
- description: 'GitHub Release ID containing artifact'
23
- required: true
24
- type: string
25
- asset_id:
26
- description: 'Release Asset ID for infrastructure tarball'
27
- required: true
28
- type: string
29
- deploy:
30
- description: 'Deploy after syncing'
31
- required: false
32
- type: boolean
33
- default: false
34
-
35
- jobs:
36
- dev-sync:
37
- runs-on: ubuntu-latest
38
- steps:
39
- - name: Checkout code
40
- uses: actions/checkout@v4
41
-
42
- - name: Install yq
43
- run: |
44
- sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
45
- sudo chmod +x /usr/local/bin/yq
46
-
47
- - name: Read config
48
- id: config
49
- run: |
50
- if [ ! -f "factiii.yml" ]; then
51
- echo "❌ factiii.yml not found"
52
- exit 1
53
- fi
54
-
55
- REPO_NAME=$(yq eval '.name' factiii.yml)
56
-
57
- if [ "${{ inputs.environment }}" == "staging" ]; then
58
- HOST=$(yq eval '.environments.staging.domain // ""' factiii.yml)
59
- SSH_USER=$(yq eval '.environments.staging.ssh_user // "ubuntu"' factiii.yml)
60
- else
61
- HOST=$(yq eval '.environments.prod.domain // ""' factiii.yml)
62
- SSH_USER=$(yq eval '.environments.prod.ssh_user // "ubuntu"' factiii.yml)
63
- fi
64
-
65
- echo "repo_name=$REPO_NAME" >> $GITHUB_OUTPUT
66
- echo "host=$HOST" >> $GITHUB_OUTPUT
67
- echo "ssh_user=$SSH_USER" >> $GITHUB_OUTPUT
68
-
69
- - name: Check if environment configured
70
- id: check_env
71
- run: |
72
- if [ "${{ inputs.environment }}" == "staging" ]; then
73
- HAS_ENV=$(yq eval '.environments.staging != null' factiii.yml)
74
- else
75
- HAS_ENV=$(yq eval '.environments.prod != null' factiii.yml)
76
- fi
77
-
78
- echo "has_env=$HAS_ENV" >> $GITHUB_OUTPUT
79
-
80
- if [ "$HAS_ENV" != "true" ]; then
81
- echo "⏭️ ${{ inputs.environment }} environment not configured in factiii.yml"
82
- exit 1
83
- fi
84
-
85
- - name: Setup SSH
86
- if: steps.check_env.outputs.has_env == 'true'
87
- env:
88
- SSH_KEY: ${{ inputs.environment == 'staging' && secrets.STAGING_SSH || secrets.PROD_SSH }}
89
- run: |
90
- if [ -z "$SSH_KEY" ]; then
91
- echo "❌ Missing ${{ inputs.environment == 'staging' && 'STAGING_SSH' || 'PROD_SSH' }} secret"
92
- exit 1
93
- fi
94
-
95
- mkdir -p ~/.ssh
96
- echo "$SSH_KEY" > ~/.ssh/deploy_key
97
- chmod 600 ~/.ssh/deploy_key
98
-
99
- - name: Download infrastructure artifact from release
100
- if: steps.check_env.outputs.has_env == 'true'
101
- env:
102
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
103
- RELEASE_ID: ${{ inputs.release_id }}
104
- ASSET_ID: ${{ inputs.asset_id }}
105
- run: |
106
- echo "⚠️ DEV SYNC MODE - Using infrastructure from local build"
107
- echo " This syncs uncommitted infrastructure changes for testing"
108
- echo " Release ID: $RELEASE_ID"
109
- echo " Asset ID: $ASSET_ID"
110
-
111
- echo "📦 Downloading infrastructure artifact..."
112
-
113
- # Download release asset using GitHub API
114
- curl -L \
115
- -H "Accept: application/octet-stream" \
116
- -H "Authorization: Bearer $GITHUB_TOKEN" \
117
- -H "X-GitHub-Api-Version: 2022-11-28" \
118
- "https://api.github.com/repos/${{ github.repository }}/releases/assets/$ASSET_ID" \
119
- -o infrastructure.tar.gz
120
-
121
- # Verify download
122
- if [ ! -f infrastructure.tar.gz ]; then
123
- echo "❌ Failed to download artifact"
124
- exit 1
125
- fi
126
-
127
- SIZE=$(du -h infrastructure.tar.gz | cut -f1)
128
- echo "✅ Downloaded artifact ($SIZE)"
129
-
130
- - name: Deploy infrastructure to server
131
- if: steps.check_env.outputs.has_env == 'true'
132
- env:
133
- HOST: ${{ steps.config.outputs.host }}
134
- USER: ${{ steps.config.outputs.ssh_user }}
135
- DEPLOY: ${{ inputs.deploy }}
136
- REPO_NAME: ${{ steps.config.outputs.repo_name }}
137
- ENVIRONMENT: ${{ inputs.environment }}
138
- run: |
139
- if [ -z "$HOST" ]; then
140
- echo "❌ Missing domain in factiii.yml: environments.$ENVIRONMENT.domain"
141
- exit 1
142
- fi
143
-
144
- echo "🚀 Syncing infrastructure to $ENVIRONMENT ($HOST)..."
145
-
146
- # Copy infrastructure to server
147
- echo "📤 Uploading infrastructure package..."
148
- scp -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no infrastructure.tar.gz "$USER@$HOST:/tmp/"
149
-
150
- # Extract and setup on server
151
- echo "📦 Extracting infrastructure on server..."
152
- ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no "$USER@$HOST" \
153
- "export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
154
- echo \"📦 Setting up infrastructure...\" && \
155
- mkdir -p ~/.factiii/infrastructure && \
156
- cd ~/.factiii/infrastructure && \
157
- tar -xzf /tmp/infrastructure.tar.gz && \
158
- rm /tmp/infrastructure.tar.gz && \
159
- echo \"\" && \
160
- echo \"📋 Verifying version...\" && \
161
- VERSION=\$(cat package.json | grep '\"version\"' | head -1 | sed 's/.*: \"\(.*\)\".*/\1/') && \
162
- echo \" Version: \$VERSION\" && \
163
- echo \"\" && \
164
- echo \"✅ Infrastructure synced successfully\""
165
-
166
- # Optionally deploy
167
- if [ "$DEPLOY" == "true" ]; then
168
- echo ""
169
- echo "🚀 Deploying to $ENVIRONMENT..."
170
- ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no "$USER@$HOST" \
171
- "export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
172
- cd ~/.factiii/$REPO_NAME && \
173
- GITHUB_ACTIONS=true node ~/.factiii/infrastructure/bin/factiii deploy --$ENVIRONMENT"
174
- fi
175
-
176
- rm -f ~/.ssh/deploy_key
177
- echo ""
178
- echo "✅ Dev sync complete!"
179
-
@@ -1,176 +0,0 @@
1
- name: Factiii Fix
2
-
3
- # Generated by @factiii/stack v{VERSION}
4
- # INFRASTRUCTURE: Fix server issues via CLI
5
- # Run: npx factiii fix (triggers this workflow)
6
- # Runs on configured environments in parallel using matrix strategy
7
-
8
- on:
9
- workflow_dispatch:
10
- inputs:
11
- environment:
12
- description: 'Environment to fix'
13
- required: true
14
- type: choice
15
- options:
16
- - all
17
- - staging
18
- - prod
19
- default: all
20
-
21
- jobs:
22
- setup:
23
- runs-on: ubuntu-latest
24
- outputs:
25
- matrix: ${{ steps.set-matrix.outputs.matrix }}
26
- steps:
27
- - name: Checkout code
28
- uses: actions/checkout@v4
29
-
30
- - name: Install yq
31
- run: |
32
- sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
33
- sudo chmod +x /usr/local/bin/yq
34
-
35
- - name: Determine environments
36
- id: set-matrix
37
- run: |
38
- ENVS="[]"
39
-
40
- if [ "${{ inputs.environment }}" == "all" ]; then
41
- # Check which environments are configured
42
- HAS_STAGING=$(yq eval '.staging != null' factiii.yml)
43
- HAS_PROD=$(yq eval '.prod != null' factiii.yml)
44
-
45
- if [ "$HAS_STAGING" == "true" ] && [ "$HAS_PROD" == "true" ]; then
46
- ENVS='["staging", "prod"]'
47
- elif [ "$HAS_STAGING" == "true" ]; then
48
- ENVS='["staging"]'
49
- elif [ "$HAS_PROD" == "true" ]; then
50
- ENVS='["prod"]'
51
- fi
52
- else
53
- ENVS='["${{ inputs.environment }}"]'
54
- fi
55
-
56
- echo "matrix={\"environment\":$ENVS}" >> $GITHUB_OUTPUT
57
-
58
- fix:
59
- needs: setup
60
- runs-on: ubuntu-latest
61
- strategy:
62
- fail-fast: false
63
- matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
64
- steps:
65
- - name: Checkout code
66
- uses: actions/checkout@v4
67
-
68
- - name: Install yq
69
- run: |
70
- sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
71
- sudo chmod +x /usr/local/bin/yq
72
-
73
- - name: Read config
74
- id: config
75
- env:
76
- ENVIRONMENT: ${{ matrix.environment }}
77
- run: |
78
- if [ ! -f "factiii.yml" ]; then
79
- echo "❌ factiii.yml not found"
80
- exit 1
81
- fi
82
-
83
- REPO_NAME=$(yq eval '.name' factiii.yml)
84
- HOST=$(yq eval ".$ENVIRONMENT.domain // \"\"" factiii.yml)
85
- SSH_USER=$(yq eval ".$ENVIRONMENT.ssh_user // \"ubuntu\"" factiii.yml)
86
-
87
- echo "repo_name=$REPO_NAME" >> $GITHUB_OUTPUT
88
- echo "host=$HOST" >> $GITHUB_OUTPUT
89
- echo "ssh_user=$SSH_USER" >> $GITHUB_OUTPUT
90
-
91
- - name: Check if environment configured
92
- id: check_env
93
- env:
94
- ENVIRONMENT: ${{ matrix.environment }}
95
- run: |
96
- HAS_ENV=$(yq eval ".$ENVIRONMENT != null" factiii.yml)
97
- echo "has_env=$HAS_ENV" >> $GITHUB_OUTPUT
98
-
99
- if [ "$HAS_ENV" != "true" ]; then
100
- echo "⏭️ $ENVIRONMENT environment not configured in factiii.yml"
101
- exit 0
102
- fi
103
-
104
- - name: Check SSH secret
105
- if: steps.check_env.outputs.has_env == 'true'
106
- env:
107
- ENVIRONMENT: ${{ matrix.environment }}
108
- SSH_KEY: ${{ matrix.environment == 'staging' && secrets.STAGING_SSH || secrets.PROD_SSH }}
109
- run: |
110
- if [ -z "$SSH_KEY" ]; then
111
- SECRET_NAME="${ENVIRONMENT^^}_SSH"
112
- echo "❌ ${SECRET_NAME} secret not found"
113
- echo "Add it at: https://github.com/${{ github.repository }}/settings/secrets/actions"
114
- exit 1
115
- fi
116
- echo "✅ SSH secret exists for $ENVIRONMENT"
117
-
118
- - name: Setup SSH
119
- if: steps.check_env.outputs.has_env == 'true'
120
- env:
121
- SSH_KEY: ${{ matrix.environment == 'staging' && secrets.STAGING_SSH || secrets.PROD_SSH }}
122
- run: |
123
- mkdir -p ~/.ssh
124
- echo "$SSH_KEY" > ~/.ssh/deploy_key
125
- chmod 600 ~/.ssh/deploy_key
126
-
127
- - name: Bootstrap Node.js (one-time)
128
- if: steps.check_env.outputs.has_env == 'true'
129
- env:
130
- HOST: ${{ steps.config.outputs.host }}
131
- USER: ${{ steps.config.outputs.ssh_user }}
132
- run: |
133
- echo "🔍 Checking Node.js on server..."
134
- ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no "$USER@$HOST" \
135
- 'if ! command -v node &> /dev/null; then
136
- echo "📦 Installing Node.js...";
137
- if [ -f /opt/homebrew/bin/brew ] || [ -f /usr/local/bin/brew ]; then
138
- export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH";
139
- brew install node;
140
- else
141
- curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y nodejs;
142
- fi;
143
- else
144
- echo "✅ Node.js already installed";
145
- fi'
146
-
147
- - name: Fix via SSH
148
- if: steps.check_env.outputs.has_env == 'true'
149
- env:
150
- HOST: ${{ steps.config.outputs.host }}
151
- USER: ${{ steps.config.outputs.ssh_user }}
152
- REPO_NAME: ${{ steps.config.outputs.repo_name }}
153
- ENVIRONMENT: ${{ matrix.environment }}
154
- run: |
155
- if [ -z "$HOST" ]; then
156
- echo "❌ Missing domain in factiii.yml: $ENVIRONMENT.domain"
157
- exit 1
158
- fi
159
-
160
- echo "🔧 Fixing $ENVIRONMENT ($HOST)..."
161
-
162
- ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ServerAliveInterval=60 -o ServerAliveCountMax=5 "$USER@$HOST" \
163
- "export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
164
- REPO_DIR=\"\$HOME/.factiii/$REPO_NAME\" && \
165
- if [ -d \"\$REPO_DIR\" ]; then \
166
- cd \"\$REPO_DIR\" && \
167
- export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH" && \
168
- GITHUB_ACTIONS=true npx factiii fix --$ENVIRONMENT; \
169
- else \
170
- echo \"❌ Repo directory not found at \$REPO_DIR\"; \
171
- echo \"Run deployment first to clone the repository\"; \
172
- exit 1; \
173
- fi"
174
-
175
- rm -f ~/.ssh/deploy_key
176
- echo "✅ $ENVIRONMENT fix complete!"
@@ -1,103 +0,0 @@
1
- name: Factiii PR Check
2
-
3
- # Generated by @factiii/stack v{VERSION}
4
- # Validates server/client/mobile builds when PR opens to main.
5
- # SSH to staging, run builds, report status to GitHub.
6
-
7
- on:
8
- pull_request:
9
- branches:
10
- - main
11
-
12
- jobs:
13
- pr-check:
14
- runs-on: ubuntu-latest
15
- steps:
16
- - name: Checkout code
17
- uses: actions/checkout@v4
18
-
19
- - name: Install yq
20
- run: |
21
- sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
22
- sudo chmod +x /usr/local/bin/yq
23
-
24
- - name: Read config
25
- id: config
26
- run: |
27
- if [ ! -f "factiii.yml" ]; then
28
- echo "❌ factiii.yml not found"
29
- exit 1
30
- fi
31
-
32
- REPO_NAME=$(yq eval '.name' factiii.yml)
33
- HOST=$(yq eval '.staging.domain // ""' factiii.yml)
34
- SSH_USER=$(yq eval '.staging.ssh_user // "ubuntu"' factiii.yml)
35
-
36
- echo "repo_name=$REPO_NAME" >> $GITHUB_OUTPUT
37
- echo "host=$HOST" >> $GITHUB_OUTPUT
38
- echo "ssh_user=$SSH_USER" >> $GITHUB_OUTPUT
39
-
40
- - name: Check if staging configured
41
- id: check_staging
42
- run: |
43
- HAS_STAGING=$(yq eval '.staging != null' factiii.yml)
44
- echo "has_staging=$HAS_STAGING" >> $GITHUB_OUTPUT
45
-
46
- if [ "$HAS_STAGING" != "true" ]; then
47
- echo "⏭️ Staging not configured - skipping PR check"
48
- exit 0
49
- fi
50
-
51
- - name: Setup SSH
52
- if: steps.check_staging.outputs.has_staging == 'true'
53
- env:
54
- SSH_KEY: ${{ secrets.STAGING_SSH }}
55
- run: |
56
- if [ -z "$SSH_KEY" ]; then
57
- echo "❌ Missing STAGING_SSH secret"
58
- exit 1
59
- fi
60
-
61
- mkdir -p ~/.ssh
62
- echo "$SSH_KEY" > ~/.ssh/deploy_key
63
- chmod 600 ~/.ssh/deploy_key
64
-
65
- - name: Run PR check on staging
66
- if: steps.check_staging.outputs.has_staging == 'true'
67
- env:
68
- HOST: ${{ steps.config.outputs.host }}
69
- USER: ${{ steps.config.outputs.ssh_user }}
70
- REPO_NAME: ${{ steps.config.outputs.repo_name }}
71
- COMMIT_HASH: ${{ github.event.pull_request.head.sha }}
72
- BRANCH: ${{ github.event.pull_request.head.ref }}
73
- PR_NUMBER: ${{ github.event.pull_request.number }}
74
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
75
- run: |
76
- if [ -z "$HOST" ]; then
77
- echo "❌ Missing staging.domain in factiii.yml"
78
- exit 1
79
- fi
80
-
81
- echo "🔍 Running PR check on staging ($HOST)..."
82
-
83
- GITHUB_TOKEN_B64=$(echo -n "$GITHUB_TOKEN" | base64 -w 0)
84
- ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no "$USER@$HOST" \
85
- "export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
86
- export GITHUB_TOKEN=\$(echo \"$GITHUB_TOKEN_B64\" | base64 -d) && \
87
- export GITHUB_ACTIONS=true COMMIT_HASH=$COMMIT_HASH BRANCH=$BRANCH PR_NUMBER=$PR_NUMBER && \
88
- REPO_DIR=\"\$HOME/.factiii/$REPO_NAME\" && \
89
- if [ -d \"\$REPO_DIR\" ]; then \
90
- cd \"\$REPO_DIR\" && npx factiii pr-check --staging; \
91
- else \
92
- echo \"❌ Repo not found at \$REPO_DIR\"; exit 1; \
93
- fi"
94
-
95
- EXIT_CODE=$?
96
- rm -f ~/.ssh/deploy_key
97
-
98
- if [ $EXIT_CODE -eq 0 ]; then
99
- echo "✅ PR check passed"
100
- else
101
- echo "❌ PR check failed"
102
- exit $EXIT_CODE
103
- fi