@moku-labs/ci 1.2.5 → 1.2.6

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 (2) hide show
  1. package/dist/release.mjs +34 -5
  2. package/package.json +1 -1
package/dist/release.mjs CHANGED
@@ -685,19 +685,48 @@ function requiredCheckContexts(stdout) {
685
685
  return parseRules(stdout).filter((rule) => rule.type === REQUIRED_CHECKS_RULE).flatMap((rule) => rule.parameters?.required_status_checks ?? []).flatMap((check) => check.context === void 0 ? [] : [check.context]);
686
686
  }
687
687
  /**
688
+ * What is wrong with a ruleset's required checks, measured against the central ones. A
689
+ * legacy check is a central one without the caller prefix (`lint` for `ci / lint`): the thin
690
+ * caller never reports it. Any other context is the project's own (`ci-pass` of a matrix
691
+ * workflow) and is none of our business.
692
+ *
693
+ * @param required - The contexts the ruleset requires.
694
+ * @param central - The central contexts (`ci / lint`, …).
695
+ * @returns The legacy contexts to drop and the central ones still missing.
696
+ * @example
697
+ * requiredChecksDrift(["lint", "ci-pass"], ["ci / lint"]); // { legacy: ["lint"], missing: ["ci / lint"] }
698
+ */
699
+ function requiredChecksDrift(required, central) {
700
+ const bare = new Set(central.map((context) => context.slice(5)));
701
+ return {
702
+ legacy: required.filter((context) => bare.has(context)),
703
+ missing: central.filter((context) => !required.includes(context))
704
+ };
705
+ }
706
+ /**
688
707
  * The body that moves an existing ruleset onto the central required checks. Every other
689
- * rule of the existing ruleset is kept as it is.
708
+ * rule is kept as it is, and so is every required check the project added itself.
690
709
  *
691
710
  * @param existing - The full existing ruleset as JSON.
692
711
  * @param template - The central ruleset template as JSON.
693
- * @returns The `PUT` body: the existing rules with the template's required checks.
712
+ * @returns The `PUT` body: the existing rules with the central required checks merged in.
694
713
  * @example
695
714
  * const body = withCentralRequiredChecks(existingJson, renderMainRuleset());
696
715
  */
697
716
  function withCentralRequiredChecks(existing, template) {
698
717
  const kept = parseRules(existing).filter((rule) => rule.type !== REQUIRED_CHECKS_RULE);
699
718
  const central = parseRules(template).filter((rule) => rule.type === REQUIRED_CHECKS_RULE);
700
- return JSON.stringify({ rules: [...kept, ...central] });
719
+ const centralContexts = requiredCheckContexts(template);
720
+ const { legacy } = requiredChecksDrift(requiredCheckContexts(existing), centralContexts);
721
+ const own = requiredCheckContexts(existing).filter((context) => !legacy.includes(context) && !centralContexts.includes(context));
722
+ const merged = central.map((rule) => ({
723
+ ...rule,
724
+ parameters: {
725
+ ...rule.parameters,
726
+ required_status_checks: [...rule.parameters?.required_status_checks ?? [], ...own.map((context) => ({ context }))]
727
+ }
728
+ }));
729
+ return JSON.stringify({ rules: [...kept, ...merged] });
701
730
  }
702
731
  /**
703
732
  * The id of the newest workflow run from `gh run list --json databaseId`.
@@ -1179,11 +1208,11 @@ function renderMainRuleset() {
1179
1208
  * const stale = await findStaleRuleset(ctx, "moku-labs/system", listing.stdout);
1180
1209
  */
1181
1210
  async function findStaleRuleset(ctx, ownerRepo, listing) {
1182
- const central = new Set(requiredCheckContexts(renderMainRuleset()));
1211
+ const central = requiredCheckContexts(renderMainRuleset());
1183
1212
  for (const id of activeBranchRulesetIds(listing)) {
1184
1213
  const detail = await ctx.exec.capture("gh", ["api", `repos/${ownerRepo}/rulesets/${id}`]);
1185
1214
  if (detail.code !== 0) continue;
1186
- const legacy = requiredCheckContexts(detail.stdout).filter((context) => !central.has(context));
1215
+ const { legacy } = requiredChecksDrift(requiredCheckContexts(detail.stdout), central);
1187
1216
  if (legacy.length > 0) return {
1188
1217
  id,
1189
1218
  body: detail.stdout,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moku-labs/ci",
3
- "version": "1.2.5",
3
+ "version": "1.2.6",
4
4
  "description": "Central CI and release for the moku family: reusable workflows, caller examples and the moku-release CLI.",
5
5
  "type": "module",
6
6
  "sideEffects": [