@aspruyt/xfg 3.6.0 → 3.7.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.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![codecov](https://codecov.io/gh/anthony-spruyt/xfg/graph/badge.svg)](https://codecov.io/gh/anthony-spruyt/xfg)
5
5
  [![npm version](https://img.shields.io/npm/v/@aspruyt/xfg.svg)](https://www.npmjs.com/package/@aspruyt/xfg)
6
6
  [![npm downloads](https://img.shields.io/npm/dw/@aspruyt/xfg.svg)](https://www.npmjs.com/package/@aspruyt/xfg)
7
- [![GitHub Marketplace](https://img.shields.io/badge/Marketplace-xfg-blue?logo=github)](https://github.com/marketplace/actions/xfg-config-file-sync)
7
+ [![GitHub Marketplace](https://img.shields.io/badge/Marketplace-xfg-blue?logo=github)](https://github.com/marketplace/actions/xfg-repo-as-code)
8
8
  [![docs](https://img.shields.io/badge/docs-GitHub%20Pages-blue)](https://anthony-spruyt.github.io/xfg/)
9
9
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
10
10
 
@@ -92,10 +92,19 @@ export function mergeSettings(root, perRepo) {
92
92
  result.deleteOrphaned = deleteOrphaned;
93
93
  }
94
94
  // Merge repo settings: per-repo overrides root (shallow merge)
95
- const rootRepo = root?.repo;
96
- const perRepoRepo = perRepo?.repo;
97
- if (rootRepo || perRepoRepo) {
98
- result.repo = { ...rootRepo, ...perRepoRepo };
95
+ // repo: false means opt out of all root repo settings
96
+ if (perRepo?.repo === false) {
97
+ // Opt-out: don't include any repo settings
98
+ }
99
+ else {
100
+ const rootRepo = root?.repo;
101
+ const perRepoRepo = perRepo?.repo;
102
+ if (rootRepo || perRepoRepo) {
103
+ result.repo = {
104
+ ...(rootRepo === false ? {} : rootRepo),
105
+ ...perRepoRepo,
106
+ };
107
+ }
99
108
  }
100
109
  return Object.keys(result).length > 0 ? result : undefined;
101
110
  }
@@ -7,7 +7,7 @@ export declare function validateRawConfig(config: RawConfig): void;
7
7
  /**
8
8
  * Validates settings object containing rulesets.
9
9
  */
10
- export declare function validateSettings(settings: unknown, context: string, rootRulesetNames?: string[]): void;
10
+ export declare function validateSettings(settings: unknown, context: string, rootRulesetNames?: string[], hasRootRepoSettings?: boolean): void;
11
11
  /**
12
12
  * Validates that config is suitable for the sync command.
13
13
  * @throws Error if files section is missing or empty
@@ -252,7 +252,8 @@ export function validateRawConfig(config) {
252
252
  const rootRulesetNames = config.settings?.rulesets
253
253
  ? Object.keys(config.settings.rulesets).filter((k) => k !== "inherit")
254
254
  : [];
255
- validateSettings(repo.settings, `Repo ${getGitDisplayName(repo.git)}`, rootRulesetNames);
255
+ const hasRootRepoSettings = config.settings?.repo !== undefined && config.settings.repo !== false;
256
+ validateSettings(repo.settings, `Repo ${getGitDisplayName(repo.git)}`, rootRulesetNames, hasRootRepoSettings);
256
257
  }
257
258
  }
258
259
  }
@@ -557,7 +558,7 @@ function validateRuleset(ruleset, name, context) {
557
558
  /**
558
559
  * Validates settings object containing rulesets.
559
560
  */
560
- export function validateSettings(settings, context, rootRulesetNames) {
561
+ export function validateSettings(settings, context, rootRulesetNames, hasRootRepoSettings) {
561
562
  if (typeof settings !== "object" ||
562
563
  settings === null ||
563
564
  Array.isArray(settings)) {
@@ -590,7 +591,20 @@ export function validateSettings(settings, context, rootRulesetNames) {
590
591
  }
591
592
  // Validate repo settings
592
593
  if (s.repo !== undefined) {
593
- validateRepoSettings(s.repo, context);
594
+ if (s.repo === false) {
595
+ if (!rootRulesetNames) {
596
+ // Root level — repo: false not valid here
597
+ throw new Error(`${context}: repo: false is not valid at root level. Define repo settings or remove the field.`);
598
+ }
599
+ // Per-repo level — check root has repo settings to opt out of
600
+ if (!hasRootRepoSettings) {
601
+ throw new Error(`${context}: Cannot opt out of repo settings — not defined in root settings.repo`);
602
+ }
603
+ // Valid opt-out, skip further repo validation
604
+ }
605
+ else {
606
+ validateRepoSettings(s.repo, context);
607
+ }
594
608
  }
595
609
  }
596
610
  // =============================================================================
package/dist/config.d.ts CHANGED
@@ -291,7 +291,7 @@ export interface RawRepoSettings {
291
291
  rulesets?: Record<string, Ruleset | false> & {
292
292
  inherit?: boolean;
293
293
  };
294
- repo?: GitHubRepoSettings;
294
+ repo?: GitHubRepoSettings | false;
295
295
  deleteOrphaned?: boolean;
296
296
  }
297
297
  export interface RawRepoConfig {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aspruyt/xfg",
3
- "version": "3.6.0",
3
+ "version": "3.7.0",
4
4
  "description": "CLI tool for repository-as-code",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",