@scalebun/cli 1.0.0 → 1.4.0

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 (57) hide show
  1. package/lib/api/client.d.ts +8 -0
  2. package/lib/api/client.d.ts.map +1 -1
  3. package/lib/api/client.js +70 -2
  4. package/lib/api/client.js.map +1 -1
  5. package/lib/commands/ci-init.d.ts +0 -6
  6. package/lib/commands/ci-init.d.ts.map +1 -1
  7. package/lib/commands/ci-init.js +172 -28
  8. package/lib/commands/ci-init.js.map +1 -1
  9. package/lib/commands/doctor.d.ts +8 -0
  10. package/lib/commands/doctor.d.ts.map +1 -0
  11. package/lib/commands/doctor.js +252 -0
  12. package/lib/commands/doctor.js.map +1 -0
  13. package/lib/commands/login.d.ts +28 -4
  14. package/lib/commands/login.d.ts.map +1 -1
  15. package/lib/commands/login.js +132 -51
  16. package/lib/commands/login.js.map +1 -1
  17. package/lib/commands/ota-bundle.d.ts.map +1 -1
  18. package/lib/commands/ota-bundle.js +2 -0
  19. package/lib/commands/ota-bundle.js.map +1 -1
  20. package/lib/commands/ota-delete-bundle.d.ts +8 -0
  21. package/lib/commands/ota-delete-bundle.d.ts.map +1 -1
  22. package/lib/commands/ota-delete-bundle.js +60 -0
  23. package/lib/commands/ota-delete-bundle.js.map +1 -1
  24. package/lib/commands/ota-keys.d.ts +14 -0
  25. package/lib/commands/ota-keys.d.ts.map +1 -0
  26. package/lib/commands/ota-keys.js +200 -0
  27. package/lib/commands/ota-keys.js.map +1 -0
  28. package/lib/commands/ota-publish.d.ts +10 -0
  29. package/lib/commands/ota-publish.d.ts.map +1 -1
  30. package/lib/commands/ota-publish.js +251 -34
  31. package/lib/commands/ota-publish.js.map +1 -1
  32. package/lib/commands/ota-rollout.d.ts +3 -0
  33. package/lib/commands/ota-rollout.d.ts.map +1 -0
  34. package/lib/commands/ota-rollout.js +235 -0
  35. package/lib/commands/ota-rollout.js.map +1 -0
  36. package/lib/commands/quickstart.d.ts +4 -0
  37. package/lib/commands/quickstart.d.ts.map +1 -0
  38. package/lib/commands/quickstart.js +274 -0
  39. package/lib/commands/quickstart.js.map +1 -0
  40. package/lib/index.js +20 -1
  41. package/lib/index.js.map +1 -1
  42. package/lib/utils/bundle.d.ts +86 -0
  43. package/lib/utils/bundle.d.ts.map +1 -1
  44. package/lib/utils/bundle.js +244 -14
  45. package/lib/utils/bundle.js.map +1 -1
  46. package/lib/utils/credentials.d.ts +12 -1
  47. package/lib/utils/credentials.d.ts.map +1 -1
  48. package/lib/utils/credentials.js +40 -1
  49. package/lib/utils/credentials.js.map +1 -1
  50. package/lib/utils/transportSecurity.d.ts +36 -0
  51. package/lib/utils/transportSecurity.d.ts.map +1 -0
  52. package/lib/utils/transportSecurity.js +74 -0
  53. package/lib/utils/transportSecurity.js.map +1 -0
  54. package/lib/utils/ui.d.ts.map +1 -1
  55. package/lib/utils/ui.js +2 -0
  56. package/lib/utils/ui.js.map +1 -1
  57. package/package.json +1 -1
