@factiii/stack 0.1.2 → 0.1.8

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 (89) hide show
  1. package/bin/factiii +13 -0
  2. package/dist/cli/pr-check.d.ts +24 -0
  3. package/dist/cli/pr-check.d.ts.map +1 -0
  4. package/dist/cli/pr-check.js +153 -0
  5. package/dist/cli/pr-check.js.map +1 -0
  6. package/dist/plugins/addons/server-mode/index.d.ts.map +1 -1
  7. package/dist/plugins/addons/server-mode/index.js +3 -0
  8. package/dist/plugins/addons/server-mode/index.js.map +1 -1
  9. package/dist/plugins/addons/server-mode/scanfix/mac.d.ts +20 -3
  10. package/dist/plugins/addons/server-mode/scanfix/mac.d.ts.map +1 -1
  11. package/dist/plugins/addons/server-mode/scanfix/mac.js +304 -177
  12. package/dist/plugins/addons/server-mode/scanfix/mac.js.map +1 -1
  13. package/dist/plugins/addons/server-mode/scanfix/tart.d.ts +19 -0
  14. package/dist/plugins/addons/server-mode/scanfix/tart.d.ts.map +1 -0
  15. package/dist/plugins/addons/server-mode/scanfix/tart.js +350 -0
  16. package/dist/plugins/addons/server-mode/scanfix/tart.js.map +1 -0
  17. package/dist/plugins/pipelines/aws/configs/free-tier.d.ts.map +1 -1
  18. package/dist/plugins/pipelines/aws/configs/free-tier.js +3 -38
  19. package/dist/plugins/pipelines/aws/configs/free-tier.js.map +1 -1
  20. package/dist/plugins/pipelines/aws/index.d.ts +4 -1
  21. package/dist/plugins/pipelines/aws/index.d.ts.map +1 -1
  22. package/dist/plugins/pipelines/aws/index.js +101 -29
  23. package/dist/plugins/pipelines/aws/index.js.map +1 -1
  24. package/dist/plugins/pipelines/aws/scanfix/credentials.d.ts +9 -0
  25. package/dist/plugins/pipelines/aws/scanfix/credentials.d.ts.map +1 -0
  26. package/dist/plugins/pipelines/aws/scanfix/credentials.js +196 -0
  27. package/dist/plugins/pipelines/aws/scanfix/credentials.js.map +1 -0
  28. package/dist/plugins/pipelines/aws/scanfix/db-replication.d.ts +13 -0
  29. package/dist/plugins/pipelines/aws/scanfix/db-replication.d.ts.map +1 -0
  30. package/dist/plugins/pipelines/aws/scanfix/db-replication.js +136 -0
  31. package/dist/plugins/pipelines/aws/scanfix/db-replication.js.map +1 -0
  32. package/dist/plugins/pipelines/aws/scanfix/ec2.d.ts +10 -0
  33. package/dist/plugins/pipelines/aws/scanfix/ec2.d.ts.map +1 -0
  34. package/dist/plugins/pipelines/aws/scanfix/ec2.js +279 -0
  35. package/dist/plugins/pipelines/aws/scanfix/ec2.js.map +1 -0
  36. package/dist/plugins/pipelines/aws/scanfix/ecr.d.ts +9 -0
  37. package/dist/plugins/pipelines/aws/scanfix/ecr.d.ts.map +1 -0
  38. package/dist/plugins/pipelines/aws/scanfix/ecr.js +100 -0
  39. package/dist/plugins/pipelines/aws/scanfix/ecr.js.map +1 -0
  40. package/dist/plugins/pipelines/aws/scanfix/iam.d.ts +10 -0
  41. package/dist/plugins/pipelines/aws/scanfix/iam.d.ts.map +1 -0
  42. package/dist/plugins/pipelines/aws/scanfix/iam.js +255 -0
  43. package/dist/plugins/pipelines/aws/scanfix/iam.js.map +1 -0
  44. package/dist/plugins/pipelines/aws/scanfix/rds.d.ts +10 -0
  45. package/dist/plugins/pipelines/aws/scanfix/rds.d.ts.map +1 -0
  46. package/dist/plugins/pipelines/aws/scanfix/rds.js +261 -0
  47. package/dist/plugins/pipelines/aws/scanfix/rds.js.map +1 -0
  48. package/dist/plugins/pipelines/aws/scanfix/s3.d.ts +9 -0
  49. package/dist/plugins/pipelines/aws/scanfix/s3.d.ts.map +1 -0
  50. package/dist/plugins/pipelines/aws/scanfix/s3.js +134 -0
  51. package/dist/plugins/pipelines/aws/scanfix/s3.js.map +1 -0
  52. package/dist/plugins/pipelines/aws/scanfix/security-groups.d.ts +10 -0
  53. package/dist/plugins/pipelines/aws/scanfix/security-groups.d.ts.map +1 -0
  54. package/dist/plugins/pipelines/aws/scanfix/security-groups.js +225 -0
  55. package/dist/plugins/pipelines/aws/scanfix/security-groups.js.map +1 -0
  56. package/dist/plugins/pipelines/aws/scanfix/ses.d.ts +9 -0
  57. package/dist/plugins/pipelines/aws/scanfix/ses.d.ts.map +1 -0
  58. package/dist/plugins/pipelines/aws/scanfix/ses.js +174 -0
  59. package/dist/plugins/pipelines/aws/scanfix/ses.js.map +1 -0
  60. package/dist/plugins/pipelines/aws/scanfix/vpc.d.ts +9 -0
  61. package/dist/plugins/pipelines/aws/scanfix/vpc.d.ts.map +1 -0
  62. package/dist/plugins/pipelines/aws/scanfix/vpc.js +237 -0
  63. package/dist/plugins/pipelines/aws/scanfix/vpc.js.map +1 -0
  64. package/dist/plugins/pipelines/aws/utils/aws-helpers.d.ts +50 -0
  65. package/dist/plugins/pipelines/aws/utils/aws-helpers.d.ts.map +1 -0
  66. package/dist/plugins/pipelines/aws/utils/aws-helpers.js +137 -0
  67. package/dist/plugins/pipelines/aws/utils/aws-helpers.js.map +1 -0
  68. package/dist/plugins/pipelines/factiii/index.d.ts.map +1 -1
  69. package/dist/plugins/pipelines/factiii/index.js +11 -0
  70. package/dist/plugins/pipelines/factiii/index.js.map +1 -1
  71. package/dist/plugins/pipelines/factiii/pr-check.d.ts +35 -0
  72. package/dist/plugins/pipelines/factiii/pr-check.d.ts.map +1 -0
  73. package/dist/plugins/pipelines/factiii/pr-check.js +202 -0
  74. package/dist/plugins/pipelines/factiii/pr-check.js.map +1 -0
  75. package/dist/plugins/pipelines/factiii/utils/workflows.d.ts.map +1 -1
  76. package/dist/plugins/pipelines/factiii/utils/workflows.js +1 -0
  77. package/dist/plugins/pipelines/factiii/utils/workflows.js.map +1 -1
  78. package/dist/plugins/pipelines/factiii/workflows/factiii-cicd-staging.yml +8 -3
  79. package/dist/plugins/pipelines/factiii/workflows/factiii-pr-check.yml +103 -0
  80. package/dist/plugins/servers/mac/staging.d.ts.map +1 -1
  81. package/dist/plugins/servers/mac/staging.js +304 -52
  82. package/dist/plugins/servers/mac/staging.js.map +1 -1
  83. package/dist/types/config.d.ts +11 -0
  84. package/dist/types/config.d.ts.map +1 -1
  85. package/dist/utils/github-status.d.ts +39 -0
  86. package/dist/utils/github-status.d.ts.map +1 -0
  87. package/dist/utils/github-status.js +172 -0
  88. package/dist/utils/github-status.js.map +1 -0
  89. package/package.json +3 -3
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ /**
3
+ * PR Check - Build validation for pull requests
4
+ *
5
+ * Runs server (Docker), client (pnpm build), and mobile (EAS) builds.
6
+ * Used when PR opens to main - validates code builds before merge.
7
+ *
8
+ * Per STANDARDS: Build logic lives here, not in workflows.
9
+ * Workflow SSHs to staging and runs: GITHUB_ACTIONS=true npx factiii pr-check --staging
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.runBuilds = runBuilds;
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const child_process_1 = require("child_process");
49
+ const staging_js_1 = require("./staging.js");
50
+ /**
51
+ * Run all builds (server, client, mobile) on the current machine.
52
+ * Call this when GITHUB_ACTIONS=true or FACTIII_ON_SERVER=true (running on staging server).
53
+ *
54
+ * @param rootDir - Repo root (e.g. ~/.factiii/repo-name on server)
55
+ * @param config - factiii.yml config
56
+ * @param options - commit, branch for git checkout
57
+ */
58
+ async function runBuilds(rootDir, config, options = {}) {
59
+ const results = [];
60
+ const sha = options.commit ?? process.env.COMMIT_HASH ?? '';
61
+ const branch = options.branch ?? process.env.BRANCH ?? '';
62
+ // Ensure we're on the right commit (when running on server from workflow)
63
+ if (sha && branch) {
64
+ try {
65
+ (0, child_process_1.execSync)(`git fetch origin ${branch} 2>/dev/null || git fetch origin`, {
66
+ cwd: rootDir,
67
+ stdio: 'pipe',
68
+ });
69
+ (0, child_process_1.execSync)(`git checkout ${sha}`, {
70
+ cwd: rootDir,
71
+ stdio: 'pipe',
72
+ });
73
+ }
74
+ catch (e) {
75
+ console.log(' ⚠️ Could not checkout commit ' + sha + ' - using current state');
76
+ }
77
+ }
78
+ const pathPrefix = process.platform === 'win32' ? '' : '/opt/homebrew/bin:/usr/local/bin:';
79
+ const pathEnv = pathPrefix + (process.env.PATH ?? '');
80
+ // 1. Server build (Docker)
81
+ const serverResult = await runServerBuild(rootDir, config, pathEnv);
82
+ results.push(serverResult);
83
+ // 2. Client build (if client/ exists)
84
+ const clientResult = await runClientBuild(rootDir, pathEnv);
85
+ if (clientResult)
86
+ results.push(clientResult);
87
+ // 3. Mobile build (if docs/mobile or apps/mobile exists)
88
+ const mobileResult = await runMobileBuild(rootDir, pathEnv);
89
+ if (mobileResult)
90
+ results.push(mobileResult);
91
+ const success = results.every((r) => r.success);
92
+ return {
93
+ success,
94
+ results,
95
+ sha,
96
+ prNumber: null,
97
+ };
98
+ }
99
+ async function runServerBuild(rootDir, config, pathEnv) {
100
+ const start = Date.now();
101
+ const dockerfile = (0, staging_js_1.getDockerfilePath)(rootDir);
102
+ const repoName = config.name ?? 'app';
103
+ const imageTag = `${repoName}:staging`;
104
+ try {
105
+ (0, child_process_1.execSync)(`cd ${rootDir} && docker build --platform linux/arm64 -t ${imageTag} -f ${dockerfile} .`, {
106
+ stdio: 'pipe',
107
+ shell: '/bin/bash',
108
+ env: { ...process.env, PATH: pathEnv },
109
+ });
110
+ return {
111
+ name: 'server',
112
+ success: true,
113
+ output: 'Docker build succeeded',
114
+ duration: Date.now() - start,
115
+ };
116
+ }
117
+ catch (e) {
118
+ const err = e;
119
+ const output = (err?.stderr?.toString() || err?.stdout?.toString() || err?.message || String(e)).trim().slice(0, 2000);
120
+ return {
121
+ name: 'server',
122
+ success: false,
123
+ output: output || 'Build failed',
124
+ duration: Date.now() - start,
125
+ };
126
+ }
127
+ }
128
+ async function runClientBuild(rootDir, pathEnv) {
129
+ const clientDir = path.join(rootDir, 'client');
130
+ if (!fs.existsSync(clientDir))
131
+ return null;
132
+ const pkgPath = path.join(clientDir, 'package.json');
133
+ if (!fs.existsSync(pkgPath))
134
+ return null;
135
+ const start = Date.now();
136
+ try {
137
+ (0, child_process_1.execSync)('pnpm install && pnpm build', {
138
+ cwd: clientDir,
139
+ stdio: 'pipe',
140
+ env: { ...process.env, PATH: pathEnv },
141
+ });
142
+ return {
143
+ name: 'client',
144
+ success: true,
145
+ output: 'pnpm build succeeded',
146
+ duration: Date.now() - start,
147
+ };
148
+ }
149
+ catch (e) {
150
+ const err = e;
151
+ const output = (err?.stderr?.toString() || err?.stdout?.toString() || err?.message || String(e)).trim().slice(0, 2000);
152
+ return {
153
+ name: 'client',
154
+ success: false,
155
+ output: output || 'Build failed',
156
+ duration: Date.now() - start,
157
+ };
158
+ }
159
+ }
160
+ async function runMobileBuild(rootDir, pathEnv) {
161
+ const mobileReadmePaths = [
162
+ path.join(rootDir, 'docs', 'mobile', 'README.md'),
163
+ path.join(rootDir, 'apps', 'mobile', 'README.md'),
164
+ path.join(rootDir, 'packages', 'mobile', 'README.md'),
165
+ ];
166
+ let mobileDir = null;
167
+ for (const readmePath of mobileReadmePaths) {
168
+ if (fs.existsSync(readmePath)) {
169
+ mobileDir = path.dirname(readmePath);
170
+ break;
171
+ }
172
+ }
173
+ if (!mobileDir)
174
+ return null;
175
+ const start = Date.now();
176
+ try {
177
+ // EAS build - common command; app repos can override via factiii.yml later
178
+ (0, child_process_1.execSync)('npx eas build --platform all --non-interactive 2>&1 || npx eas build --platform all 2>&1', {
179
+ cwd: mobileDir,
180
+ stdio: 'pipe',
181
+ env: { ...process.env, PATH: pathEnv },
182
+ timeout: 600000, // 10 min for EAS
183
+ });
184
+ return {
185
+ name: 'mobile',
186
+ success: true,
187
+ output: 'EAS build succeeded',
188
+ duration: Date.now() - start,
189
+ };
190
+ }
191
+ catch (e) {
192
+ const err = e;
193
+ const output = (err?.stderr?.toString() || err?.stdout?.toString() || err?.message || String(e)).trim().slice(0, 2000);
194
+ return {
195
+ name: 'mobile',
196
+ success: false,
197
+ output: output || 'Build failed',
198
+ duration: Date.now() - start,
199
+ };
200
+ }
201
+ }
202
+ //# sourceMappingURL=pr-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-check.js","sourceRoot":"","sources":["../../../../src/plugins/pipelines/factiii/pr-check.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"workflows.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/factiii/utils/workflows.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkDtE;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,IAAI,CAAC,CAgCf"}
1
+ {"version":3,"file":"workflows.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/factiii/utils/workflows.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDtE;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,IAAI,CAAC,CAgCf"}
@@ -74,6 +74,7 @@ async function generateWorkflows(rootDir) {
74
74
  'factiii-fix.yml',
75
75
  'factiii-scan.yml',
76
76
  'factiii-undeploy.yml',
77
+ 'factiii-pr-check.yml',
77
78
  'factiii-cicd-staging.yml',
78
79
  'factiii-cicd-prod.yml',
79
80
  'factiii-command.yml',
@@ -1 +1 @@
1
- {"version":3,"file":"workflows.js","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/factiii/utils/workflows.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workflows.js","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/factiii/utils/workflows.ts"],"names":[],"mappings":"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"}
@@ -73,23 +73,28 @@ jobs:
73
73
  BRANCH: ${{ github.ref_name }}
