@gambi97/keel-cli 0.3.2 → 0.3.3

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.
@@ -209,8 +209,11 @@ export async function configureRepo(ctx, answers, infisicalProjectId) {
209
209
  INFISICAL_HOST: answers.infisical.host,
210
210
  };
211
211
  await setVariables(ctx, variables);
212
- await configureEnvironments(ctx, answers);
213
- return protectMainBranch(ctx, answers);
212
+ const warnings = [
213
+ await configureEnvironments(ctx, answers),
214
+ await protectMainBranch(ctx, answers),
215
+ ].filter((w) => w !== undefined);
216
+ return warnings.length > 0 ? warnings.join('\n\n') : undefined;
214
217
  }
215
218
  async function setSecrets(ctx, secrets) {
216
219
  await sodium.ready;
@@ -251,16 +254,45 @@ async function setVariables(ctx, variables) {
251
254
  }
252
255
  }
253
256
  }
254
- /** Each environment gets a GitHub deployment environment; gated ones (prod) require approval. */
255
- async function configureEnvironments(ctx, answers) {
257
+ /**
258
+ * Each environment gets a GitHub deployment environment; gated ones (prod)
259
+ * require a reviewer approval. Required reviewers need GitHub Enterprise Cloud
260
+ * on private repositories — GitHub answers 422 there. Rather than strand the
261
+ * bootstrap at its last step, fall back to an ungated environment and warn:
262
+ * the environment still exists (deployments target it) but production will
263
+ * auto-deploy on merge. Like the branch-protection miss, this degrades to a
264
+ * warning instead of killing the run.
265
+ */
266
+ export async function configureEnvironments(ctx, answers) {
267
+ const ungated = [];
256
268
  for (const env of answers.environments) {
257
- await ctx.octokit.repos.createOrUpdateEnvironment({
258
- owner: ctx.owner,
259
- repo: ctx.repo,
260
- environment_name: env.githubEnvironment,
261
- ...(env.gated ? { reviewers: [{ type: 'User', id: ctx.ownerId }] } : {}),
262
- });
269
+ try {
270
+ await ctx.octokit.repos.createOrUpdateEnvironment({
271
+ owner: ctx.owner,
272
+ repo: ctx.repo,
273
+ environment_name: env.githubEnvironment,
274
+ ...(env.gated ? { reviewers: [{ type: 'User', id: ctx.ownerId }] } : {}),
275
+ });
276
+ }
277
+ catch (error) {
278
+ // Only the reviewer rule can trip the plan limit; re-throw anything else
279
+ // (and any failure on a non-gated environment, which asked for no rule).
280
+ if (!env.gated || error.status !== 422)
281
+ throw error;
282
+ await ctx.octokit.repos.createOrUpdateEnvironment({
283
+ owner: ctx.owner,
284
+ repo: ctx.repo,
285
+ environment_name: env.githubEnvironment,
286
+ });
287
+ ungated.push(env.githubEnvironment);
288
+ }
263
289
  }
290
+ if (ungated.length === 0)
291
+ return undefined;
292
+ return (`Created the ${ungated.join(', ')} environment(s) without the manual-approval gate: ` +
293
+ 'required reviewers need GitHub Enterprise Cloud on private repositories, so production ' +
294
+ 'will auto-deploy on merge to main. Make the repository public (reviewers are free there) ' +
295
+ 'or upgrade the plan, then re-run to add the gate.');
264
296
  }
265
297
  /**
266
298
  * Require a green plan on PRs and forbid force-pushes/deletion of main.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gambi97/keel-cli",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "One command from zero to a production-shaped serverless infrastructure on Scaleway (Terraform + GitHub Actions + Infisical). Only Node required.",
5
5
  "keywords": [
6
6
  "keel",
@@ -197,3 +197,9 @@ Avoid local applies: they race against CI on the same state.
197
197
  - **Apply fails creating IAM resources**: the CI Scaleway key needs IAM
198
198
  permissions (IAMManager) to create the app's database (and Object Storage)
199
199
  credential.
200
+ - **Apply fails with "expires_at ... organization security settings require an
201
+ expiration date for API keys"**: the app's database and Object Storage
202
+ credentials are long-lived service credentials — the container reads them at
203
+ runtime, so they intentionally never expire. If your Scaleway organization
204
+ enforces API-key expiration, exempt these service applications or turn the
205
+ policy off (Console → Organization → Security), then re-run the apply.