@@ -12,8 +12,16 @@ export declare class ApiClient {
12
12
  get<T = unknown>(path: string): Promise<T>;
13
13
  /** POST request — sends JSON body, returns parsed JSON. */
14
14
  post<T = unknown>(path: string, body?: unknown): Promise<T>;
15
+ /** PATCH request — sends JSON body, returns parsed JSON. */
16
+ patch<T = unknown>(path: string, body?: unknown): Promise<T>;
15
17
  /** DELETE request — returns parsed JSON. */
16
18
  delete<T = unknown>(path: string): Promise<T>;
19
+ /**
20
+ * Multipart POST to a backend path with extra headers (symbol uploads).
21
+ * Bearer auth is still attached; endpoint-specific headers (e.g. the SDK
22
+ * secret key) ride alongside it.
23
+ */
24
+ postMultipart(path: string, body: Buffer, contentType: string, extraHeaders?: Record<string, string>): Promise<unknown>;
17
25
  /** Upload raw bytes via PUT to an arbitrary URL (presigned S3/R2). */
18
26
  putBytes(url: string, data: Buffer, contentType: string): Promise<void>;
19
27
  private request;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD;;;;GAIG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,KAAK,EAAE,WAAW;IAM9B,yCAAyC;IACnC,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhD,2DAA2D;IACrD,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIjE,4CAA4C;IACtC,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAInD,sEAAsE;IAChE,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YA6C/D,OAAO;CA0DtB"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGxD;;;;GAIG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,KAAK,EAAE,WAAW;IAU9B,yCAAyC;IACnC,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhD,2DAA2D;IACrD,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIjE,4DAA4D;IACtD,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIlE,4CAA4C;IACtC,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAInD;;;;OAIG;IACG,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,YAAY,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACxC,OAAO,CAAC,OAAO,CAAC;IA8CnB,sEAAsE;IAChE,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YA6C/D,OAAO;CAuEtB"}
package/lib/api/client.js CHANGED
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.ApiClient = void 0;
37
37
  const https = __importStar(require("https"));
38
38
  const http = __importStar(require("http"));
39
+ const transportSecurity_1 = require("../utils/transportSecurity");
39
40
  /**
40
41
  * Minimal HTTP client for the Scalebun backend API.
41
42
  * Uses PAT-based auth (Authorization: Bearer <token>).
@@ -43,8 +44,12 @@ const http = __importStar(require("http"));
43
44
  */
