@factiii/stack 0.1.25 → 0.1.27

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 (52) hide show
  1. package/dist/cli/init.d.ts.map +1 -1
  2. package/dist/cli/init.js +285 -6
  3. package/dist/cli/init.js.map +1 -1
  4. package/dist/cli/scan.d.ts.map +1 -1
  5. package/dist/cli/scan.js +28 -13
  6. package/dist/cli/scan.js.map +1 -1
  7. package/dist/constants/config-files.d.ts +6 -0
  8. package/dist/constants/config-files.d.ts.map +1 -1
  9. package/dist/constants/config-files.js +16 -1
  10. package/dist/constants/config-files.js.map +1 -1
  11. package/dist/plugins/pipelines/factiii/index.d.ts +5 -3
  12. package/dist/plugins/pipelines/factiii/index.d.ts.map +1 -1
  13. package/dist/plugins/pipelines/factiii/index.js +14 -77
  14. package/dist/plugins/pipelines/factiii/index.js.map +1 -1
  15. package/dist/plugins/pipelines/factiii/scanfix/env-files.d.ts +12 -0
  16. package/dist/plugins/pipelines/factiii/scanfix/env-files.d.ts.map +1 -0
  17. package/dist/plugins/pipelines/factiii/scanfix/env-files.js +310 -0
  18. package/dist/plugins/pipelines/factiii/scanfix/env-files.js.map +1 -0
  19. package/dist/plugins/pipelines/factiii/scanfix/local-config.d.ts +7 -0
  20. package/dist/plugins/pipelines/factiii/scanfix/local-config.d.ts.map +1 -0
  21. package/dist/plugins/pipelines/factiii/scanfix/local-config.js +70 -0
  22. package/dist/plugins/pipelines/factiii/scanfix/local-config.js.map +1 -0
  23. package/dist/plugins/pipelines/factiii/scanfix/workflows.d.ts.map +1 -1
  24. package/dist/plugins/pipelines/factiii/scanfix/workflows.js +10 -24
  25. package/dist/plugins/pipelines/factiii/scanfix/workflows.js.map +1 -1
  26. package/dist/plugins/pipelines/factiii/utils/workflows.d.ts.map +1 -1
  27. package/dist/plugins/pipelines/factiii/utils/workflows.js +5 -20
  28. package/dist/plugins/pipelines/factiii/utils/workflows.js.map +1 -1
  29. package/dist/plugins/pipelines/factiii/workflows/stack-ci.yml +56 -0
  30. package/dist/plugins/pipelines/factiii/workflows/stack-cicd-prod.yml +35 -96
  31. package/dist/utils/config-helpers.d.ts +15 -0
  32. package/dist/utils/config-helpers.d.ts.map +1 -1
  33. package/dist/utils/config-helpers.js +57 -5
  34. package/dist/utils/config-helpers.js.map +1 -1
  35. package/package.json +1 -1
  36. package/dist/plugins/pipelines/factiii/workflows/factiii-cicd-prod.yml +0 -115
  37. package/dist/plugins/pipelines/factiii/workflows/factiii-cicd-staging.yml +0 -120
  38. package/dist/plugins/pipelines/factiii/workflows/factiii-command.yml +0 -132
  39. package/dist/plugins/pipelines/factiii/workflows/factiii-deploy.yml +0 -202
  40. package/dist/plugins/pipelines/factiii/workflows/factiii-dev-sync.yml +0 -181
  41. package/dist/plugins/pipelines/factiii/workflows/factiii-fix.yml +0 -178
  42. package/dist/plugins/pipelines/factiii/workflows/factiii-pr-check.yml +0 -106
  43. package/dist/plugins/pipelines/factiii/workflows/factiii-scan.yml +0 -183
  44. package/dist/plugins/pipelines/factiii/workflows/factiii-undeploy.yml +0 -96
  45. package/dist/plugins/pipelines/factiii/workflows/stack-cicd-staging.yml +0 -120
  46. package/dist/plugins/pipelines/factiii/workflows/stack-command.yml +0 -132
  47. package/dist/plugins/pipelines/factiii/workflows/stack-deploy.yml +0 -202
  48. package/dist/plugins/pipelines/factiii/workflows/stack-dev-sync.yml +0 -181
  49. package/dist/plugins/pipelines/factiii/workflows/stack-fix.yml +0 -177
  50. package/dist/plugins/pipelines/factiii/workflows/stack-pr-check.yml +0 -106
  51. package/dist/plugins/pipelines/factiii/workflows/stack-scan.yml +0 -182
  52. package/dist/plugins/pipelines/factiii/workflows/stack-undeploy.yml +0 -96