74
74
  GITHUB_REPO: ${{ github.repository }}
75
75
  STAGING_ENVS: ${{ secrets.STAGING_ENVS }}
76
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76
77
  run: |
77
78
  if [ -z "$HOST" ]; then
78
79
  echo "❌ Missing domain in factiii.yml: staging.domain"
79
80
  exit 1
80
81
  fi
81
-
82
+
82
83
  echo "🚀 Deploying to staging ($HOST)..."
83
-
84
+
84
85
  # Prepare environment variables for SSH (base64 encode to handle special characters)
85
86
  ENV_VARS_EXPORT=""
86
87
  if [ -n "$STAGING_ENVS" ]; then
87
88
  ENV_VARS_B64=$(echo -n "$STAGING_ENVS" | base64 -w 0)
88
89
  ENV_VARS_EXPORT="STAGING_ENVS=\$(echo '$ENV_VARS_B64' | base64 -d) && export STAGING_ENVS && "
89
90
  fi
90
-
91
+
92
+ # Base64 encode GITHUB_TOKEN for safe SSH transport
93
+ GITHUB_TOKEN_B64=$(echo -n "$GITHUB_TOKEN" | base64 -w 0)
94
+
91
95
  ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no "$USER@$HOST" \
92
96
  "export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
97
+ export GITHUB_TOKEN=\$(echo \"$GITHUB_TOKEN_B64\" | base64 -d) && \
93
98
  REPO_DIR=\"\$HOME/.factiii/$REPO_NAME\" && \
94
99
  if [ -d \"\$REPO_DIR\" ]; then \
95
100
  cd \"\$REPO_DIR\" && \
@@ -0,0 +1,103 @@
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
@@ -1 +1 @@
1
- {"version":3,"file":"staging.d.ts","sourceRoot":"","sources":["../../../../src/plugins/servers/mac/staging.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,KAAK,EACV,aAAa,EAEb,YAAY,EACZ,wBAAwB,EACzB,MAAM,yBAAyB,CAAC;AA2XjC;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,YAAY,CAAC,CA0DvB;AAmOD;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,EACrB,WAAW,GAAE,MAAkB,GAC9B,OAAO,CAAC,YAAY,CAAC,CAiLvB"}
1
+ {"version":3,"file":"staging.d.ts","sourceRoot":"","sources":["../../../../src/plugins/servers/mac/staging.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,KAAK,EACV,aAAa,EAEb,YAAY,EACZ,wBAAwB,EACzB,MAAM,yBAAyB,CAAC;AA2XjC;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,YAAY,CAAC,CA0DvB;AAqZD;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,EACrB,WAAW,GAAE,MAAkB,GAC9B,OAAO,CAAC,YAAY,CAAC,CAmRvB"}