@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.
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +285 -6
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/scan.d.ts.map +1 -1
- package/dist/cli/scan.js +28 -13
- package/dist/cli/scan.js.map +1 -1
- package/dist/constants/config-files.d.ts +6 -0
- package/dist/constants/config-files.d.ts.map +1 -1
- package/dist/constants/config-files.js +16 -1
- package/dist/constants/config-files.js.map +1 -1
- package/dist/plugins/pipelines/factiii/index.d.ts +5 -3
- package/dist/plugins/pipelines/factiii/index.d.ts.map +1 -1
- package/dist/plugins/pipelines/factiii/index.js +14 -77
- package/dist/plugins/pipelines/factiii/index.js.map +1 -1
- package/dist/plugins/pipelines/factiii/scanfix/env-files.d.ts +12 -0
- package/dist/plugins/pipelines/factiii/scanfix/env-files.d.ts.map +1 -0
- package/dist/plugins/pipelines/factiii/scanfix/env-files.js +310 -0
- package/dist/plugins/pipelines/factiii/scanfix/env-files.js.map +1 -0
- package/dist/plugins/pipelines/factiii/scanfix/local-config.d.ts +7 -0
- package/dist/plugins/pipelines/factiii/scanfix/local-config.d.ts.map +1 -0
- package/dist/plugins/pipelines/factiii/scanfix/local-config.js +70 -0
- package/dist/plugins/pipelines/factiii/scanfix/local-config.js.map +1 -0
- package/dist/plugins/pipelines/factiii/scanfix/workflows.d.ts.map +1 -1
- package/dist/plugins/pipelines/factiii/scanfix/workflows.js +10 -24
- package/dist/plugins/pipelines/factiii/scanfix/workflows.js.map +1 -1
- package/dist/plugins/pipelines/factiii/utils/workflows.d.ts.map +1 -1
- package/dist/plugins/pipelines/factiii/utils/workflows.js +5 -20
- package/dist/plugins/pipelines/factiii/utils/workflows.js.map +1 -1
- package/dist/plugins/pipelines/factiii/workflows/stack-ci.yml +56 -0
- package/dist/plugins/pipelines/factiii/workflows/stack-cicd-prod.yml +35 -96
- package/dist/utils/config-helpers.d.ts +15 -0
- package/dist/utils/config-helpers.d.ts.map +1 -1
- package/dist/utils/config-helpers.js +57 -5
- package/dist/utils/config-helpers.js.map +1 -1
- package/package.json +1 -1
- package/dist/plugins/pipelines/factiii/workflows/factiii-cicd-prod.yml +0 -115
- package/dist/plugins/pipelines/factiii/workflows/factiii-cicd-staging.yml +0 -120
- package/dist/plugins/pipelines/factiii/workflows/factiii-command.yml +0 -132
- package/dist/plugins/pipelines/factiii/workflows/factiii-deploy.yml +0 -202
- package/dist/plugins/pipelines/factiii/workflows/factiii-dev-sync.yml +0 -181
- package/dist/plugins/pipelines/factiii/workflows/factiii-fix.yml +0 -178
- package/dist/plugins/pipelines/factiii/workflows/factiii-pr-check.yml +0 -106
- package/dist/plugins/pipelines/factiii/workflows/factiii-scan.yml +0 -183
- package/dist/plugins/pipelines/factiii/workflows/factiii-undeploy.yml +0 -96
- package/dist/plugins/pipelines/factiii/workflows/stack-cicd-staging.yml +0 -120
- package/dist/plugins/pipelines/factiii/workflows/stack-command.yml +0 -132
- package/dist/plugins/pipelines/factiii/workflows/stack-deploy.yml +0 -202
- package/dist/plugins/pipelines/factiii/workflows/stack-dev-sync.yml +0 -181
- package/dist/plugins/pipelines/factiii/workflows/stack-fix.yml +0 -177
- package/dist/plugins/pipelines/factiii/workflows/stack-pr-check.yml +0 -106
- package/dist/plugins/pipelines/factiii/workflows/stack-scan.yml +0 -182
- 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!"
|