@@ -1,181 +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
- CONFIG_FILE="stack.yml"; if [ ! -f "$CONFIG_FILE" ]; then CONFIG_FILE="factiii.yml"; fi
51
- if [ ! -f "$CONFIG_FILE" ]; then
52
- echo "❌ stack.yml or factiii.yml not found"
53
- exit 1
54
- fi
55
-
56
- REPO_NAME=$(yq eval '.name' "$CONFIG_FILE")
57
-
58
- if [ "${{ inputs.environment }}" == "staging" ]; then
59
- HOST=$(yq eval '.staging.domain // ""' "$CONFIG_FILE")
60
- SSH_USER=$(yq eval '.staging.ssh_user // "ubuntu"' "$CONFIG_FILE")
61
- else
62
- HOST=$(yq eval '.prod.domain // ""' "$CONFIG_FILE")
63
- SSH_USER=$(yq eval '.prod.ssh_user // "ubuntu"' "$CONFIG_FILE")
64
- fi
65
-
66
- echo "repo_name=$REPO_NAME" >> $GITHUB_OUTPUT
67
- echo "host=$HOST" >> $GITHUB_OUTPUT
68
- echo "ssh_user=$SSH_USER" >> $GITHUB_OUTPUT
69
-
70
- - name: Check if environment configured
71
- id: check_env
72
- run: |
73
- CONFIG_FILE="stack.yml"; if [ ! -f "$CONFIG_FILE" ]; then CONFIG_FILE="factiii.yml"; fi
74
- if [ "${{ inputs.environment }}" == "staging" ]; then
75
- HAS_ENV=$(yq eval '.staging != null' "$CONFIG_FILE")
76
- else
77
- HAS_ENV=$(yq eval '.prod != null' "$CONFIG_FILE")
78
- fi
79
-
80
- echo "has_env=$HAS_ENV" >> $GITHUB_OUTPUT
81
-
82
- if [ "$HAS_ENV" != "true" ]; then
83
- echo "⏭️ ${{ inputs.environment }} not configured in config"
84
- exit 1
85
- fi
86
-
87
- - name: Setup SSH
88
- if: steps.check_env.outputs.has_env == 'true'
89
- env:
90
- SSH_KEY: ${{ inputs.environment == 'staging' && secrets.STAGING_SSH || secrets.PROD_SSH }}
91
- run: |
92
- if [ -z "$SSH_KEY" ]; then
93
- echo "❌ Missing ${{ inputs.environment == 'staging' && 'STAGING_SSH' || 'PROD_SSH' }} secret"
94
- exit 1
95
- fi
96
-
97
- mkdir -p ~/.ssh
98
- echo "$SSH_KEY" > ~/.ssh/deploy_key
99
- chmod 600 ~/.ssh/deploy_key
100
-
101
- - name: Download infrastructure artifact from release
102
- if: steps.check_env.outputs.has_env == 'true'
103
- env:
104
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
105
- RELEASE_ID: ${{ inputs.release_id }}
106
- ASSET_ID: ${{ inputs.asset_id }}
107
- run: |
108
- echo "⚠️ DEV SYNC MODE - Using infrastructure from local build"
109
- echo " This syncs uncommitted infrastructure changes for testing"
110
- echo " Release ID: $RELEASE_ID"
111
- echo " Asset ID: $ASSET_ID"
112
-
113
- echo "📦 Downloading infrastructure artifact..."
114
-
115
- # Download release asset using GitHub API
116
- curl -L \
117
- -H "Accept: application/octet-stream" \
118
- -H "Authorization: Bearer $GITHUB_TOKEN" \
119
- -H "X-GitHub-Api-Version: 2022-11-28" \
120
- "https://api.github.com/repos/${{ github.repository }}/releases/assets/$ASSET_ID" \
121
- -o infrastructure.tar.gz
122
-
123
- # Verify download
124
- if [ ! -f infrastructure.tar.gz ]; then
125
- echo "❌ Failed to download artifact"
126
- exit 1
127
- fi
128
-
129
- SIZE=$(du -h infrastructure.tar.gz | cut -f1)
130
- echo "✅ Downloaded artifact ($SIZE)"
131
-
132
- - name: Deploy infrastructure to server
133
- if: steps.check_env.outputs.has_env == 'true'
134
- env:
135
- HOST: ${{ steps.config.outputs.host }}
136
- USER: ${{ steps.config.outputs.ssh_user }}
137
- DEPLOY: ${{ inputs.deploy }}
138
- REPO_NAME: ${{ steps.config.outputs.repo_name }}
139
- ENVIRONMENT: ${{ inputs.environment }}
140
- run: |
141
- if [ -z "$HOST" ]; then
142
- echo "❌ Missing domain in config: $ENVIRONMENT.domain"
143
- exit 1
144
- fi
145
-
146
- echo "🚀 Syncing infrastructure to $ENVIRONMENT ($HOST)..."
147
-
148
- # Copy infrastructure to server
149
- echo "📤 Uploading infrastructure package..."
150
- scp -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no infrastructure.tar.gz "$USER@$HOST:/tmp/"
151
-
152
- # Extract and setup on server
153
- echo "📦 Extracting infrastructure on server..."
154
- ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no "$USER@$HOST" \
155
- "export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
156
- echo \"📦 Setting up infrastructure...\" && \
157
- mkdir -p ~/.factiii/infrastructure && \
158
- cd ~/.factiii/infrastructure && \
159
- tar -xzf /tmp/infrastructure.tar.gz && \
160
- rm /tmp/infrastructure.tar.gz && \
161
- echo \"\" && \
162
- echo \"📋 Verifying version...\" && \
163
- VERSION=\$(cat package.json | grep '\"version\"' | head -1 | sed 's/.*: \"\(.*\)\".*/\1/') && \
164
- echo \" Version: \$VERSION\" && \
165
- echo \"\" && \
166
- echo \"✅ Infrastructure synced successfully\""
167
-
168
- # Optionally deploy
169
- if [ "$DEPLOY" == "true" ]; then
170
- echo ""
171
- echo "🚀 Deploying to $ENVIRONMENT..."
172
- ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no "$USER@$HOST" \
173
- "export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
174
- cd ~/.factiii/$REPO_NAME && \
175
- GITHUB_ACTIONS=true node ~/.factiii/infrastructure/bin/factiii deploy --$ENVIRONMENT"
176
- fi
177
-
178
- rm -f ~/.ssh/deploy_key
179
- echo ""
180
- echo "✅ Dev sync complete!"
181
-
@@ -1,178 +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
- CONFIG_FILE="stack.yml"; if [ ! -f "$CONFIG_FILE" ]; then CONFIG_FILE="factiii.yml"; fi
41
- if [ "${{ inputs.environment }}" == "all" ]; then
42
- HAS_STAGING=$(yq eval '.staging != null' "$CONFIG_FILE")
43
- HAS_PROD=$(yq eval '.prod != null' "$CONFIG_FILE")
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
- CONFIG_FILE="stack.yml"; if [ ! -f "$CONFIG_FILE" ]; then CONFIG_FILE="factiii.yml"; fi
79
- if [ ! -f "$CONFIG_FILE" ]; then
80
- echo "❌ stack.yml or factiii.yml not found"
81
- exit 1
82
- fi
83
-
84
- REPO_NAME=$(yq eval '.name' "$CONFIG_FILE")
85
- HOST=$(yq eval ".$ENVIRONMENT.domain // \"\"" "$CONFIG_FILE")
86
- SSH_USER=$(yq eval ".$ENVIRONMENT.ssh_user // \"ubuntu\"" "$CONFIG_FILE")
87
-
88
- echo "repo_name=$REPO_NAME" >> $GITHUB_OUTPUT
89
- echo "host=$HOST" >> $GITHUB_OUTPUT
90
- echo "ssh_user=$SSH_USER" >> $GITHUB_OUTPUT
91
-
92
- - name: Check if environment configured
93
- id: check_env
94
- env:
95
- ENVIRONMENT: ${{ matrix.environment }}
96
- run: |
97
- CONFIG_FILE="stack.yml"; if [ ! -f "$CONFIG_FILE" ]; then CONFIG_FILE="factiii.yml"; fi
98
- HAS_ENV=$(yq eval ".$ENVIRONMENT != null" "$CONFIG_FILE")
99
- echo "has_env=$HAS_ENV" >> $GITHUB_OUTPUT
100
-
101
- if [ "$HAS_ENV" != "true" ]; then
102
- echo "⏭️ $ENVIRONMENT not configured"
103
- exit 0
104
- fi
105
-
106
- - name: Check SSH secret
107
- if: steps.check_env.outputs.has_env == 'true'
108
- env:
109
- ENVIRONMENT: ${{ matrix.environment }}
110
- SSH_KEY: ${{ matrix.environment == 'staging' && secrets.STAGING_SSH || secrets.PROD_SSH }}
111
- run: |
112
- if [ -z "$SSH_KEY" ]; then
113
- SECRET_NAME="${ENVIRONMENT^^}_SSH"
114
- echo "❌ ${SECRET_NAME} secret not found"
115
- echo "Add it at: https://github.com/${{ github.repository }}/settings/secrets/actions"
116
- exit 1
117
- fi
118
- echo "✅ SSH secret exists for $ENVIRONMENT"
119
-
120
- - name: Setup SSH
121
- if: steps.check_env.outputs.has_env == 'true'
122
- env:
123
- SSH_KEY: ${{ matrix.environment == 'staging' && secrets.STAGING_SSH || secrets.PROD_SSH }}
124
- run: |
125
- mkdir -p ~/.ssh
126
- echo "$SSH_KEY" > ~/.ssh/deploy_key
127
- chmod 600 ~/.ssh/deploy_key
128
-
129
- - name: Bootstrap Node.js (one-time)
130
- if: steps.check_env.outputs.has_env == 'true'
131
- env:
132
- HOST: ${{ steps.config.outputs.host }}
133
- USER: ${{ steps.config.outputs.ssh_user }}
134
- run: |
135
- echo "🔍 Checking Node.js on server..."
136
- ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no "$USER@$HOST" \
137
- 'if ! command -v node &> /dev/null; then
138
- echo "📦 Installing Node.js...";
139
- if [ -f /opt/homebrew/bin/brew ] || [ -f /usr/local/bin/brew ]; then
140
- export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH";
141
- brew install node;
142
- else
143
- curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y nodejs;
144
- fi;
145
- else
146
- echo "✅ Node.js already installed";
147
- fi'
148
-
149
- - name: Fix via SSH
150
- if: steps.check_env.outputs.has_env == 'true'
151
- env:
152
- HOST: ${{ steps.config.outputs.host }}
153
- USER: ${{ steps.config.outputs.ssh_user }}
154
- REPO_NAME: ${{ steps.config.outputs.repo_name }}
155
- ENVIRONMENT: ${{ matrix.environment }}
156
- run: |
157
- if [ -z "$HOST" ]; then
158
- echo "❌ Missing domain in config: $ENVIRONMENT.domain"
159
- exit 1
160
- fi
161
-
162
- echo "🔧 Fixing $ENVIRONMENT ($HOST)..."
163
-
164
- ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ServerAliveInterval=60 -o ServerAliveCountMax=5 "$USER@$HOST" \
165
- "export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
166
- REPO_DIR=\"\$HOME/.factiii/$REPO_NAME\" && \
167
- if [ -d \"\$REPO_DIR\" ]; then \
168
- cd \"\$REPO_DIR\" && \
169
- export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH" && \
170
- GITHUB_ACTIONS=true npx factiii fix --$ENVIRONMENT; \
171
- else \
172
- echo \"❌ Repo directory not found at \$REPO_DIR\"; \
173
- echo \"Run deployment first to clone the repository\"; \
174
- exit 1; \
175
- fi"
176
-
177
- rm -f ~/.ssh/deploy_key
178
- echo "✅ $ENVIRONMENT fix complete!"
@@ -1,106 +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
- CONFIG_FILE="stack.yml"
28
- if [ ! -f "$CONFIG_FILE" ]; then CONFIG_FILE="factiii.yml"; fi
29
- if [ ! -f "$CONFIG_FILE" ]; then
30
- echo "❌ stack.yml or factiii.yml not found"
31
- exit 1
32
- fi
33
-
34
- REPO_NAME=$(yq eval '.name' "$CONFIG_FILE")
35
- HOST=$(yq eval '.staging.domain // ""' "$CONFIG_FILE")
36
- SSH_USER=$(yq eval '.staging.ssh_user // "ubuntu"' "$CONFIG_FILE")
37
-
38
- echo "repo_name=$REPO_NAME" >> $GITHUB_OUTPUT
39
- echo "host=$HOST" >> $GITHUB_OUTPUT
40
- echo "ssh_user=$SSH_USER" >> $GITHUB_OUTPUT
41
-
42
- - name: Check if staging configured
43
- id: check_staging
44
- run: |
45
- CONFIG_FILE="stack.yml"; if [ ! -f "$CONFIG_FILE" ]; then CONFIG_FILE="factiii.yml"; fi
46
- HAS_STAGING=$(yq eval '.staging != null' "$CONFIG_FILE")
47
- echo "has_staging=$HAS_STAGING" >> $GITHUB_OUTPUT
48
-
49
- if [ "$HAS_STAGING" != "true" ]; then
50
- echo "⏭️ Staging not configured - skipping PR check"
51
- exit 0
52
- fi
53
-
54
- - name: Setup SSH
55
- if: steps.check_staging.outputs.has_staging == 'true'
56
- env:
57
- SSH_KEY: ${{ secrets.STAGING_SSH }}
58
- run: |
59
- if [ -z "$SSH_KEY" ]; then
60
- echo "❌ Missing STAGING_SSH secret"
61
- exit 1
62
- fi
63
-
64
- mkdir -p ~/.ssh
65
- echo "$SSH_KEY" > ~/.ssh/deploy_key
66
- chmod 600 ~/.ssh/deploy_key
67
-
68
- - name: Run PR check on staging
69
- if: steps.check_staging.outputs.has_staging == 'true'
70
- env:
71
- HOST: ${{ steps.config.outputs.host }}
72
- USER: ${{ steps.config.outputs.ssh_user }}
73
- REPO_NAME: ${{ steps.config.outputs.repo_name }}
74
- COMMIT_HASH: ${{ github.event.pull_request.head.sha }}
75
- BRANCH: ${{ github.event.pull_request.head.ref }}
76
- PR_NUMBER: ${{ github.event.pull_request.number }}
77
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
78
- run: |
79
- if [ -z "$HOST" ]; then
80
- echo "❌ Missing staging.domain in config"
81
- exit 1
82
- fi
83
-
84
- echo "🔍 Running PR check on staging ($HOST)..."
85
-
86
- GITHUB_TOKEN_B64=$(echo -n "$GITHUB_TOKEN" | base64 -w 0)
87
- ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no "$USER@$HOST" \
88
- "export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
89
- export GITHUB_TOKEN=\$(echo \"$GITHUB_TOKEN_B64\" | base64 -d) && \
90
- export GITHUB_ACTIONS=true COMMIT_HASH=$COMMIT_HASH BRANCH=$BRANCH PR_NUMBER=$PR_NUMBER && \
91
- REPO_DIR=\"\$HOME/.factiii/$REPO_NAME\" && \
92
- if [ -d \"\$REPO_DIR\" ]; then \
93
- cd \"\$REPO_DIR\" && npx factiii pr-check --staging; \
94
- else \
95
- echo \"❌ Repo not found at \$REPO_DIR\"; exit 1; \
96
- fi"
97
-
98
- EXIT_CODE=$?
99
- rm -f ~/.ssh/deploy_key
100
-
101
- if [ $EXIT_CODE -eq 0 ]; then
102
- echo "✅ PR check passed"
103
- else
104
- echo "❌ PR check failed"
105
- exit $EXIT_CODE
106
- fi
@@ -1,183 +0,0 @@
1
- name: Factiii Scan
2
-
3
- # Generated by @factiii/stack v{VERSION}
4
- # INFRASTRUCTURE: Scan servers for issues via CLI
5
- # Run: npx factiii scan (triggers this workflow for remote environments)
6
- # Runs on configured environments in parallel using matrix strategy
7
-
8
- on:
9
- workflow_dispatch:
10
- inputs:
11
- environment:
12
- description: 'Environment to scan'
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
- CONFIG_FILE="stack.yml"; if [ ! -f "$CONFIG_FILE" ]; then CONFIG_FILE="factiii.yml"; fi
39
- if [ ! -f "$CONFIG_FILE" ]; then
40
- echo "matrix={\"environment\":[]}" >> $GITHUB_OUTPUT
41
- echo "❌ stack.yml or factiii.yml not found"
42
- exit 1
43
- fi
44
- ENVS="[]"
45
-
46
- if [ "${{ inputs.environment }}" == "all" ]; then
47
- HAS_STAGING=$(yq eval '.staging != null' "$CONFIG_FILE")
48
- HAS_PROD=$(yq eval '.prod != null' "$CONFIG_FILE")
49
-
50
- if [ "$HAS_STAGING" == "true" ] && [ "$HAS_PROD" == "true" ]; then
51
- ENVS='["staging", "prod"]'
52
- elif [ "$HAS_STAGING" == "true" ]; then
53
- ENVS='["staging"]'
54
- elif [ "$HAS_PROD" == "true" ]; then
55
- ENVS='["prod"]'
56
- fi
57
- else
58
- ENVS='["${{ inputs.environment }}"]'
59
- fi
60
-
61
- echo "matrix={\"environment\":$ENVS}" >> $GITHUB_OUTPUT
62
-
63
- scan:
64
- needs: setup
65
- runs-on: ubuntu-latest
66
- strategy:
67
- fail-fast: false
68
- matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
69
- steps:
70
- - name: Checkout code
71
- uses: actions/checkout@v4
72
-
73
- - name: Install yq
74
- run: |
75
- sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
76
- sudo chmod +x /usr/local/bin/yq
77
-
78
- - name: Read config
79
- id: config
80
- env:
81
- ENVIRONMENT: ${{ matrix.environment }}
82
- run: |
83
- CONFIG_FILE="stack.yml"; if [ ! -f "$CONFIG_FILE" ]; then CONFIG_FILE="factiii.yml"; fi
84
- if [ ! -f "$CONFIG_FILE" ]; then
85
- echo "❌ stack.yml or factiii.yml not found"
86
- exit 1
87
- fi
88
-
89
- REPO_NAME=$(yq eval '.name' "$CONFIG_FILE")
90
- HOST=$(yq eval ".$ENVIRONMENT.domain // \"\"" "$CONFIG_FILE")
91
- SSH_USER=$(yq eval ".$ENVIRONMENT.ssh_user // \"ubuntu\"" "$CONFIG_FILE")
92
-
93
- echo "repo_name=$REPO_NAME" >> $GITHUB_OUTPUT
94
- echo "host=$HOST" >> $GITHUB_OUTPUT
95
- echo "ssh_user=$SSH_USER" >> $GITHUB_OUTPUT
96
-
97
- - name: Check if environment configured
98
- id: check_env
99
- env:
100
- ENVIRONMENT: ${{ matrix.environment }}
101
- run: |
102
- CONFIG_FILE="stack.yml"; if [ ! -f "$CONFIG_FILE" ]; then CONFIG_FILE="factiii.yml"; fi
103
- HAS_ENV=$(yq eval ".$ENVIRONMENT != null" "$CONFIG_FILE")
104
- echo "has_env=$HAS_ENV" >> $GITHUB_OUTPUT
105
-
106
- if [ "$HAS_ENV" != "true" ]; then
107
- echo "⏭️ $ENVIRONMENT not configured"
108
- exit 0
109
- fi
110
-
111
- - name: Check SSH secret
112
- if: steps.check_env.outputs.has_env == 'true'
113
- env:
114
- ENVIRONMENT: ${{ matrix.environment }}
115
- SSH_KEY: ${{ matrix.environment == 'staging' && secrets.STAGING_SSH || secrets.PROD_SSH }}
116
- run: |
117
- if [ -z "$SSH_KEY" ]; then
118
- SECRET_NAME="${ENVIRONMENT^^}_SSH"
119
- echo "❌ ${SECRET_NAME} secret not found"
120
- echo "Add it at: https://github.com/${{ github.repository }}/settings/secrets/actions"
121
- exit 1
122
- fi
123
- echo "✅ SSH secret exists for $ENVIRONMENT"
124
-
125
- - name: Setup SSH
126
- if: steps.check_env.outputs.has_env == 'true'
127
- env:
128
- SSH_KEY: ${{ matrix.environment == 'staging' && secrets.STAGING_SSH || secrets.PROD_SSH }}
129
- run: |
130
- mkdir -p ~/.ssh
131
- echo "$SSH_KEY" > ~/.ssh/deploy_key
132
- chmod 600 ~/.ssh/deploy_key
133
-
134
- - name: Bootstrap Node.js (one-time)
135
- if: steps.check_env.outputs.has_env == 'true'
136
- env:
137
- HOST: ${{ steps.config.outputs.host }}
138
- USER: ${{ steps.config.outputs.ssh_user }}
139
- run: |
140
- echo "🔍 Checking Node.js on server..."
141
- ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no "$USER@$HOST" \
142
- 'if ! command -v node &> /dev/null; then
143
- echo "📦 Installing Node.js...";
144
- if [ -f /opt/homebrew/bin/brew ] || [ -f /usr/local/bin/brew ]; then
145
- export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH";
146
- brew install node;
147
- else
148
- curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y nodejs;
149
- fi;
150
- else
151
- echo "✅ Node.js already installed";
152
- fi'
153
-
154
- - name: Scan via SSH
155
- if: steps.check_env.outputs.has_env == 'true'
156
- env:
157
- HOST: ${{ steps.config.outputs.host }}
158
- USER: ${{ steps.config.outputs.ssh_user }}
159
- REPO_NAME: ${{ steps.config.outputs.repo_name }}
160
- ENVIRONMENT: ${{ matrix.environment }}
161
- run: |
162
- if [ -z "$HOST" ]; then
163
- echo "❌ Missing domain in config: $ENVIRONMENT.domain"
164
- exit 1
165
- fi
166
-
167
- echo "🔍 Scanning $ENVIRONMENT ($HOST)..."
168
-
169
- ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no "$USER@$HOST" \
170
- "export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
171
- REPO_DIR=\"\$HOME/.factiii/$REPO_NAME\" && \
172
- if [ -d \"\$REPO_DIR\" ]; then \
173
- cd \"\$REPO_DIR\" && \
174
- export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH" && \
175
- GITHUB_ACTIONS=true npx factiii scan --$ENVIRONMENT; \
176
- else \
177
- echo \"❌ Repo directory not found at \$REPO_DIR\"; \
178
- echo \"Run deployment first to clone the repository\"; \
179
- exit 1; \
180
- fi"
181
-
182
- rm -f ~/.ssh/deploy_key
183
- echo "✅ $ENVIRONMENT scan complete!"