44
45
  class ApiClient {
45
46
  constructor(creds) {
46
- // Strip trailing slash
47
- this.apiUrl = creds.apiUrl.replace(/\/+$/, '');
47
+ // Every request below attaches `Authorization: Bearer <token>`, so the
48
+ // scheme is a security decision, not a formatting one. Refuse a plaintext
49
+ // endpoint here — at construction, before any socket is opened — rather
50
+ // than at each call site, so no future method can quietly skip the check.
51
+ // Loopback is exempt; see transportSecurity.ts.
52
+ this.apiUrl = (0, transportSecurity_1.assertSecureApiUrl)(creds.apiUrl);
48
53
  this.token = creds.token;
49
54
  }
50
55
  /** GET request — returns parsed JSON. */
@@ -55,10 +60,63 @@ class ApiClient {
55
60
  async post(path, body) {
56
61
  return this.request('POST', path, body);
57
62
  }
63
+ /** PATCH request — sends JSON body, returns parsed JSON. */
64
+ async patch(path, body) {
65
+ return this.request('PATCH', path, body);
66
+ }
58
67
  /** DELETE request — returns parsed JSON. */
59
68
  async delete(path) {
60
69
  return this.request('DELETE', path);
61
70
  }
71
+ /**
72
+ * Multipart POST to a backend path with extra headers (symbol uploads).
73
+ * Bearer auth is still attached; endpoint-specific headers (e.g. the SDK
74
+ * secret key) ride alongside it.
75
+ */
76
+ async postMultipart(path, body, contentType, extraHeaders = {}) {
77
+ return new Promise((resolve, reject) => {
78
+ const parsed = new URL(`${this.apiUrl}${path}`);
79
+ const transport = parsed.protocol === 'https:' ? https : http;
80
+ const req = transport.request({
81
+ hostname: parsed.hostname,
82
+ port: parsed.port || undefined,
83
+ path: parsed.pathname + parsed.search,
84
+ method: 'POST',
85
+ headers: {
86
+ Authorization: `Bearer ${this.token}`,
87
+ Accept: 'application/json',
88
+ 'Content-Type': contentType,
89
+ 'Content-Length': body.length,
90
+ ...extraHeaders,
91
+ },
92
+ timeout: 120000,
93
+ }, (res) => {
94
+ const chunks = [];
95
+ res.on('data', (c) => chunks.push(c));
96
+ res.on('end', () => {
97
+ const raw = Buffer.concat(chunks).toString('utf-8');
98
+ if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
99
+ try {
100
+ resolve(JSON.parse(raw));
101
+ }
102
+ catch {
103
+ resolve(raw);
104
+ }
105
+ }
106
+ else {
107
+ reject(new Error(`API error (HTTP ${res.statusCode}): ${raw.slice(0, 300)}`));
108
+ }
109
+ });
110
+ });
111
+ req.on('error', reject);
112
+ req.on('timeout', () => {
113
+ req.destroy();
114
+ reject(new Error('Multipart upload timed out'));
115
+ });
116
+ req.write(body);
117
+ req.end();
118
+ });
119
+ }
62
120
  /** Upload raw bytes via PUT to an arbitrary URL (presigned S3/R2). */
63
121
  async putBytes(url, data, contentType) {
64
122
  return new Promise((resolve, reject) => {
@@ -131,6 +189,16 @@ class ApiClient {
131
189
  resolve(raw);
132
190
  }
133
191
  }
192
+ else if (res.statusCode === 401) {
193
+ // The most common cause by far is an expired credential — the old
194
+ // login flow stored 15-minute session JWTs, and CI secrets rot.
195
+ // A bare "Unauthorized" cost real debugging time during the first
196
+ // device run; the fix is one command, so name it.
197
+ reject(new Error(`API error (HTTP 401): ${raw.slice(0, 200)}\n` +
198
+ ` Your credential is invalid or has expired.\n` +
199
+ ` → Locally: run \`scalebun login\`\n` +
200
+ ` → In CI: refresh the SCALEBUN_TOKEN secret (create one in the dashboard under Settings → Access Tokens)`));
201
+ }
134
202
  else {
135
203
  reject(new Error(`API error (HTTP ${res.statusCode}): ${raw.slice(0, 500)}`));
136
204
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,3 @@
1
1
  import { Command } from 'commander';
2
- /**
3
- * `scalebun ci init` — Sprint 12 (S12-CLI-1).
4
- *
5
- * Generates copy-paste CI/CD workflows for GitHub Actions, Bitrise, or CircleCI:
6
- * npx scalebun ci init --provider github
7
- */
8
2
  export declare function registerCiInitCommand(program: Command): void;
9
3
  //# sourceMappingURL=ci-init.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ci-init.d.ts","sourceRoot":"","sources":["../../src/commands/ci-init.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkCpC;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0B5D"}
1
+ {"version":3,"file":"ci-init.d.ts","sourceRoot":"","sources":["../../src/commands/ci-init.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0KpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyC5D"}
@@ -36,64 +36,208 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.registerCiInitCommand = registerCiInitCommand;
37
37
  const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
- const GITHUB_ACTIONS_WORKFLOW = `name: Scalebun OTA Publish
39
+ /**
40
+ * `scalebun ci init` — generate working CI/CD pipelines for OTA publishing.
41
+ *
42
+ * Credentials in CI are environment variables, no login step:
43
+ * SCALEBUN_TOKEN a personal access token (scalebun_pat_…) — create one in
44
+ * the dashboard (Settings → Access Tokens) or via
45
+ * `scalebun login` locally and copy from the output
46
+ * SCALEBUN_API_URL the backend API base, e.g. https://api.scalebun.com/api/v1
47
+ *
48
+ * `readCredentials()` picks both up automatically, so every command that works
49
+ * locally works headless: publish, rollout, pause, rollback.
50
+ */
51
+ const GITHUB_ACTIONS_WORKFLOW = `name: Scalebun OTA
40
52
 
41
53
  on:
42
54
  push:
43
- branches: [ main, production ]
55
+ branches: [main]
56
+ # Manual controls from the Actions tab — staged rollout without a laptop.
57
+ workflow_dispatch:
58
+ inputs:
59
+ action:
60
+ description: What to do
61
+ type: choice
62
+ options: [publish, rollout, pause, rollback]
63
+ default: publish
64
+ percent:
65
+ description: Rollout percent (rollout action only)
66
+ default: '100'
67
+
68
+ env:
69
+ # Create a PAT in the Scalebun dashboard (Settings -> Access Tokens) and add
70
+ # both values as repository secrets. Session JWTs expire in minutes - always
71
+ # use a scalebun_pat_... token here.
72
+ SCALEBUN_TOKEN: \${{ secrets.SCALEBUN_TOKEN }}
73
+ SCALEBUN_API_URL: \${{ secrets.SCALEBUN_API_URL }}
74
+ SCALEBUN_APP_ID: \${{ secrets.SCALEBUN_APP_ID }}
75
+ # Required by --sourcemap: without it the map uploads but is never
76
+ # registered for symbolication, so production stack traces stay minified.
77
+ SCALEBUN_SDK_SECRET: \${{ secrets.SCALEBUN_SDK_SECRET }}
44
78
 
45
79
  jobs:
46
- publish-ota:
80
+ ota:
47
81
  runs-on: ubuntu-latest
48
82
  steps:
49
83
  - uses: actions/checkout@v4
50
84
 
51
- - name: Setup Node.js
52
- uses: actions/setup-node@v4
85
+ - uses: actions/setup-node@v4
53
86
  with:
54
87
  node-version: 20
88
+ cache: npm
55
89
 
56
90
  - name: Install dependencies
57
91
  run: npm ci
58
92
 
59
- - name: Publish OTA Update to Scalebun
93
+ # ── Publish (push to main, or manual "publish") ──────────────────────
94
+ # Starts at 10%, NOT 100: a staged rollout is the whole point of OTA.
95
+ # Widen it with the manual "rollout" action once health looks clean.
96
+ # NOTE: the channel must already exist - a typo'd channel name is
97
+ # rejected rather than silently created.
98
+ - name: Publish OTA update
99
+ if: github.event_name == 'push' || inputs.action == 'publish'
100
+ # The commit message is UNTRUSTED input. Interpolating \${{ }} straight
101
+ # into run: splices it into the shell — a message with a quote breaks the
102
+ # job, and one with ";cmd;" executes with SCALEBUN_TOKEN in scope.
103
+ # Passing it through env keeps it data.
60
104
  env:
61
- SCALEBUN_TOKEN: \${{ secrets.SCALEBUN_TOKEN }}
105
+ COMMIT_MESSAGE: \${{ github.event.head_commit.message || 'Manual publish' }}
62
106
  run: |
63
107
  npx scalebun ota publish \\
64
- --app-id \${{ secrets.SCALEBUN_APP_ID }} \\
108
+ --app-id "$SCALEBUN_APP_ID" \\
65
109
  --channel production \\
66
110
  --platform android \\
67
111
  --hermes \\
68
- --sourcemap
112
+ --sourcemap \\
113
+ --rollout 10 \\
114
+ --release-note "$COMMIT_MESSAGE"
115
+
116
+ # ── Manual controls ──────────────────────────────────────────────────
117
+ - name: Widen rollout
118
+ if: inputs.action == 'rollout'
119
+ run: npx scalebun ota rollout --app-id "$SCALEBUN_APP_ID" --percent "\${{ inputs.percent }}"
120
+
121
+ - name: Pause release
122
+ if: inputs.action == 'pause'
123
+ run: npx scalebun ota pause --app-id "$SCALEBUN_APP_ID"
124
+
125
+ - name: Roll back release
126
+ if: inputs.action == 'rollback'
127
+ run: npx scalebun ota rollback --app-id "$SCALEBUN_APP_ID" --yes
69
128
  `;
70
- /**
71
- * `scalebun ci init` — Sprint 12 (S12-CLI-1).
72
- *
73
- * Generates copy-paste CI/CD workflows for GitHub Actions, Bitrise, or CircleCI:
74
- * npx scalebun ci init --provider github
75
- */
129
+ const GITLAB_CI_TEMPLATE = `# Scalebun OTA — GitLab CI
130
+ #
131
+ # Set these CI/CD variables (Settings -> CI/CD -> Variables, masked):
132
+ # SCALEBUN_TOKEN scalebun_pat_... (dashboard -> Settings -> Access Tokens)
133
+ # SCALEBUN_API_URL e.g. https://api.scalebun.com/api/v1
134
+ # SCALEBUN_APP_ID your application id
135
+ #
136
+ # Session JWTs expire in minutes - always use a scalebun_pat_... token in CI.
137
+
138
+ stages: [ota]
139
+
140
+ .ota-base:
141
+ stage: ota
142
+ image: node:20
143
+ before_script:
144
+ - npm ci
145
+
146
+ # Publishes on every push to the default branch, staged at 10%.
147
+ ota-publish:
148
+ extends: .ota-base
149
+ rules:
150
+ - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
151
+ script:
152
+ - npx scalebun ota publish
153
+ --app-id "$SCALEBUN_APP_ID"
154
+ --channel production
155
+ --platform android
156
+ --hermes
157
+ --sourcemap
158
+ --rollout 10
159
+ --release-note "$CI_COMMIT_TITLE"
160
+
161
+ # Manual jobs — run from the pipeline UI once health looks clean (or bad).
162
+ ota-rollout-100:
163
+ extends: .ota-base
164
+ rules: [{ when: manual }]
165
+ script:
166
+ - npx scalebun ota rollout --app-id "$SCALEBUN_APP_ID" --percent 100
167
+
168
+ ota-pause:
169
+ extends: .ota-base
170
+ rules: [{ when: manual }]
171
+ script:
172
+ - npx scalebun ota pause --app-id "$SCALEBUN_APP_ID"
173
+
174
+ ota-rollback:
175
+ extends: .ota-base
176
+ rules: [{ when: manual }]
177
+ script:
178
+ - npx scalebun ota rollback --app-id "$SCALEBUN_APP_ID" --yes
179
+ `;
180
+ function writeTemplate(targetPath, content) {
181
+ if (fs.existsSync(targetPath)) {
182
+ console.error(`❌ ${path.relative(process.cwd(), targetPath)} already exists — refusing to overwrite.\n` +
183
+ ' Delete it first if you want a fresh template.');
184
+ return false;
185
+ }
186
+ fs.mkdirSync(path.dirname(targetPath), { recursive: true });
187
+ fs.writeFileSync(targetPath, content, 'utf-8');
188
+ return true;
189
+ }
190
+ function printNextSteps(provider, file) {
191
+ console.log(`✅ ${provider} pipeline generated: ${file}`);
192
+ console.log('');
193
+ console.log('Next steps:');
194
+ console.log(' 1. Create an access token: dashboard → Settings → Access Tokens');
195
+ console.log(' (or run `scalebun login` locally and copy the scalebun_pat_… it prints)');
196
+ console.log(' 2. Add SCALEBUN_TOKEN, SCALEBUN_API_URL and SCALEBUN_APP_ID as CI secrets.');
197
+ console.log(' 3. Make sure the target channel exists (`scalebun ota channels --app-id <id>`).');
198
+ console.log(' 4. Push — the release goes out staged at 10%; widen it from the CI UI.');
199
+ }
76
200
  function registerCiInitCommand(program) {
77
201
  const ci = program.command('ci').description('CI/CD integration setup');
78
202
  ci.command('init')
79
- .description('Generate CI/CD pipeline configs for OTA publishing')
80
- .option('--provider <name>', 'CI provider: github | bitrise | circleci', 'github')
203
+ .description('Generate a CI/CD pipeline for OTA publishing (publish / rollout / pause / rollback)')
204
+ .option('--provider <name>', 'CI provider: github | gitlab', 'github')
81
205
  .action((opts) => {
82
206
  const provider = opts.provider.toLowerCase();
83
207
  if (provider === 'github') {
84
- const targetDir = path.join(process.cwd(), '.github', 'workflows');
85
- const targetPath = path.join(targetDir, 'scalebun-ota.yml');
86
- fs.mkdirSync(targetDir, { recursive: true });
87
- fs.writeFileSync(targetPath, GITHUB_ACTIONS_WORKFLOW, 'utf-8');
88
- console.log(`✅ GitHub Actions workflow generated: ${path.relative(process.cwd(), targetPath)}`);
89
- console.log('\nNext steps:');
90
- console.log(' 1. Add SCALEBUN_TOKEN and SCALEBUN_APP_ID to your repository secrets.');
91
- console.log(' 2. Git push to trigger your first automated OTA release!\n');
208
+ const target = path.join(process.cwd(), '.github', 'workflows', 'scalebun-ota.yml');
209
+ if (writeTemplate(target, GITHUB_ACTIONS_WORKFLOW)) {
210
+ printNextSteps('GitHub Actions', path.relative(process.cwd(), target));
211
+ }
212
+ else {
213
+ process.exit(1);
214
+ }
215
+ }
216
+ else if (provider === 'gitlab') {
217
+ const target = path.join(process.cwd(), '.gitlab-ci.scalebun-ota.yml');
218
+ if (writeTemplate(target, GITLAB_CI_TEMPLATE)) {
219
+ printNextSteps('GitLab CI', path.relative(process.cwd(), target));
220
+ console.log('');
221
+ console.log(" Include it from your .gitlab-ci.yml:");
222
+ console.log(" include:");
223
+ console.log(" - local: .gitlab-ci.scalebun-ota.yml");
224
+ }
225
+ else {
226
+ process.exit(1);
227
+ }
92
228
  }
93
229
  else {
94
- console.log(`ℹ️ Generating ${provider} CI config template:`);
95
- console.log('\nCommand to add to your CI script:');
96
- console.log(' npx scalebun ota publish --app-id $SCALEBUN_APP_ID --channel production --hermes --sourcemap\n');
230
+ // Any other system: the commands are plain npx calls over env-var
231
+ // credentials, so print the recipe instead of pretending to support it.
232
+ console.log(`ℹ️ No template for "${provider}" but any CI works. Set these env vars:`);
233
+ console.log(' SCALEBUN_TOKEN (scalebun_pat_… from the dashboard)');
234
+ console.log(' SCALEBUN_API_URL (your backend, e.g. https://api.scalebun.com/api/v1)');
235
+ console.log('');
236
+ console.log(' Then script the commands directly:');
237
+ console.log(' npx scalebun ota publish --app-id $APP_ID --channel production --hermes --rollout 10');
238
+ console.log(' npx scalebun ota rollout --app-id $APP_ID --percent 100');
239
+ console.log(' npx scalebun ota pause --app-id $APP_ID');
240
+ console.log(' npx scalebun ota rollback --app-id $APP_ID --yes');
97
241
  }
98
242
  });
99
243
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ci-init.js","sourceRoot":"","sources":["../../src/commands/ci-init.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,sDA0BC;AApED,uCAAyB;AACzB,2CAA6B;AAG7B,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8B/B,CAAC;AAEF;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,OAAgB;IACpD,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,yBAAyB,CAAC,CAAC;IAExE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,oDAAoD,CAAC;SACjE,MAAM,CAAC,mBAAmB,EAAE,0CAA0C,EAAE,QAAQ,CAAC;SACjF,MAAM,CAAC,CAAC,IAA0B,EAAE,EAAE;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAE7C,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;YACnE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;YAE5D,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,uBAAuB,EAAE,OAAO,CAAC,CAAC;YAE/D,OAAO,CAAC,GAAG,CAAC,wCAAwC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC;YAChG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAC;YACvF,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;QAC9E,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,kBAAkB,QAAQ,sBAAsB,CAAC,CAAC;YAC9D,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,kGAAkG,CAAC,CAAC;QAClH,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"ci-init.js","sourceRoot":"","sources":["../../src/commands/ci-init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerDoctorCommand(program: Command): void;
3
+ /**
4
+ * All doctor checks as a reusable step (`quickstart` runs it inline).
5
+ * Same contract as the command: exits the process on a blocking failure.
6
+ */
7
+ export declare function runDoctor(): Promise<void>;
8
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2DpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAK5D;AAED;;;GAGG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CA6M/C"}