@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 +10 -0
- package/dist/cli.mjs +40 -4
- package/dist/cli.mjs.map +1 -1
- package/package.json +4 -4
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
|
];
|