@theholocron/cli 4.16.0 → 4.16.1

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/README.md CHANGED
@@ -99,6 +99,16 @@ export default defineConfig({
99
99
  });
100
100
  ```
101
101
 
102
+ The generated ruleset also sets `require_extra_approval_for_unattributed_changes:
103
+ false` — with `required_approving_review_count: 0` and a single maintainer, the
104
+ GitHub default (`true`) is an unsatisfiable block on any PR with an
105
+ unverified/unattributed commit. Repository-admin bypass still covers the real
106
+ risk. And the `codecov.yml` `holocron setup` writes carries `if_not_found:
107
+ success` on every status default, so an infra-only PR (dep bump, config,
108
+ lockfile — no coverable change) passes instead of hanging on a `codecov/*`
109
+ required check that never posts. A re-run of `holocron setup` backfills both into
110
+ an existing repo.
111
+
102
112
  ### Git hooks
103
113
 
104
114
  ```ts
package/dist/cli.mjs CHANGED
@@ -3379,7 +3379,7 @@ function createIgnoreConfig() {
3379
3379
  }
3380
3380
  //#endregion
3381
3381
  //#region src/templates/configs/codecov/codecov.yml
3382
- var codecov_default = "codecov:\n require_ci_to_pass: true\n\ncoverage:\n precision: 2\n round: down\n status:\n project:\n default:\n target: auto\n threshold: 2%\n patch:\n default:\n target: 80%\n\ncomment:\n layout: \"reach,diff,flags,components\"\n behavior: default\n require_changes: true\n\ncomponent_management:\n default_rules:\n statuses:\n - type: patch\n target: 80%\n individual_components:\n";
3382
+ var codecov_default = "codecov:\n require_ci_to_pass: true\n\ncoverage:\n precision: 2\n round: down\n status:\n project:\n default:\n target: auto\n threshold: 2%\n # Infra-only PRs (dep bumps, config, lockfile) touch no coverable code,\n # so codecov produces no report to compare. Pass instead of blocking\n # forever on a required check that will never post.\n if_not_found: success\n patch:\n default:\n target: 80%\n if_not_found: success\n\ncomment:\n layout: \"reach,diff,flags,components\"\n behavior: default\n require_changes: true\n\ncomponent_management:\n default_rules:\n statuses:\n - type: patch\n target: 80%\n if_not_found: success\n individual_components:\n";
3383
3383
  //#endregion
3384
3384
  //#region src/templates/configs/codecov/utils.ts
3385
3385
  const INDIVIDUAL_COMPONENTS_MARKER = " individual_components:";
@@ -3393,10 +3393,45 @@ function codecovComponentBlock(packages) {
3393
3393
  ``
3394
3394
  ]).join("\n");
3395
3395
  }
3396
+ /**
3397
+ * Ensure every codecov status default carries `if_not_found: success`, so an
3398
+ * infra-only PR (dep bump, config, lockfile — no coverable change) passes
3399
+ * instead of hanging forever on a required check codecov never posts.
3400
+ *
3401
+ * Injects the key on the line after each `target:` that sits inside a status
3402
+ * block (`coverage.status.*.default` or a `statuses:` list item — indent ≥ 8,
3403
+ * or ≥ 8 for a `- type:` list entry), when the immediate sibling lines do not
3404
+ * already declare it.
3405
+ */
3406
+ function ensureIfNotFound(yaml) {
3407
+ const lines = yaml.split("\n");
3408
+ const out = [];
3409
+ for (let i = 0; i < lines.length; i++) {
3410
+ const line = lines[i];
3411
+ out.push(line);
3412
+ const m = /^(\s{8,})target:\s+\S+\s*$/.exec(line);
3413
+ if (!m) continue;
3414
+ const indent = m[1];
3415
+ let alreadySet = false;
3416
+ for (let j = i + 1; j < lines.length; j++) {
3417
+ const sib = lines[j];
3418
+ if (sib.trim() === "") continue;
3419
+ const sibIndent = sib.match(/^\s*/)[0].length;
3420
+ if (sibIndent < indent.length) break;
3421
+ if (sibIndent === indent.length && /^\s*if_not_found\s*:/.test(sib)) {
3422
+ alreadySet = true;
3423
+ break;
3424
+ }
3425
+ if (sibIndent === indent.length && /^\s*(- |\w)/.test(sib) && !/^\s*(threshold|flags|paths|branches)\s*:/.test(sib)) break;
3426
+ }
3427
+ if (!alreadySet) out.push(`${indent}if_not_found: success`);
3428
+ }
3429
+ return out.join("\n");
3430
+ }
3396
3431
  function mergeCodecovComponents(existing, packages) {
3397
3432
  const idx = existing.indexOf(INDIVIDUAL_COMPONENTS_MARKER);
3398
- if (idx === -1) return existing;
3399
- return existing.slice(0, idx + 24) + codecovComponentBlock(packages);
3433
+ if (idx === -1) return ensureIfNotFound(existing);
3434
+ return ensureIfNotFound(existing.slice(0, idx + 24)) + codecovComponentBlock(packages);
3400
3435
  }
3401
3436
  async function readWorkspacePackages(repoRoot) {
3402
3437
  const packagesDir = join(repoRoot, "packages");
@@ -3965,7 +4000,8 @@ function buildRulesetPayload(requiredChecks = []) {
3965
4000
  dismiss_stale_reviews_on_push: false,
3966
4001
  require_code_owner_review: false,
3967
4002
  require_last_push_approval: false,
3968
- required_review_thread_resolution: true
4003
+ required_review_thread_resolution: true,
4004
+ require_extra_approval_for_unattributed_changes: false
3969
4005
  }
3970
4006
  }
3971
4007
  ];