@firestartr/cli 2.7.0-snapshot-13 → 2.7.0-snapshot-14

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 (26) hide show
  1. package/build/index.js +1171 -273
  2. package/build/packages/cdk8s_renderer/index.d.ts +5 -3
  3. package/build/packages/cdk8s_renderer/src/charts/github/index.d.ts +1 -0
  4. package/build/packages/cdk8s_renderer/src/charts/github/orgSettingsChart.d.ts +8 -0
  5. package/build/packages/cdk8s_renderer/src/charts/index.d.ts +2 -1
  6. package/build/packages/cdk8s_renderer/src/claims/base/index.d.ts +1 -0
  7. package/build/packages/cdk8s_renderer/src/claims/base/orgSettings.d.ts +5 -0
  8. package/build/packages/cdk8s_renderer/src/claims/base/schemas/index.d.ts +139 -0
  9. package/build/packages/cdk8s_renderer/src/claims/base/schemas/orgsettings.schema.d.ts +32 -0
  10. package/build/packages/cdk8s_renderer/src/claims/github/index.d.ts +109 -0
  11. package/build/packages/cdk8s_renderer/src/claims/github/orgSettings.d.ts +34 -0
  12. package/build/packages/cdk8s_renderer/src/claims/github/orgsettings.schema.d.ts +111 -0
  13. package/build/packages/cdk8s_renderer/src/config.d.ts +4 -0
  14. package/build/packages/cdk8s_renderer/src/loader/lazy_loader.d.ts +1 -1
  15. package/build/packages/cdk8s_renderer/src/loader/loader.d.ts +7 -1
  16. package/build/packages/cdk8s_renderer/src/renderer/claims-render.d.ts +1 -1
  17. package/build/packages/cdk8s_renderer/src/validations/githubOrgSettings.d.ts +2 -0
  18. package/build/packages/gh_provisioner/src/entities/ghorgsettings/index.d.ts +7 -0
  19. package/build/packages/importer/src/decanter/gh/github_org_settings.d.ts +10 -0
  20. package/build/packages/importer/src/decanter/gh/github_org_settings_collection.d.ts +10 -0
  21. package/build/packages/importer/src/decanter/index.d.ts +2 -0
  22. package/build/packages/operator/src/ctl.d.ts +7 -0
  23. package/build/packages/operator/src/parentDependency.d.ts +30 -0
  24. package/build/packages/operator/src/processItem.d.ts +3 -0
  25. package/build/packages/operator/src/queueSort.d.ts +2 -0
  26. package/package.json +1 -1
package/build/index.js CHANGED
@@ -239466,7 +239466,7 @@ class SimpleTokenizer {
239466
239466
  ;// CONCATENATED MODULE: ../catalog_common/src/codeowners/index.ts
239467
239467
  // Common CODEOWNERS machinery (pure TypeScript/data; NO IO, NO classes)
239468
239468
  // Strictly follows GitHub CODEOWNERS syntax.
239469
- // Spec: see specs/common/001-common-codeowners-machinery/spec.md
239469
+ // Design: see packages/catalog_common/docs/adr/0001-codeowners-machinery-is-pure-data.md
239470
239470
 
239471
239471
  const OWNER_RE = /^@[\w.-]+(\/[\w.-]+)?$/;
239472
239472
  function parse(raw) {
@@ -278569,6 +278569,9 @@ class InitializerPatches extends BasePatches {
278569
278569
  if (data?.defaultValues) {
278570
278570
  this.data['values'] = data.defaultValues;
278571
278571
  }
278572
+ if (data?.path) {
278573
+ this.data['path'] = data.path;
278574
+ }
278572
278575
  }
278573
278576
  static FILE_NAME() {
278574
278577
  if (!this.fileName) {
@@ -278738,6 +278741,7 @@ UUIDInitializer.applicableKinds = [
278738
278741
  'ComponentClaim',
278739
278742
  'TFWorkspaceClaim',
278740
278743
  'OrgWebhookClaim',
278744
+ 'OrgSettingsClaim',
278741
278745
  ];
278742
278746
 
278743
278747
 
@@ -279392,6 +279396,7 @@ InitializerClaimRef.applicableKinds = [
279392
279396
  'ComponentClaim',
279393
279397
  'TFWorkspaceClaim',
279394
279398
  'OrgWebhookClaim',
279399
+ 'OrgSettingsClaim',
279395
279400
  ];
279396
279401
 
279397
279402
 
@@ -279722,6 +279727,20 @@ var external_fs_default = /*#__PURE__*/__nccwpck_require__.n(external_fs_);
279722
279727
  // List of currently set path variables for each entity type
279723
279728
  const __PATH_VARIABLES = {};
279724
279729
  const __EXCLUDED_PATHS = [];
279730
+ let repositoryUrl;
279731
+ let defaultBranch = 'main';
279732
+ function setRepositoryUrl(url) {
279733
+ repositoryUrl = url;
279734
+ }
279735
+ function getRepositoryUrl() {
279736
+ return repositoryUrl;
279737
+ }
279738
+ function setDefaultBranch(branch) {
279739
+ defaultBranch = branch;
279740
+ }
279741
+ function getDefaultBranch() {
279742
+ return defaultBranch;
279743
+ }
279725
279744
  function setExcludedPaths(excludedPaths) {
279726
279745
  __EXCLUDED_PATHS.length = 0;
279727
279746
  for (const path of excludedPaths) {
@@ -280379,6 +280398,8 @@ TechnologyInitializer.applicableKinds = ['ComponentClaim'];
280379
280398
 
280380
280399
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/initializers/backstage.ts
280381
280400
 
280401
+
280402
+
280382
280403
  class BackstageInitializer extends InitializerPatches {
280383
280404
  constructor() {
280384
280405
  super(...arguments);
@@ -280388,6 +280409,16 @@ class BackstageInitializer extends InitializerPatches {
280388
280409
  return true;
280389
280410
  }
280390
280411
  async __patches(claim, _) {
280412
+ const claimPath = this.data?.path;
280413
+ const repoUrl = getRepositoryUrl();
280414
+ let relativePath;
280415
+ if (repoUrl && claimPath) {
280416
+ const claimsRoot = getPath('claims');
280417
+ relativePath = external_path_.relative(claimsRoot, claimPath)
280418
+ .split(external_path_.sep)
280419
+ .map((segment) => encodeURIComponent(segment))
280420
+ .join('/');
280421
+ }
280391
280422
  return [
280392
280423
  {
280393
280424
  validate() {
@@ -280433,10 +280464,41 @@ class BackstageInitializer extends InitializerPatches {
280433
280464
  };
280434
280465
  },
280435
280466
  },
280467
+ {
280468
+ validate() {
280469
+ return true;
280470
+ },
280471
+ apply(cr) {
280472
+ if (!repoUrl || !relativePath)
280473
+ return cr;
280474
+ cr.metadata.annotations = cr.metadata.annotations ?? {};
280475
+ cr.metadata.annotations['backstage.io/edit-url'] =
280476
+ `${repoUrl}/blob/${getDefaultBranch()}/${relativePath}`;
280477
+ return cr;
280478
+ },
280479
+ identify() {
280480
+ return 'initializers/BackstageInitializer';
280481
+ },
280482
+ applicable() {
280483
+ return {
280484
+ applicableProviders: ['catalog'],
280485
+ };
280486
+ },
280487
+ },
280436
280488
  ];
280437
280489
  }
280438
280490
  }
280439
- BackstageInitializer.applicableKinds = ['ComponentClaim'];
280491
+ BackstageInitializer.applicableKinds = [
280492
+ 'ComponentClaim',
280493
+ 'SystemClaim',
280494
+ 'DomainClaim',
280495
+ 'GroupClaim',
280496
+ 'UserClaim',
280497
+ 'TFWorkspaceClaim',
280498
+ 'SecretsClaim',
280499
+ 'ArgoDeployClaim',
280500
+ 'OrgWebhookClaim',
280501
+ ];
280440
280502
 
280441
280503
 
280442
280504
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/initializers/syncer.ts
@@ -280688,6 +280750,7 @@ const INITIALIZERS_BY_FILE_NAME = {
280688
280750
  defaults_github_membership: InitializerDefault,
280689
280751
  defaults_github_group: InitializerDefault,
280690
280752
  defaults_github_orgwebhook: InitializerDefault,
280753
+ defaults_github_orgsettings: InitializerDefault,
280691
280754
  };
280692
280755
  const SCHEMAS_BY_INITIALIZER_NAME = {
280693
280756
  [TechnologyInitializer.FILE_NAME()]: technologies,
@@ -281838,6 +281901,38 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
281838
281901
  },
281839
281902
  });
281840
281903
 
281904
+ ;// CONCATENATED MODULE: ../cdk8s_renderer/src/claims/base/schemas/orgsettings.schema.ts
281905
+
281906
+ /* harmony default export */ const orgsettings_schema = ({
281907
+ $schema: SCHEMA,
281908
+ $id: 'OrgSettingsClaim',
281909
+ definitions: {
281910
+ OrgSettingsClaim: {
281911
+ $id: 'firestartr.dev://common/OrgSettingsClaim',
281912
+ type: 'object',
281913
+ description: 'A GitHub organization settings claim',
281914
+ unevaluatedProperties: false,
281915
+ allOf: [
281916
+ { $ref: 'firestartr.dev://common/ClaimEnvelope' },
281917
+ {
281918
+ type: 'object',
281919
+ properties: {
281920
+ providers: {
281921
+ type: 'object',
281922
+ properties: {
281923
+ github: {
281924
+ $ref: 'firestartr.dev://github/GithubOrgSettingsClaim',
281925
+ },
281926
+ },
281927
+ additionalProperties: false,
281928
+ },
281929
+ },
281930
+ },
281931
+ ],
281932
+ },
281933
+ },
281934
+ });
281935
+
281841
281936
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/claims/github/group.schema.ts
281842
281937
 
281843
281938
  /* harmony default export */ const github_group_schema = ({
@@ -282180,6 +282275,116 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
282180
282275
  },
282181
282276
  });
282182
282277
 
282278
+ ;// CONCATENATED MODULE: ../cdk8s_renderer/src/claims/github/orgsettings.schema.ts
282279
+
282280
+ const organizationSettingsProperties = {
282281
+ name: {
282282
+ type: 'string',
282283
+ },
282284
+ tfStateKey: {
282285
+ $ref: 'firestartr.dev://common/TerraformStateKey',
282286
+ },
282287
+ org: {
282288
+ $ref: 'firestartr.dev://common/ClaimName',
282289
+ },
282290
+ billing_email: {
282291
+ type: 'string',
282292
+ },
282293
+ twitter_username: {
282294
+ type: 'string',
282295
+ },
282296
+ company: {
282297
+ type: 'string',
282298
+ },
282299
+ blog: {
282300
+ type: 'string',
282301
+ },
282302
+ email: {
282303
+ type: 'string',
282304
+ },
282305
+ location: {
282306
+ type: 'string',
282307
+ },
282308
+ description: {
282309
+ type: 'string',
282310
+ },
282311
+ has_organization_projects: {
282312
+ type: 'boolean',
282313
+ },
282314
+ has_repository_projects: {
282315
+ type: 'boolean',
282316
+ },
282317
+ default_repository_permission: {
282318
+ type: 'string',
282319
+ enum: ['read', 'write', 'admin', 'none'],
282320
+ },
282321
+ members_can_create_repositories: {
282322
+ type: 'boolean',
282323
+ },
282324
+ members_can_create_public_repositories: {
282325
+ type: 'boolean',
282326
+ },
282327
+ members_can_create_private_repositories: {
282328
+ type: 'boolean',
282329
+ },
282330
+ members_can_create_internal_repositories: {
282331
+ type: 'boolean',
282332
+ },
282333
+ members_can_create_pages: {
282334
+ type: 'boolean',
282335
+ },
282336
+ members_can_create_public_pages: {
282337
+ type: 'boolean',
282338
+ },
282339
+ members_can_create_private_pages: {
282340
+ type: 'boolean',
282341
+ },
282342
+ members_can_fork_private_repositories: {
282343
+ type: 'boolean',
282344
+ },
282345
+ web_commit_signoff_required: {
282346
+ type: 'boolean',
282347
+ },
282348
+ advanced_security_enabled_for_new_repositories: {
282349
+ type: 'boolean',
282350
+ },
282351
+ dependabot_alerts_enabled_for_new_repositories: {
282352
+ type: 'boolean',
282353
+ },
282354
+ dependabot_security_updates_enabled_for_new_repositories: {
282355
+ type: 'boolean',
282356
+ },
282357
+ dependency_graph_enabled_for_new_repositories: {
282358
+ type: 'boolean',
282359
+ },
282360
+ secret_scanning_enabled_for_new_repositories: {
282361
+ type: 'boolean',
282362
+ },
282363
+ secret_scanning_push_protection_enabled_for_new_repositories: {
282364
+ type: 'boolean',
282365
+ },
282366
+ };
282367
+ /* harmony default export */ const github_orgsettings_schema = ({
282368
+ $schema: SCHEMA,
282369
+ $id: 'GithubOrgSettingsClaim',
282370
+ definitions: {
282371
+ GithubOrgSettingsClaim: {
282372
+ $id: 'firestartr.dev://github/GithubOrgSettingsClaim',
282373
+ type: 'object',
282374
+ description: 'A Github Organization Settings claim',
282375
+ allOf: [
282376
+ { $ref: 'firestartr.dev://common/ClaimProviderEnvelope' },
282377
+ {
282378
+ type: 'object',
282379
+ properties: organizationSettingsProperties,
282380
+ additionalProperties: false,
282381
+ required: ['org', 'billing_email'],
282382
+ },
282383
+ ],
282384
+ },
282385
+ },
282386
+ });
282387
+
282183
282388
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/claims/github/feature.schema.ts
282184
282389
 
282185
282390
  /* harmony default export */ const feature_schema = ({
@@ -282326,7 +282531,7 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
282326
282531
  type: 'string',
282327
282532
  minLength: 1,
282328
282533
  maxLength: 50,
282329
- pattern: '^(?!\\s+$)[^"\\\\]+$',
282534
+ pattern: '^[^"\\\\\\s]+(?: +[^"\\\\\\s]+)*$',
282330
282535
  description: 'Label name (1-50 chars, no " or \\ characters)',
282331
282536
  },
282332
282537
  color: {
@@ -282353,12 +282558,14 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
282353
282558
 
282354
282559
 
282355
282560
 
282561
+
282356
282562
  const GithubSchemas = [
282357
282563
  github_group_schema,
282358
282564
  github_user_schema,
282359
282565
  feature_schema,
282360
282566
  github_component_schema,
282361
282567
  github_orgwebhook_schema,
282568
+ github_orgsettings_schema,
282362
282569
  component_secrets_vars_schema,
282363
282570
  component_labels_schema,
282364
282571
  ];
@@ -282764,6 +282971,7 @@ const SecretsSchemas = [external_secrets_schema];
282764
282971
 
282765
282972
 
282766
282973
 
282974
+
282767
282975
  const schemas = {
282768
282976
  root: root_schema,
282769
282977
  schemas: [
@@ -282781,6 +282989,7 @@ const schemas = {
282781
282989
  SecretsSchemas,
282782
282990
  secrets_schema,
282783
282991
  orgwebhook_schema,
282992
+ orgsettings_schema,
282784
282993
  ],
282785
282994
  };
282786
282995
  /* harmony default export */ const base_schemas = (schemas);
@@ -282887,6 +283096,9 @@ const deploy_schema = 'firestartr.dev://common/ArgoDeployClaim';
282887
283096
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/claims/base/orgWebhook.ts
282888
283097
  const orgWebhook_schema = 'firestartr.dev://common/OrgWebhookClaim';
282889
283098
 
283099
+ ;// CONCATENATED MODULE: ../cdk8s_renderer/src/claims/base/orgSettings.ts
283100
+ const orgSettings_schema = 'firestartr.dev://common/OrgSettingsClaim';
283101
+
282890
283102
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/claims/base/secrets.ts
282891
283103
  const base_secrets_schema = 'firestartr.dev://common/SecretsClaim';
282892
283104
 
@@ -282900,6 +283112,7 @@ const base_secrets_schema = 'firestartr.dev://common/SecretsClaim';
282900
283112
 
282901
283113
 
282902
283114
 
283115
+
282903
283116
  /* harmony default export */ const base = ({
282904
283117
  UserClaimSchema: schema,
282905
283118
  GroupClaimSchema: base_group_schema,
@@ -282909,6 +283122,7 @@ const base_secrets_schema = 'firestartr.dev://common/SecretsClaim';
282909
283122
  TFWorkspaceClaimSchema: workspace_schema,
282910
283123
  ArgoDeployClaimSchema: deploy_schema,
282911
283124
  OrgWebhookClaimSchema: orgWebhook_schema,
283125
+ OrgSettingsClaimSchema: orgSettings_schema,
282912
283126
  SecretsClaimSchema: base_secrets_schema,
282913
283127
  });
282914
283128
 
@@ -283116,7 +283330,7 @@ async function setVirtualClaimAdditionalData(renderedData, claim, claimRef) {
283116
283330
  return renderedData;
283117
283331
  }
283118
283332
  async function setNonVirtualClaimAdditionalData(renderedData, claim, claimRef, loadInitializers, loadGlobals, loadOverrides, loadNormalizers) {
283119
- renderedData[claimRef]['initializers'] = await loadInitializers(claim);
283333
+ renderedData[claimRef]['initializers'] = await loadInitializers(claim, renderedData[claimRef]['claimPath']);
283120
283334
  renderedData[claimRef]['globals'] = await loadGlobals(claim);
283121
283335
  renderedData[claimRef]['overrides'] = loadOverrides(claim);
283122
283336
  renderedData[claimRef]['normalizers'] = await loadNormalizers(claim, renderedData[claimRef]['claimPath']);
@@ -283278,7 +283492,7 @@ async function loadNormalizers(_claim, path) {
283278
283492
  *
283279
283493
  */
283280
283494
  let loadedInitializers = false;
283281
- async function loadInitializers(claim, initializersPath = getPath('initializers')) {
283495
+ async function loadInitializers(claim, claimPath, initializersPath = getPath('initializers')) {
283282
283496
  const result = [];
283283
283497
  await crawl(initializersPath, (entry) => {
283284
283498
  return isYamlFile.test(entry);
@@ -283301,7 +283515,7 @@ async function loadInitializers(claim, initializersPath = getPath('initializers'
283301
283515
  });
283302
283516
  for (const initializer of INITIALIZERS) {
283303
283517
  if (initializer.applicableKinds.includes(claim.kind)) {
283304
- result.push(new initializer());
283518
+ result.push(new initializer({ path: claimPath }));
283305
283519
  }
283306
283520
  }
283307
283521
  logger.info(`Loaded initializers ${JSON.stringify(result)}`);
@@ -283336,35 +283550,41 @@ function loader_patchClaim(claim, defaultsClaims) {
283336
283550
  }
283337
283551
  return claim;
283338
283552
  }
283339
- /*
283340
- * Loads all CRs and stores them into a object.
283341
- *
283342
- * This function receives no input.
283343
- *
283344
- * Returns:
283345
- * - An object promise which contains each loaded CR
283346
- *
283347
- */
283348
- async function loadCRs(crsPath = getPath('crs'), excludedPaths = [getPath('globals'), getPath('initializers')], allowedClaimReferences = []) {
283553
+ async function loadCRsWithFullSet(crsPath = getPath('crs'), excludedPaths = [getPath('globals'), getPath('initializers')], allowedClaimReferences = []) {
283349
283554
  const result = {};
283555
+ const fullResult = {};
283350
283556
  await crawlWithExclusions(crsPath, (entry) => {
283351
283557
  return isYamlFile.test(entry);
283352
283558
  }, async (entry, data) => {
283353
283559
  const yamlData = stripKnownRelations(catalog_common/* default.io.fromYaml */.Z.io.fromYaml(data));
283354
- if (!('kind' in yamlData && 'name' in yamlData.metadata)) {
283355
- logger.warn(`Invalid claim file ${entry}`);
283356
- }
283357
- else {
283358
- if (result[`${yamlData.kind}-${yamlData.metadata.name}`]) {
283359
- logger.error(`Duplicate CR ${yamlData.kind}-${yamlData.metadata.name}`);
283360
- }
283560
+ const metadata = yamlData?.metadata;
283561
+ if (!(yamlData &&
283562
+ typeof yamlData === 'object' &&
283563
+ 'kind' in yamlData &&
283564
+ metadata &&
283565
+ typeof metadata === 'object' &&
283566
+ 'name' in metadata)) {
283567
+ logger.warn(`Invalid CR file ${entry}`);
283568
+ }
283569
+ else {
283570
+ const crKey = `${yamlData.kind}-${metadata.name}`;
283571
+ if (fullResult[crKey]) {
283572
+ logger.error(`Duplicate CR ${crKey}`);
283573
+ }
283574
+ // Keep the complete CR set for validations that need repository-wide context.
283575
+ fullResult[crKey] = yamlData;
283576
+ // Keep the filtered CR set for previous-CR lookup during claim rendering.
283361
283577
  if (allowedClaimReferences.length === 0 ||
283362
283578
  allowedClaimReferences.includes(yamlData.metadata?.annotations?.[catalog_common/* default.generic.getFirestartrAnnotation */.Z.generic.getFirestartrAnnotation('claim-ref')])) {
283363
- result[`${yamlData.kind}-${yamlData.metadata.name}`] = yamlData;
283579
+ result[crKey] = yamlData;
283364
283580
  }
283365
283581
  }
283366
283582
  }, excludedPaths.concat(getAdditionalPaths()));
283367
- return result;
283583
+ return { crs: result, fullCrs: fullResult };
283584
+ }
283585
+ async function loadCRs(crsPath = getPath('crs'), excludedPaths = [getPath('globals'), getPath('initializers')], allowedClaimReferences = []) {
283586
+ const { crs } = await loadCRsWithFullSet(crsPath, excludedPaths, allowedClaimReferences);
283587
+ return crs;
283368
283588
  }
283369
283589
  /*
283370
283590
  * Description: Get the renamed using claimRef annotation
@@ -283414,6 +283634,7 @@ async function loadClaimsList(claimRefList, claimsPath = getPath('claims')) {
283414
283634
  const data = {
283415
283635
  renderClaims: {},
283416
283636
  crs: {},
283637
+ fullCrs: {},
283417
283638
  };
283418
283639
  const defaults = loadClaimDefaults();
283419
283640
  for await (const claimRef of claimRefList) {
@@ -283425,7 +283646,9 @@ async function loadClaimsList(claimRefList, claimsPath = getPath('claims')) {
283425
283646
  // Replaces only the first instance of '-'
283426
283647
  crClaimReferences.push(ref.replace('-', '/'));
283427
283648
  }
283428
- data['crs'] = await loadCRs(getPath('crs'), [getPath('globals'), getPath('initializers')], crClaimReferences);
283649
+ const loadedCrs = await loadCRsWithFullSet(getPath('crs'), [getPath('globals'), getPath('initializers')], crClaimReferences);
283650
+ data['crs'] = loadedCrs.crs;
283651
+ data['fullCrs'] = loadedCrs.fullCrs;
283429
283652
  return data;
283430
283653
  }
283431
283654
  function getOrg() {
@@ -288975,12 +289198,71 @@ class GithubOrgWebhookChart extends BaseGithubChart {
288975
289198
  }
288976
289199
  }
288977
289200
 
289201
+ ;// CONCATENATED MODULE: ../cdk8s_renderer/src/charts/github/orgSettingsChart.ts
289202
+
289203
+
289204
+ class GithubOrgSettingsChart extends BaseGithubChart {
289205
+ template() {
289206
+ const claim = this.get('claim');
289207
+ const firestartrId = this.get('firestartrId');
289208
+ const githubProvider = claim.providers.github;
289209
+ const template = {
289210
+ metadata: {
289211
+ name: githubProvider.name,
289212
+ },
289213
+ spec: {
289214
+ org: githubProvider.org,
289215
+ billingEmail: githubProvider.billing_email,
289216
+ company: githubProvider.company,
289217
+ blog: githubProvider.blog,
289218
+ email: githubProvider.email,
289219
+ twitterUsername: githubProvider.twitter_username,
289220
+ location: githubProvider.location,
289221
+ description: githubProvider.description,
289222
+ hasOrganizationProjects: githubProvider.has_organization_projects,
289223
+ hasRepositoryProjects: githubProvider.has_repository_projects,
289224
+ defaultRepositoryPermission: githubProvider.default_repository_permission,
289225
+ membersCanCreateRepositories: githubProvider.members_can_create_repositories,
289226
+ membersCanCreatePublicRepositories: githubProvider.members_can_create_public_repositories,
289227
+ membersCanCreatePrivateRepositories: githubProvider.members_can_create_private_repositories,
289228
+ membersCanCreateInternalRepositories: githubProvider.members_can_create_internal_repositories,
289229
+ membersCanCreatePages: githubProvider.members_can_create_pages,
289230
+ membersCanCreatePublicPages: githubProvider.members_can_create_public_pages,
289231
+ membersCanCreatePrivatePages: githubProvider.members_can_create_private_pages,
289232
+ membersCanForkPrivateRepositories: githubProvider.members_can_fork_private_repositories,
289233
+ webCommitSignoffRequired: githubProvider.web_commit_signoff_required,
289234
+ advancedSecurityEnabledForNewRepositories: githubProvider.advanced_security_enabled_for_new_repositories,
289235
+ dependabotAlertsEnabledForNewRepositories: githubProvider.dependabot_alerts_enabled_for_new_repositories,
289236
+ dependabotSecurityUpdatesEnabledForNewRepositories: githubProvider.dependabot_security_updates_enabled_for_new_repositories,
289237
+ dependencyGraphEnabledForNewRepositories: githubProvider.dependency_graph_enabled_for_new_repositories,
289238
+ secretScanningEnabledForNewRepositories: githubProvider.secret_scanning_enabled_for_new_repositories,
289239
+ secretScanningPushProtectionEnabledForNewRepositories: githubProvider.secret_scanning_push_protection_enabled_for_new_repositories,
289240
+ firestartr: {
289241
+ tfStateKey: firestartrId,
289242
+ },
289243
+ writeConnectionSecretToRef: {
289244
+ name: `firestartrgithuborganizationsettings-${githubProvider.name}-outputs`.toLowerCase(),
289245
+ outputs: [],
289246
+ },
289247
+ },
289248
+ };
289249
+ return JSON.parse(JSON.stringify(template));
289250
+ }
289251
+ gvk() {
289252
+ return FirestartrGithubOrganizationSettings.GVK;
289253
+ }
289254
+ instanceApiObject(template) {
289255
+ return new FirestartrGithubOrganizationSettings(this, template.metadata.name, template);
289256
+ }
289257
+ }
289258
+
288978
289259
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/charts/github/index.ts
288979
289260
 
288980
289261
 
288981
289262
 
288982
289263
 
288983
289264
 
289265
+
288984
289266
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/charts/catalog/base.ts
288985
289267
 
288986
289268
  class BaseCatalogChart extends BaseChart {
@@ -289724,6 +290006,7 @@ class SecretsChart extends BaseSecretsChart {
289724
290006
  ArgoDeployChart: ArgoDeployChart,
289725
290007
  SecretsChart: SecretsChart,
289726
290008
  GithubOrgWebhookChart: GithubOrgWebhookChart,
290009
+ GithubOrgSettingsChart: GithubOrgSettingsChart,
289727
290010
  });
289728
290011
 
289729
290012
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/renderer/claims-render.ts
@@ -289735,6 +290018,7 @@ class SecretsChart extends BaseSecretsChart {
289735
290018
 
289736
290019
 
289737
290020
 
290021
+
289738
290022
  function normalizeProvidesApis(providesApis) {
289739
290023
  if (!providesApis)
289740
290024
  return [];
@@ -289756,6 +290040,7 @@ async function renderClaims(catalogScope, firestartrScope, data) {
289756
290040
  'TFWorkspaceClaim',
289757
290041
  'ArgoDeployClaim',
289758
290042
  'OrgWebhookClaim',
290043
+ 'OrgSettingsClaim',
289759
290044
  ], renderClaims);
289760
290045
  for (const renderClaims of sortedKinds) {
289761
290046
  for (const claimKey of Object.keys(renderClaims)) {
@@ -289770,7 +290055,8 @@ async function renderClaims(catalogScope, firestartrScope, data) {
289770
290055
  if (!previousCR) {
289771
290056
  logger.debug(`No CR found for claim ${claimKey}, it will be rendered from scratch`);
289772
290057
  }
289773
- const { firestartrEntity, extraCharts, catalogEntity } = await renderClaim(catalogScope, firestartrScope, claim, patches, previousCR);
290058
+ const claimPath = renderClaims[claimKey].claimPath;
290059
+ const { firestartrEntity, extraCharts, catalogEntity } = await renderClaim(catalogScope, firestartrScope, claim, patches, previousCR, claimPath);
289774
290060
  if (catalogEntity) {
289775
290061
  result[`${catalogEntity.kind}-${catalogEntity.metadata.name}`] =
289776
290062
  catalogEntity.toJson();
@@ -289799,7 +290085,7 @@ async function renderClaims(catalogScope, firestartrScope, data) {
289799
290085
  }
289800
290086
  return result;
289801
290087
  }
289802
- async function renderClaim(catalogScope, firestartrScope, claim, patches, previousCR = null) {
290088
+ async function renderClaim(catalogScope, firestartrScope, claim, patches, previousCR = null, claimPath) {
289803
290089
  let catalogEntity = undefined;
289804
290090
  let firestartrEntity = undefined;
289805
290091
  const extraCharts = [];
@@ -289867,6 +290153,20 @@ async function renderClaim(catalogScope, firestartrScope, claim, patches, previo
289867
290153
  .join('/');
289868
290154
  const definitionUrl = `https://github.com/${org}/${repoName}/blob/${defaultBranch}/${encodedDefinitionFilePath}`;
289869
290155
  const sanitizedApiName = sanitizeApiEntityName(apiDefinition.name);
290156
+ const repoUrl = getRepositoryUrl();
290157
+ const apiAnnotations = {
290158
+ ...(claim.annotations || {}),
290159
+ title: apiDefinition.name,
290160
+ };
290161
+ if (repoUrl && claimPath) {
290162
+ const claimsRoot = getPath('claims');
290163
+ const relativePath = external_path_.relative(claimsRoot, claimPath)
290164
+ .split(external_path_.sep)
290165
+ .map((segment) => encodeURIComponent(segment))
290166
+ .join('/');
290167
+ apiAnnotations['backstage.io/edit-url'] =
290168
+ `${repoUrl}/blob/${defaultBranch}/${relativePath}`;
290169
+ }
289870
290170
  const apiChart = new charts.CatalogApiChart(catalogScope, `${chartId}-api-${sanitizedApiName}`, firestartrId, {
289871
290171
  name: sanitizedApiName,
289872
290172
  type: apiDefinition.type,
@@ -289874,10 +290174,7 @@ async function renderClaim(catalogScope, firestartrScope, claim, patches, previo
289874
290174
  owner: claim.owner,
289875
290175
  system: claim.system,
289876
290176
  definitionUrl,
289877
- annotations: {
289878
- ...(claim.annotations || {}),
289879
- title: apiDefinition.name,
289880
- },
290177
+ annotations: apiAnnotations,
289881
290178
  }, []);
289882
290179
  await apiChart.render();
289883
290180
  const apiObject = await apiChart.postRenderer([]);
@@ -289930,6 +290227,11 @@ async function renderClaim(catalogScope, firestartrScope, claim, patches, previo
289930
290227
  firestartrEntity = new charts.GithubOrgWebhookChart(firestartrScope, `github-${chartId}`, firestartrId, claim, renderPatches);
289931
290228
  }
289932
290229
  break;
290230
+ case 'OrgSettingsClaim':
290231
+ if (loadGithub) {
290232
+ firestartrEntity = new charts.GithubOrgSettingsChart(firestartrScope, `github-${chartId}`, firestartrId, claim, renderPatches);
290233
+ }
290234
+ break;
289933
290235
  default:
289934
290236
  console.error(`Unknown claim kind: ${claim.kind}`);
289935
290237
  break;
@@ -289946,7 +290248,7 @@ async function renderClaim(catalogScope, firestartrScope, claim, patches, previo
289946
290248
  *
289947
290249
  */
289948
290250
  const [catalogChart, firestartrEntityChart] = await Promise.all([
289949
- loadCatalog ? catalogEntity.render() : Promise.resolve(undefined),
290251
+ catalogEntity ? catalogEntity.render() : Promise.resolve(undefined),
289950
290252
  firestartrEntity?.render(),
289951
290253
  ]);
289952
290254
  /*
@@ -289955,7 +290257,7 @@ async function renderClaim(catalogScope, firestartrScope, claim, patches, previo
289955
290257
  *
289956
290258
  */
289957
290259
  return {
289958
- catalogEntity: loadCatalog
290260
+ catalogEntity: catalogChart
289959
290261
  ? await catalogChart.postRenderer(postPatches)
289960
290262
  : undefined,
289961
290263
  firestartrEntity: await (firestartrEntityChart
@@ -290044,6 +290346,39 @@ function validateComponentPagesPath(_renderClaims) {
290044
290346
  return;
290045
290347
  }
290046
290348
 
290349
+ ;// CONCATENATED MODULE: ../cdk8s_renderer/src/validations/githubOrgSettings.ts
290350
+ const GITHUB_ORG_SETTINGS_KIND = 'FirestartrGithubOrganizationSettings';
290351
+ const FIRESTARTR_CLAIM_REF_ANNOTATION = 'firestartr.dev/claim-ref';
290352
+ const CLAIM_REF_LABEL = 'claim-ref';
290353
+ function formatResourceRef(name, claimRef) {
290354
+ return claimRef ? `${name} (claim: ${claimRef})` : name;
290355
+ }
290356
+ // Render-time singleton: at most one FirestartrGithubOrganizationSettings per
290357
+ // GitHub org (case-insensitive) across the whole rendered set. See ADR 0003.
290358
+ function validateGithubOrgSettingsSingleton(crs) {
290359
+ const refsByOrg = new Map();
290360
+ for (const crKey of Object.keys(crs)) {
290361
+ const cr = crs[crKey];
290362
+ if (cr.kind !== GITHUB_ORG_SETTINGS_KIND)
290363
+ continue;
290364
+ const org = cr.spec?.org;
290365
+ if (typeof org !== 'string' || !org)
290366
+ continue;
290367
+ const name = cr.metadata?.name || crKey;
290368
+ const claimRef = cr.metadata?.annotations?.[FIRESTARTR_CLAIM_REF_ANNOTATION] ||
290369
+ cr.metadata?.labels?.[CLAIM_REF_LABEL];
290370
+ const normalizedOrg = org.toLowerCase();
290371
+ const refs = refsByOrg.get(normalizedOrg) || [];
290372
+ refs.push(formatResourceRef(name, claimRef));
290373
+ refsByOrg.set(normalizedOrg, refs);
290374
+ }
290375
+ for (const [org, refs] of refsByOrg.entries()) {
290376
+ if (refs.length < 2)
290377
+ continue;
290378
+ throw new Error(`Duplicate ${GITHUB_ORG_SETTINGS_KIND} resources found for GitHub organization "${org}": ${refs.join(', ')}`);
290379
+ }
290380
+ }
290381
+
290047
290382
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/renderer/renderer.ts
290048
290383
 
290049
290384
 
@@ -290053,6 +290388,7 @@ function validateComponentPagesPath(_renderClaims) {
290053
290388
 
290054
290389
 
290055
290390
 
290391
+
290056
290392
  /*
290057
290393
  * Function called when rendering but not importing
290058
290394
  *
@@ -290067,10 +290403,15 @@ function validateComponentPagesPath(_renderClaims) {
290067
290403
  async function renderer_render(catalogScope, firestartrScope, claimList) {
290068
290404
  const data = await loadClaimsList(claimList);
290069
290405
  const result = await renderClaims(catalogScope, firestartrScope, data);
290406
+ const fullCrSet = {
290407
+ ...data.fullCrs,
290408
+ ...result,
290409
+ };
290070
290410
  try {
290071
290411
  validateSubReferences(data.renderClaims);
290072
290412
  validateComponentPagesPath(data.renderClaims);
290073
290413
  validateTfStateKeyUniqueness(result);
290414
+ validateGithubOrgSettingsSingleton(fullCrSet);
290074
290415
  validateCrSizes(result);
290075
290416
  validatePermissionsUniqueness(result);
290076
290417
  }
@@ -290500,6 +290841,8 @@ async function addLastStateAndLastClaimAnnotations(filePath, lastStatePRLink, la
290500
290841
  INITIALIZERS_BY_FILE_NAME: INITIALIZERS_BY_FILE_NAME,
290501
290842
  NORMALIZERS: NORMALIZERS,
290502
290843
  AllowedProviders: AllowedProviders,
290844
+ setRepositoryUrl: setRepositoryUrl,
290845
+ setDefaultBranch: setDefaultBranch,
290503
290846
  runComparer: runComparer,
290504
290847
  isCatalogEntity: isCatalogEntity,
290505
290848
  loadCRs: loadCRs,
@@ -290523,7 +290866,7 @@ async function addLastStateAndLastClaimAnnotations(filePath, lastStatePRLink, la
290523
290866
  * This function returns nothing.
290524
290867
  *
290525
290868
  */
290526
- async function runRenderer(globalsPath, initializersPath, claimsPath, crsPath, claimsDefaults, outputCatalogDir, outputCrDir, renamesEnabled, provider, excludedPaths = [], validateReferentialIntegrity, claimRefs = '', claimFilesList = '') {
290869
+ async function runRenderer(globalsPath, initializersPath, claimsPath, crsPath, claimsDefaults, outputCatalogDir, outputCrDir, renamesEnabled, provider, excludedPaths = [], validateReferentialIntegrity, claimRefs = '', claimFilesList = '', repositoryUrl, defaultBranch) {
290527
290870
  configureProvider(provider);
290528
290871
  setPath('initializers', initializersPath);
290529
290872
  setPath('crs', crsPath);
@@ -290532,6 +290875,8 @@ async function runRenderer(globalsPath, initializersPath, claimsPath, crsPath, c
290532
290875
  setPath('claimsDefaults', claimsDefaults);
290533
290876
  setRenamesEnabled(renamesEnabled);
290534
290877
  setExcludedPaths(excludedPaths);
290878
+ setRepositoryUrl(repositoryUrl);
290879
+ setDefaultBranch(defaultBranch ?? 'main');
290535
290880
  const catalogApp = new lib.App({
290536
290881
  outdir: outputCatalogDir,
290537
290882
  outputFileExtension: '.yaml',
@@ -291058,6 +291403,107 @@ MemberCollectionGithubDecanter.collectionKind = 'gh-members';
291058
291403
  applyCollectionMixins(MemberCollectionGithubDecanter);
291059
291404
  /* harmony default export */ const github_member_collection = (MemberCollectionGithubDecanter);
291060
291405
 
291406
+ ;// CONCATENATED MODULE: ../importer/src/decanter/gh/github_org_settings.ts
291407
+
291408
+
291409
+ const ORG_SETTINGS_OPTIONAL_FIELDS = [
291410
+ 'twitter_username',
291411
+ 'company',
291412
+ 'blog',
291413
+ 'email',
291414
+ 'location',
291415
+ 'description',
291416
+ 'has_organization_projects',
291417
+ 'has_repository_projects',
291418
+ 'default_repository_permission',
291419
+ 'members_can_create_repositories',
291420
+ 'members_can_create_public_repositories',
291421
+ 'members_can_create_private_repositories',
291422
+ 'members_can_create_internal_repositories',
291423
+ 'members_can_create_pages',
291424
+ 'members_can_create_public_pages',
291425
+ 'members_can_create_private_pages',
291426
+ 'members_can_fork_private_repositories',
291427
+ 'web_commit_signoff_required',
291428
+ 'advanced_security_enabled_for_new_repositories',
291429
+ 'dependabot_alerts_enabled_for_new_repositories',
291430
+ 'dependabot_security_updates_enabled_for_new_repositories',
291431
+ 'dependency_graph_enabled_for_new_repositories',
291432
+ 'secret_scanning_enabled_for_new_repositories',
291433
+ 'secret_scanning_push_protection_enabled_for_new_repositories',
291434
+ ];
291435
+ class OrgSettingsGithubDecanter extends GithubDecanter {
291436
+ constructor() {
291437
+ super(...arguments);
291438
+ this.claimKind = 'OrgSettingsClaim';
291439
+ }
291440
+ __decantStart() {
291441
+ this.claim = {
291442
+ kind: this.claimKind,
291443
+ version: this.VERSION(),
291444
+ name: this.orgSettingsName(),
291445
+ };
291446
+ }
291447
+ __decantProviders() {
291448
+ importer_src_logger.info(`Decanting GitHub organization settings providers for ${this.org}`);
291449
+ this.__patchClaim({
291450
+ op: 'add',
291451
+ value: {
291452
+ github: this.data.providerPayload,
291453
+ },
291454
+ path: '/providers',
291455
+ });
291456
+ }
291457
+ async __gatherOrgSettings() {
291458
+ importer_src_logger.info(`Gathering GitHub organization settings for ${this.org}`);
291459
+ this.data.orgSettings = await this.github.org.getOrgInfo(this.org);
291460
+ }
291461
+ __gatherProviderPayload() {
291462
+ const billingEmail = this.data.orgSettings.billing_email;
291463
+ if (typeof billingEmail !== 'string' || billingEmail.trim() === '') {
291464
+ throw new Error(`GitHub organization ${this.org} did not return billing_email. ` +
291465
+ 'billing_email is required for OrgSettingsClaim / FirestartrGithubOrganizationSettings. ' +
291466
+ 'Run importer with credentials that can read billing email or create/manage the claim manually.');
291467
+ }
291468
+ const providerPayload = {
291469
+ name: this.orgSettingsName(),
291470
+ org: this.org,
291471
+ billing_email: billingEmail,
291472
+ };
291473
+ for (const field of ORG_SETTINGS_OPTIONAL_FIELDS) {
291474
+ const value = this.data.orgSettings[field];
291475
+ if (value !== undefined && value !== null) {
291476
+ providerPayload[field] = value;
291477
+ }
291478
+ }
291479
+ this.data.providerPayload = providerPayload;
291480
+ importer_src_logger.info(`Prepared GitHub organization settings claim payload for ${this.org}`);
291481
+ }
291482
+ async __adaptInitializerBase(_claim) {
291483
+ return await this.__loadInitializer('defaults_github_orgsettings.yaml');
291484
+ }
291485
+ orgSettingsName() {
291486
+ return `${this.org.toLowerCase()}-org-settings`;
291487
+ }
291488
+ }
291489
+
291490
+ ;// CONCATENATED MODULE: ../importer/src/decanter/gh/github_org_settings_collection.ts
291491
+
291492
+
291493
+
291494
+ class OrgSettingsCollectionGithubDecanter extends GithubDecanter {
291495
+ async collection(filters = []) {
291496
+ if (this.IS_SKIP_SET(filters, OrgSettingsCollectionGithubDecanter.collectionKind)) {
291497
+ return [];
291498
+ }
291499
+ const filteredOrgs = await this.filter(OrgSettingsCollectionGithubDecanter.collectionKind, filters, [this.org]);
291500
+ return filteredOrgs.map((orgName) => new OrgSettingsGithubDecanter({}, orgName));
291501
+ }
291502
+ }
291503
+ OrgSettingsCollectionGithubDecanter.collectionKind = 'gh-org-settings';
291504
+ applyCollectionMixins(OrgSettingsCollectionGithubDecanter);
291505
+ /* harmony default export */ const github_org_settings_collection = (OrgSettingsCollectionGithubDecanter);
291506
+
291061
291507
  ;// CONCATENATED MODULE: ../importer/src/utils/codeowner.ts
291062
291508
  function extractFromCodeOwners(codeOwnersContent) {
291063
291509
  if (!codeOwnersContent) {
@@ -291553,6 +291999,7 @@ applyCollectionMixins(RepoCollectionGithubDecanter);
291553
291999
 
291554
292000
 
291555
292001
 
292002
+
291556
292003
  // A single claim can render multiple CRs.
291557
292004
  // Some of those rendered kinds are derived/child resources whose parent is the
291558
292005
  // main CR for the claim, so they do not correspond to claim files that should be moved.
@@ -291564,6 +292011,7 @@ let previousCRs = {};
291564
292011
  const collections = {
291565
292012
  GroupCollectionGithubDecanter: github_group_collection,
291566
292013
  MemberCollectionGithubDecanter: github_member_collection,
292014
+ OrgSettingsCollectionGithubDecanter: github_org_settings_collection,
291567
292015
  RepoCollectionGithubDecanter: github_repo_collection,
291568
292016
  };
291569
292017
  function isInPreviousCRs(kind, name) {
@@ -291656,9 +292104,11 @@ function getClaimPathFromCR(claimsBasePath, cr) {
291656
292104
  FirestartrGithubGroup: 'groups',
291657
292105
  FirestartrGithubRepository: 'components',
291658
292106
  FirestartrGithubMembership: 'users',
292107
+ // common.io.writeClaim derives OrgSettingsClaim -> orgsettingss.
292108
+ FirestartrGithubOrganizationSettings: 'orgsettingss',
291659
292109
  };
291660
292110
  const claimRef = `${cr.metadata.annotations['firestartr.dev/claim-ref']}.yaml`.toLowerCase();
291661
- return external_path_.join(claimsBasePath, mapCrsToClaims[cr.kind], claimRef.replace(/^[^/]+/, ''));
292111
+ return external_path_.join(claimsBasePath, mapCrsToClaims[cr.kind], claimRef.replace(/^[^/]+\//, ''));
291662
292112
  }
291663
292113
  function getCrPath(crsBasePath, cr) {
291664
292114
  return external_path_.join(crsBasePath, `${cr.kind}.${cr.metadata.name}.yaml`);
@@ -291669,6 +292119,7 @@ async function getDataFromKinds(org, filters = [], needsReImport) {
291669
292119
  importGithubMemberships(org, filters, needsReImport).then((memberships) => (data['memberships'] = memberships)),
291670
292120
  importGithubGroups(org, filters, needsReImport).then((groups) => (data['groups'] = groups)),
291671
292121
  importGithubRepositories(org, filters, needsReImport).then((repos) => (data['repos'] = repos)),
292122
+ importGithubOrgSettings(org, filters, needsReImport).then((orgSettings) => (data['orgSettings'] = orgSettings)),
291672
292123
  ]);
291673
292124
  const renderClaims = {};
291674
292125
  const deps = {};
@@ -291695,6 +292146,12 @@ async function getDataFromKinds(org, filters = [], needsReImport) {
291695
292146
  membership.deps;
291696
292147
  postRender[`FirestartrGithubMembership-${membership.renderClaim.claim.name}`] = membership.postRenderFunctions;
291697
292148
  }
292149
+ for (const orgSettings of data['orgSettings']) {
292150
+ renderClaims[`OrgSettingsClaim-${orgSettings.renderClaim.claim.name}`] =
292151
+ orgSettings.renderClaim;
292152
+ deps[`FirestartrGithubOrganizationSettings-${orgSettings.renderClaim.claim.name}`] = orgSettings.deps;
292153
+ postRender[`FirestartrGithubOrganizationSettings-${orgSettings.renderClaim.claim.name}`] = orgSettings.postRenderFunctions;
292154
+ }
291698
292155
  return { renderClaims, deps: deps, postRender: postRender };
291699
292156
  }
291700
292157
  async function importGithubGroups(org, filters = [], needsReImport) {
@@ -291737,6 +292194,19 @@ async function importGithubMemberships(org, filters = [], needsReImport) {
291737
292194
  }
291738
292195
  return memberships;
291739
292196
  }
292197
+ async function importGithubOrgSettings(org, filters = [], needsReImport) {
292198
+ const orgSettingsList = [];
292199
+ const orgSettingsCollection = new github_org_settings_collection({}, org);
292200
+ const collection = await orgSettingsCollection.collection(filters);
292201
+ for (const orgSettings of collection) {
292202
+ orgSettings.needsReImport = needsReImport;
292203
+ await orgSettings.gather();
292204
+ await orgSettings.decant();
292205
+ orgSettingsList.push(await orgSettings.adapt());
292206
+ orgSettings.render();
292207
+ }
292208
+ return orgSettingsList;
292209
+ }
291740
292210
  async function getPreviousCrs(crsPath) { }
291741
292211
  /* harmony default export */ const decanter = ({ importGithubGitopsRepository });
291742
292212
 
@@ -291788,6 +292258,7 @@ const KIND_TO_COLLECTION_FILTERS = {
291788
292258
  FirestartrGithubRepository: 'gh-repo',
291789
292259
  FirestartrGithubGroup: 'gh-group',
291790
292260
  FirestartrGithubMembership: 'gh-members',
292261
+ FirestartrGithubOrganizationSettings: 'gh-org-settings',
291791
292262
  };
291792
292263
  const DEPENDANT_KINDS = [
291793
292264
  'FirestartrGithubRepositoryFeature',
@@ -291796,6 +292267,9 @@ const DEPENDANT_KINDS = [
291796
292267
  // we create a special Collection that will use
291797
292268
  class ReimportCollection {
291798
292269
  helperNameExtractor(cr) {
292270
+ if (cr.kind === 'FirestartrGithubOrganizationSettings') {
292271
+ return cr.spec.org;
292272
+ }
291799
292273
  return cr.metadata.annotations['firestartr.dev/external-name'];
291800
292274
  }
291801
292275
  isSkipped(cr, generatedFilters) {
@@ -291962,19 +292436,25 @@ function buildFilters(filters, force, crsPath, generatedFilters) {
291962
292436
  return generatedFilters;
291963
292437
  }
291964
292438
  function createSkipFilters(filters) {
291965
- const includedCollections = filters.map((f) => f.split(',')[0]);
291966
- const allFilters = filters.filter((f) => f.split(',')[0] === 'all');
292439
+ const crExistsFilter = 'all,FUNCTION=fCheckCRExistsOnDisk';
292440
+ const includedCollections = filters
292441
+ .filter((f) => f !== crExistsFilter)
292442
+ .map((f) => f.split(',')[0]);
292443
+ const allFilters = filters.filter((f) => f.split(',')[0] === 'all' && f !== crExistsFilter);
292444
+ const hasExplicitFilters = includedCollections.length > 0;
291967
292445
  for (const collectionClass of Object.values(collections)) {
291968
- if (allFilters.length > 0) {
291969
- for (const allFilter of allFilters) {
291970
- const adaptedFilter = allFilter.replace('all', collectionClass.collectionKind);
291971
- filters.push(adaptedFilter);
292446
+ const collectionKind = collectionClass.collectionKind;
292447
+ if (allFilters.length > 0 || !hasExplicitFilters) {
292448
+ for (const allFilter of [...allFilters, crExistsFilter]) {
292449
+ filters.push(allFilter.replace('all', collectionKind));
291972
292450
  }
291973
292451
  continue;
291974
292452
  }
291975
- if (includedCollections.indexOf(collectionClass.collectionKind) === -1) {
291976
- filters.push(`${collectionClass.collectionKind},SKIP=SKIP`);
292453
+ if (includedCollections.indexOf(collectionKind) === -1) {
292454
+ filters.push(`${collectionKind},SKIP=SKIP`);
292455
+ continue;
291977
292456
  }
292457
+ filters.push(crExistsFilter.replace('all', collectionKind));
291978
292458
  }
291979
292459
  return filters;
291980
292460
  }
@@ -292246,6 +292726,7 @@ const kindPluralMap = {
292246
292726
  githubrepositorysecretssections: 'FirestartrGithubRepositorySecretsSection',
292247
292727
  terraformmodules: 'FirestartrTerraformModule',
292248
292728
  githuborgwebhooks: 'FirestartrGithubOrgWebhook',
292729
+ githuborganizationsettings: 'FirestartrGithubOrganizationSettings',
292249
292730
  terraformworkspaces: 'FirestartrTerraformWorkspace',
292250
292731
  terraformworkspaceplans: 'FirestartrTerraformWorkspacePlan',
292251
292732
  providerconfigs: 'FirestartrProviderConfig',
@@ -292393,9 +292874,9 @@ function getOperatorProfile() {
292393
292874
  }
292394
292875
  async function getItem(kind, namespace, item) {
292395
292876
  const itemPath = `${namespace}/${kind}/${item.metadata.name}`;
292396
- return await getItemByItemPath(itemPath);
292877
+ return await ctl_getItemByItemPath(itemPath);
292397
292878
  }
292398
- async function getItemByItemPath(itemPath, apiGroup = catalog_common/* default.types.controller.FirestartrApiGroup */.Z.types.controller.FirestartrApiGroup, apiVersion = 'v1') {
292879
+ async function ctl_getItemByItemPath(itemPath, apiGroup = catalog_common/* default.types.controller.FirestartrApiGroup */.Z.types.controller.FirestartrApiGroup, apiVersion = 'v1') {
292399
292880
  try {
292400
292881
  operator_src_logger.debug(`The ctl is getting the item at '${itemPath}'.`);
292401
292882
  const { kc, opts } = await ctl_getConnection();
@@ -292419,6 +292900,39 @@ async function getItemByItemPath(itemPath, apiGroup = catalog_common/* default.t
292419
292900
  throw e;
292420
292901
  }
292421
292902
  }
292903
+ /**
292904
+ * Like getItemByItemPath but returns null when the resource is not found
292905
+ * (404) or there is a conflict (409), without logging those as errors.
292906
+ * Use this when a missing resource is an expected condition (e.g. checking
292907
+ * whether a parent CR has been provisioned before its children arrive).
292908
+ */
292909
+ async function getItemByItemPathOrNull(itemPath, apiGroup = catalog_common/* default.types.controller.FirestartrApiGroup */.Z.types.controller.FirestartrApiGroup, apiVersion = 'v1') {
292910
+ try {
292911
+ operator_src_logger.debug(`The ctl is getting the item at '${itemPath}'.`);
292912
+ const { kc, opts } = await ctl_getConnection();
292913
+ opts.headers['Content-Type'] = 'application/json';
292914
+ opts.headers['Accept'] = 'application/json';
292915
+ const url = apiGroup === catalog_common/* default.types.controller.KubernetesApiGroup */.Z.types.controller.KubernetesApiGroup
292916
+ ? `${kc.getCurrentCluster().server}/api/v1/namespaces/${itemPath}`
292917
+ : `${kc.getCurrentCluster().server}/apis/${apiGroup}/${apiVersion}/namespaces/${itemPath}`;
292918
+ operator_src_logger.silly(`Sending request ${url}`);
292919
+ const r = await fetch(url, { method: 'get', headers: opts.headers });
292920
+ if (r.status === 404 || r.status === 409) {
292921
+ operator_src_logger.debug(`Item at '${itemPath}' returned ${r.status} (expected), returning null.`);
292922
+ return null;
292923
+ }
292924
+ if (!r.ok) {
292925
+ const err = new Error(`Error on getItemByItemPath: ${itemPath}: ${r.statusText}`);
292926
+ operator_src_logger.error(`Error on getItemByItemPath: ${itemPath}: ${r.statusText}`);
292927
+ throw err;
292928
+ }
292929
+ return await r.json();
292930
+ }
292931
+ catch (e) {
292932
+ operator_src_logger.error(`Error on getItemByItemPath: ${e}`);
292933
+ throw e;
292934
+ }
292935
+ }
292422
292936
  async function writeManifest(kind, namespace, item, apiSlug) {
292423
292937
  const { kc, opts } = await ctl_getConnection();
292424
292938
  opts.headers['Content-Type'] = 'application/json';
@@ -292704,40 +293218,52 @@ async function checkIfRenamed(namespace, item) {
292704
293218
  }
292705
293219
  }
292706
293220
  async function upsertFinalizer(kind, namespace, item, finalizer) {
292707
- if ('finalizers' in item.metadata &&
292708
- item.metadata.finalizers.includes(finalizer)) {
292709
- operator_src_logger.debug(`The ctl tried to upsert the finalizer '${finalizer}' for '${kind}/${item.metadata.name}' in namespace '${namespace}', but it was already set.`);
292710
- return;
292711
- }
292712
- operator_src_logger.debug(`The ctl is setting the finalizer '${finalizer}' for '${kind}/${item.metadata.name}' in namespace '${namespace}'.`);
292713
293221
  const { kc, opts } = await ctl_getConnection();
292714
293222
  const url = `${kc.getCurrentCluster().server}/apis/firestartr.dev/v1/namespaces/${namespace}/${kind}/${item.metadata.name}`;
292715
- opts.headers['Content-Type'] = 'application/json-patch+json';
292716
- opts.headers['Accept'] = '*';
292717
- let patch;
292718
- if (!item['metadata']['finalizers']) {
292719
- patch = {
292720
- op: 'add',
292721
- path: '/metadata/finalizers',
292722
- value: [finalizer],
292723
- };
292724
- }
292725
- else {
292726
- patch = {
292727
- op: 'add',
292728
- path: '/metadata/finalizers/-',
292729
- value: finalizer,
292730
- };
292731
- }
292732
- const r = await fetch(url, {
292733
- method: 'PATCH',
292734
- headers: opts.headers,
292735
- body: JSON.stringify([patch]),
292736
- });
292737
- if (!r.ok) {
292738
- throw `Error on setFinalizer: ${namespace}/${kind}/${item['metadata']['name']}: ${r.statusText}`;
293223
+ for (let attempt = 0; attempt < 5; attempt++) {
293224
+ // Fresh GET to get current finalizers and resourceVersion
293225
+ const getResp = await fetch(url, {
293226
+ method: 'GET',
293227
+ headers: { ...opts.headers, Accept: 'application/json' },
293228
+ });
293229
+ if (!getResp.ok) {
293230
+ throw `Error fetching item for finalizer upsert: ${namespace}/${kind}/${item.metadata.name}: ${getResp.statusText}`;
293231
+ }
293232
+ const currentItem = await getResp.json();
293233
+ const currentFinalizers = currentItem.metadata.finalizers || [];
293234
+ if (currentFinalizers.includes(finalizer)) {
293235
+ operator_src_logger.debug(`The ctl tried to upsert the finalizer '${finalizer}' for '${kind}/${item.metadata.name}' in namespace '${namespace}', but it was already set.`);
293236
+ return;
293237
+ }
293238
+ operator_src_logger.debug(`The ctl is setting the finalizer '${finalizer}' for '${kind}/${item.metadata.name}' in namespace '${namespace}' (attempt ${attempt + 1}).`);
293239
+ const newFinalizers = [...currentFinalizers, finalizer];
293240
+ const body = JSON.stringify([
293241
+ {
293242
+ op: 'add',
293243
+ path: '/metadata/finalizers',
293244
+ value: newFinalizers,
293245
+ },
293246
+ ]);
293247
+ const patchResp = await fetch(url, {
293248
+ method: 'PATCH',
293249
+ headers: {
293250
+ ...opts.headers,
293251
+ 'Content-Type': 'application/json-patch+json',
293252
+ Accept: '*',
293253
+ 'If-Match': currentItem.metadata.resourceVersion,
293254
+ },
293255
+ body,
293256
+ });
293257
+ if (patchResp.ok) {
293258
+ return patchResp.json();
293259
+ }
293260
+ if (patchResp.status === 409) {
293261
+ operator_src_logger.debug(`Conflict upserting finalizer '${finalizer}' for '${kind}/${item.metadata.name}' (attempt ${attempt + 1}), retrying.`);
293262
+ continue;
293263
+ }
293264
+ throw `Error on upsertFinalizer: ${namespace}/${kind}/${item.metadata.name}: ${patchResp.statusText}`;
292739
293265
  }
292740
- return r.json();
293266
+ throw `Failed to upsert finalizer '${finalizer}' for '${namespace}/${kind}/${item.metadata.name}' after 5 attempts.`;
292741
293267
  }
292742
293268
  /**
292743
293269
  * Remove the given finalizer
@@ -292751,30 +293277,57 @@ async function unsetFinalizer(kind, namespace, item, finalizer) {
292751
293277
  const { kc, opts } = await ctl_getConnection();
292752
293278
  let itemObj;
292753
293279
  if (typeof item === 'string') {
292754
- itemObj = await getItemByItemPath([namespace, kind, item].join('/'));
293280
+ itemObj = await ctl_getItemByItemPath([namespace, kind, item].join('/'));
292755
293281
  }
292756
293282
  else {
292757
293283
  itemObj = item;
292758
293284
  }
292759
293285
  const name = itemObj.metadata.name;
292760
- operator_src_logger.debug(`The ctl is removing the finalizer '${finalizer}' from '${kind}/${name}' in namespace '${namespace}'.`);
292761
293286
  const url = `${kc.getCurrentCluster().server}/apis/firestartr.dev/v1/namespaces/${namespace}/${kind}/${name}`;
292762
- opts.headers['Content-Type'] = 'application/json-patch+json';
292763
- opts.headers['Accept'] = '*';
292764
- const patch = {
292765
- op: 'replace',
292766
- path: '/metadata/finalizers',
292767
- value: itemObj.metadata.finalizers.filter((f) => f !== finalizer),
292768
- };
292769
- const r = await fetch(url, {
292770
- method: 'PATCH',
292771
- headers: opts.headers,
292772
- body: JSON.stringify([patch]),
292773
- });
292774
- if (!r.ok) {
292775
- throw `Error on unsetFinalizer: ${namespace}/${kind}/${name}: ${r.statusText}`;
293287
+ for (let attempt = 0; attempt < 5; attempt++) {
293288
+ // Fresh GET to get current finalizers and resourceVersion
293289
+ const getResp = await fetch(url, {
293290
+ method: 'GET',
293291
+ headers: { ...opts.headers, Accept: 'application/json' },
293292
+ });
293293
+ if (!getResp.ok) {
293294
+ throw `Error fetching item for finalizer unset: ${namespace}/${kind}/${name}: ${getResp.statusText}`;
293295
+ }
293296
+ const currentItem = await getResp.json();
293297
+ const currentFinalizers = currentItem.metadata.finalizers || [];
293298
+ if (!currentFinalizers.includes(finalizer)) {
293299
+ operator_src_logger.debug(`The ctl tried to unset the finalizer '${finalizer}' for '${kind}/${name}' in namespace '${namespace}', but it was not present.`);
293300
+ return;
293301
+ }
293302
+ operator_src_logger.debug(`The ctl is removing the finalizer '${finalizer}' from '${kind}/${name}' in namespace '${namespace}' (attempt ${attempt + 1}).`);
293303
+ const newFinalizers = currentFinalizers.filter((f) => f !== finalizer);
293304
+ const body = JSON.stringify([
293305
+ {
293306
+ op: 'replace',
293307
+ path: '/metadata/finalizers',
293308
+ value: newFinalizers,
293309
+ },
293310
+ ]);
293311
+ const patchResp = await fetch(url, {
293312
+ method: 'PATCH',
293313
+ headers: {
293314
+ ...opts.headers,
293315
+ 'Content-Type': 'application/json-patch+json',
293316
+ Accept: '*',
293317
+ 'If-Match': currentItem.metadata.resourceVersion,
293318
+ },
293319
+ body,
293320
+ });
293321
+ if (patchResp.ok) {
293322
+ return patchResp.json();
293323
+ }
293324
+ if (patchResp.status === 409) {
293325
+ operator_src_logger.debug(`Conflict unsetting finalizer '${finalizer}' for '${kind}/${name}' (attempt ${attempt + 1}), retrying.`);
293326
+ continue;
293327
+ }
293328
+ throw `Error on unsetFinalizer: ${namespace}/${kind}/${name}: ${patchResp.statusText}`;
292776
293329
  }
292777
- return r.json();
293330
+ throw `Failed to unset finalizer '${finalizer}' for '${namespace}/${kind}/${name}' after 5 attempts.`;
292778
293331
  }
292779
293332
  /**
292780
293333
  * @deprecated Misspelled export kept for backward compatibility.
@@ -293041,7 +293594,7 @@ function conditionsSorter(conditions) {
293041
293594
 
293042
293595
 
293043
293596
  async function upsertInitialStatus(pluralKind, namespace, item) {
293044
- item = await getItemByItemPath(`${namespace}/${pluralKind}/${item.metadata.name}`);
293597
+ item = await ctl_getItemByItemPath(`${namespace}/${pluralKind}/${item.metadata.name}`);
293045
293598
  if (!('status' in item))
293046
293599
  item.status = {};
293047
293600
  if (!('conditions' in item.status))
@@ -293127,7 +293680,7 @@ function shouldForceReconcileByAnnotation(cr) {
293127
293680
  }
293128
293681
  async function updateSyncTransition(itemPath, reason, lastSyncTime, nextSyncTime, message, status) {
293129
293682
  operator_src_logger.info(`The item at '${itemPath}' transitioned to a new SYNCHRONIZED condition of '${status}'. The reason for the change is '${reason}' with the message: '${message}'.`);
293130
- const k8sItem = await getItemByItemPath(itemPath);
293683
+ const k8sItem = await ctl_getItemByItemPath(itemPath);
293131
293684
  if (!('status' in k8sItem))
293132
293685
  k8sItem.status = {};
293133
293686
  if (!('conditions' in k8sItem.status))
@@ -293150,7 +293703,7 @@ async function updateSyncTransition(itemPath, reason, lastSyncTime, nextSyncTime
293150
293703
  async function updateRetryStatusInCR(pluralKind, namespace, name, retryCount, nextRetryTime) {
293151
293704
  const itemPath = `${namespace}/${pluralKind}/${name}`;
293152
293705
  try {
293153
- const item = await getItemByItemPath(itemPath);
293706
+ const item = await ctl_getItemByItemPath(itemPath);
293154
293707
  if (!('status' in item) || item.status === null)
293155
293708
  item.status = {};
293156
293709
  item.status.retryCount = retryCount;
@@ -293196,7 +293749,7 @@ async function writePrioritizedStatus(kind, namespace, item) {
293196
293749
  }
293197
293750
  async function updateTransition(itemPath, reason, type, statusValue, message = '', updateStatusOnly = false) {
293198
293751
  operator_src_logger.info(`The item at '${itemPath}' transitioned to a new status of '${statusValue}' (type: '${type}'). The reason for the change is '${reason}' with the message: '${message}'. This was a status-only update: '${updateStatusOnly}'.`);
293199
- const k8sItem = await getItemByItemPath(itemPath);
293752
+ const k8sItem = await ctl_getItemByItemPath(itemPath);
293200
293753
  if (!('status' in k8sItem))
293201
293754
  k8sItem.status = {};
293202
293755
  if (!('conditions' in k8sItem.status))
@@ -293269,7 +293822,7 @@ const SYNC_DEFAULT_ERROR_MESSAGE = 'An error occurred while executing the Sync o
293269
293822
 
293270
293823
  const DEFAULT_REVISION_TIME = '1m';
293271
293824
  async function createWatcherForItem(itemPath, itemCR) {
293272
- const item = itemCR ?? (await getItemByItemPath(itemPath));
293825
+ const item = itemCR ?? (await ctl_getItemByItemPath(itemPath));
293273
293826
  const syncStatus = await getSyncStatus(itemPath, item);
293274
293827
  let nextTimeoutInMS = syncStatus.nextTimeoutInMS;
293275
293828
  // we have lapsed last interval
@@ -293301,7 +293854,7 @@ async function destroyWatcherForItem(watcher) {
293301
293854
  operator_src_logger.debug(`Disabled SyncWatcher for ${watcher.itemPath}`);
293302
293855
  }
293303
293856
  async function getSyncSpecs(itemPath, itemCR) {
293304
- const item = itemCR ?? (await getItemByItemPath(itemPath));
293857
+ const item = itemCR ?? (await ctl_getItemByItemPath(itemPath));
293305
293858
  return {
293306
293859
  item,
293307
293860
  syncable: helperIsSyncable(item),
@@ -293313,7 +293866,7 @@ async function getSyncSpecs(itemPath, itemCR) {
293313
293866
  };
293314
293867
  }
293315
293868
  async function getSyncStatus(itemPath, itemCR) {
293316
- const item = itemCR ?? (await getItemByItemPath(itemPath));
293869
+ const item = itemCR ?? (await ctl_getItemByItemPath(itemPath));
293317
293870
  const syncCondition = getConditionByType(item.status?.conditions ?? [], 'SYNCHRONIZED');
293318
293871
  // no sync condition present
293319
293872
  if (!syncCondition) {
@@ -293345,7 +293898,7 @@ async function getSyncStatus(itemPath, itemCR) {
293345
293898
  }
293346
293899
  }
293347
293900
  async function setSyncStatus(itemPath, reason, status, message) {
293348
- const item = await getItemByItemPath(itemPath);
293901
+ const item = await ctl_getItemByItemPath(itemPath);
293349
293902
  const machinery = assessSyncCalculationMachinery(item);
293350
293903
  const syncStatus = await machinery(item, reason, status, message);
293351
293904
  syncStatus.itemPath = itemPath;
@@ -293595,7 +294148,7 @@ async function loopKeeper(api) {
293595
294148
  }
293596
294149
  }
293597
294150
  async function getItemIfNeededSync(watcher) {
293598
- const item = await getItemByItemPath(watcher.itemPath);
294151
+ const item = await ctl_getItemByItemPath(watcher.itemPath);
293599
294152
  const isProvisioning = item.status?.conditions?.find((condition) => condition.type === 'PROVISIONING' && condition.status === 'True');
293600
294153
  if (isProvisioning)
293601
294154
  return null;
@@ -293685,7 +294238,7 @@ async function retry_loop(enqueueIfNeeded) {
293685
294238
  }
293686
294239
  async function getItemIfNeededRetry(watcher) {
293687
294240
  try {
293688
- const item = await getItemByItemPath(watcher.itemPath);
294241
+ const item = await ctl_getItemByItemPath(watcher.itemPath);
293689
294242
  const isProvisioning = item.status?.conditions?.find((condition) => condition.type === 'PROVISIONING' && condition.status === 'True');
293690
294243
  if (isProvisioning)
293691
294244
  return null;
@@ -293869,6 +294422,7 @@ const kindsWithFinalizer = [
293869
294422
  'FirestartrGithubRepository',
293870
294423
  'FirestartrGithubRepositoryFeature',
293871
294424
  'FirestartrGithubOrgWebhook',
294425
+ 'FirestartrGithubOrganizationSettings',
293872
294426
  'FirestartrGithubRepositorySecretsSection',
293873
294427
  ];
293874
294428
  const kindsWithDependants = [
@@ -293973,7 +294527,7 @@ async function handleUnsetFinalizer(pluralKind, namespace, item) {
293973
294527
  */
293974
294528
  function enqueue(pluralKind, workItem, queue, compute, syncCtl, retryCtl) {
293975
294529
  workItem.getItem = () => {
293976
- return getItemByItemPath(informer_itemPath(pluralKind, workItem.item));
294530
+ return ctl_getItemByItemPath(informer_itemPath(pluralKind, workItem.item));
293977
294531
  };
293978
294532
  workItem.isDeadLetter = false;
293979
294533
  workItem.handler = {
@@ -293992,7 +294546,7 @@ function enqueue(pluralKind, workItem, queue, compute, syncCtl, retryCtl) {
293992
294546
  return result;
293993
294547
  },
293994
294548
  writeConnectionSecret: writeConnectionSecret,
293995
- resolveReferences: () => resolve(workItem.item, getItemByItemPath, getSecret),
294549
+ resolveReferences: () => resolve(workItem.item, ctl_getItemByItemPath, getSecret),
293996
294550
  resolveOwnOutputs: () => {
293997
294551
  return resolveSecretRef(workItem.item.metadata.namespace, workItem.item, getSecret);
293998
294552
  },
@@ -294063,7 +294617,7 @@ function enqueue(pluralKind, workItem, queue, compute, syncCtl, retryCtl) {
294063
294617
  if (needsUpdateSyncConditions) {
294064
294618
  if (operation === OperationType.SYNC) {
294065
294619
  // Fetch the CR once and reuse for both hasSyncFailed check and ERROR guard
294066
- const currentItem = await getItemByItemPath(workItem.handler.itemPath());
294620
+ const currentItem = await ctl_getItemByItemPath(workItem.handler.itemPath());
294067
294621
  const syncStatus = await getSyncStatus(workItem.handler.itemPath(), currentItem);
294068
294622
  if (syncStatus.hasSyncFailed) {
294069
294623
  return;
@@ -294312,64 +294866,40 @@ function dummy_fWait(ms) {
294312
294866
  });
294313
294867
  }
294314
294868
 
294315
- ;// CONCATENATED MODULE: ../operator/src/ownership.ts
294869
+ ;// CONCATENATED MODULE: ../operator/src/ctl_collections.ts
294316
294870
 
294317
294871
 
294318
294872
 
294319
- async function getOwnerReferences(item) {
294320
- return item.metadata?.ownerReferences || [];
294321
- }
294322
- async function ownership_setOwnerReference(itemPath, namespace, ownerKind, ownerName, blockOwnerDeletion = true) {
294323
- let item = null;
294873
+ // generator function to traverse elements
294874
+ // it is async and iterable
294875
+ async function* traverseCRCollection(pluralKind, namespace, options = {}, apiGroup = 'firestartr.dev', apiVersion = 'v1') {
294876
+ const { limit = 300 } = options; // between 250-300
294324
294877
  try {
294325
- // we need to search for the owner's uuid
294326
- const owner = await getItemByItemPath(`${namespace}/${ownerKind}/${ownerName}`);
294327
- const ownerReference = {
294328
- apiVersion: owner.apiVersion,
294329
- kind: owner.kind,
294330
- name: ownerName,
294331
- controller: true,
294332
- blockOwnerDeletion,
294333
- uid: owner.metadata.uid,
294334
- };
294335
- // we get the item (to prevent race conditions)
294336
- item = await getItemByItemPath(itemPath);
294337
- const ownerReferences = item.metadata.ownerReferences ?? [];
294338
- const existingRefIndex = ownerReferences.findIndex((ref) => ref.uid === ownerReference.uid);
294339
- if (existingRefIndex === -1) {
294340
- // Reference does not exist, add it
294341
- ownerReferences.push(ownerReference);
294342
- }
294343
- else {
294344
- ownerReferences[existingRefIndex] = ownerReference;
294345
- }
294346
- await writeOwnerReferences(definitions_getPluralFromKind(item.kind), item.metadata.namespace, item, ownerReferences);
294878
+ let continueToken = undefined;
294879
+ const { kc, opts } = await ctl_getConnection();
294880
+ const k8sApi = kc.makeApiClient(client_node_dist.CustomObjectsApi);
294881
+ const apiGroup = 'firestartr.dev';
294882
+ const apiVersion = 'v1';
294883
+ const apiPaths = `/apis/${apiGroup}/${apiVersion}/namespaces/${namespace}/${pluralKind}`;
294884
+ do {
294885
+ const res = await k8sApi.listNamespacedCustomObject(apiGroup, apiVersion, namespace, pluralKind, undefined, // pretty
294886
+ undefined, // allowWatchBookmarks
294887
+ continueToken, // _continue
294888
+ undefined, // fieldSelector
294889
+ undefined, // labelSelector
294890
+ limit);
294891
+ const body = res.body;
294892
+ const items = body.items || [];
294893
+ for (const item of items) {
294894
+ yield item;
294895
+ }
294896
+ continueToken = body.metadata?.continue;
294897
+ } while (continueToken);
294347
294898
  }
294348
294899
  catch (err) {
294349
- operator_src_logger.error(err);
294350
- throw `Setting OwnerReferences to ${item.kind}/${item.metadata.name}: ${err}`;
294351
- }
294352
- }
294353
- async function writeOwnerReferences(kind, namespace, item, ownerReferences) {
294354
- operator_src_logger.debug(`The ctl is setting the ownerReferences for '${kind}/${item.metadata.name}' in namespace '${namespace}'.`);
294355
- const { kc, opts } = await ctl_getConnection();
294356
- const url = `${kc.getCurrentCluster().server}/apis/firestartr.dev/v1/namespaces/${namespace}/${kind}/${item.metadata.name}`;
294357
- opts.headers['Content-Type'] = 'application/json-patch+json';
294358
- opts.headers['Accept'] = '*';
294359
- const patch = {
294360
- op: 'replace',
294361
- path: '/metadata/ownerReferences',
294362
- value: ownerReferences,
294363
- };
294364
- const r = await fetch(url, {
294365
- method: 'PATCH',
294366
- headers: opts.headers,
294367
- body: JSON.stringify([patch]),
294368
- });
294369
- if (!r.ok) {
294370
- throw `Error on setOwnerReferences: ${namespace}/${kind}/${item['metadata']['name']}: ${r.statusText}`;
294900
+ operator_src_logger.error(`Error traversing ${namespace}/${pluralKind}: ${err}`);
294901
+ throw new Error(`Error traversing ${namespace}/${pluralKind}: ${err}`);
294371
294902
  }
294372
- return r.json();
294373
294903
  }
294374
294904
 
294375
294905
  ;// CONCATENATED MODULE: ../operator/fdummies/index.ts
@@ -294378,6 +294908,11 @@ async function writeOwnerReferences(kind, namespace, item, ownerReferences) {
294378
294908
 
294379
294909
 
294380
294910
 
294911
+
294912
+ const dummyChildrenMap = {
294913
+ FirestartrDummyA: ['FirestartrDummyB'],
294914
+ FirestartrDummyB: ['FirestartrDummyC'],
294915
+ };
294381
294916
  function processFirestartrDummies(item, op, handler) {
294382
294917
  operator_src_logger.info(`FirestartrDummies Processor: ${op}`);
294383
294918
  try {
@@ -294408,20 +294943,93 @@ async function* updated(item, op, handler) {
294408
294943
  for await (const transition of doRun(item, op, handler)) {
294409
294944
  yield transition;
294410
294945
  }
294411
- await handleOwnerReferences(item, handler);
294946
+ await manageDummyOwnershipReferences(item, handler);
294412
294947
  }
294413
294948
  async function* created(item, op, handler) {
294414
294949
  for await (const transition of doRun(item, op, handler)) {
294415
294950
  yield transition;
294416
294951
  }
294417
- await handleOwnerReferences(item, handler);
294952
+ await manageDummyOwnershipReferences(item, handler);
294418
294953
  }
294419
- async function handleOwnerReferences(item, handler) {
294954
+ async function manageDummyOwnershipReferences(item, _handler) {
294955
+ /*******************************************************************************
294956
+ // suspended due to https://github.com/prefapp/gitops-k8s/issues/1767
294957
+ if ('needs' in item.spec) {
294958
+ const needs = item.spec.needs;
294959
+ await setOwnerReference(
294960
+ handler.itemPath(),
294961
+ item.metadata.namespace,
294962
+ getPluralFromKind(needs.kind),
294963
+ needs.name,
294964
+ );
294965
+ }
294966
+ ********************************************************************************/
294420
294967
  if ('needs' in item.spec) {
294421
- const needs = item.spec.needs;
294422
- await ownership_setOwnerReference(handler.itemPath(), item.metadata.namespace, definitions_getPluralFromKind(needs.kind), needs.name);
294968
+ await installParentFinalizer(item);
294423
294969
  }
294424
294970
  }
294971
+ async function manageDummyOwnershipPostDeletion(item, _handler) {
294972
+ if ('needs' in item.spec) {
294973
+ await manageChildrenReferences(item);
294974
+ }
294975
+ if (Object.prototype.hasOwnProperty.call(dummyChildrenMap, item.kind)) {
294976
+ await removeFinalizerIfNoMoreChildren(item);
294977
+ }
294978
+ }
294979
+ async function installParentFinalizer(item) {
294980
+ const needs = item.spec.needs;
294981
+ const parentItem = await ctl_getItemByItemPath([item.metadata.namespace, definitions_getPluralFromKind(needs.kind), needs.name].join('/'));
294982
+ await upsertFinalizer(definitions_getPluralFromKind(parentItem.kind), parentItem.metadata.namespace, parentItem, 'firestartr.dev/foreground-deletion');
294983
+ }
294984
+ async function manageChildrenReferences(item) {
294985
+ const parentItem = await ctl_getItemByItemPath([
294986
+ item.metadata.namespace,
294987
+ definitions_getPluralFromKind(item.spec.needs.kind),
294988
+ item.spec.needs.name,
294989
+ ].join('/'));
294990
+ await removeFinalizerIfNoMoreChildren(parentItem);
294991
+ }
294992
+ async function removeFinalizerIfNoMoreChildren(parentItem) {
294993
+ try {
294994
+ let numberOfChildren = 0;
294995
+ const childKinds = dummyChildrenMap[parentItem.kind];
294996
+ if (!childKinds)
294997
+ return;
294998
+ for (const childKind of childKinds) {
294999
+ const children = await findDummiesWithNeeds(childKind, parentItem);
295000
+ numberOfChildren += children.length;
295001
+ }
295002
+ if (numberOfChildren === 0) {
295003
+ try {
295004
+ await unsetFinalizer(definitions_getPluralFromKind(parentItem.kind), parentItem.metadata.namespace, parentItem, 'firestartr.dev/foreground-deletion');
295005
+ }
295006
+ catch (unsetErr) {
295007
+ if (typeof unsetErr === 'string' && unsetErr.includes('Not Found')) {
295008
+ operator_src_logger.info(`${parentItem.kind}/${parentItem.metadata.name} was already deleted; skipping finalizer removal`);
295009
+ }
295010
+ else {
295011
+ throw unsetErr;
295012
+ }
295013
+ }
295014
+ }
295015
+ }
295016
+ catch (err) {
295017
+ operator_src_logger.error(`Error managing children references in item: ${parentItem.kind}/${parentItem.metadata.name}: ${err}`);
295018
+ throw new Error(`Error managing children references in item: ${parentItem.kind}/${parentItem.metadata.name}: ${err}`);
295019
+ }
295020
+ }
295021
+ async function findDummiesWithNeeds(kind, parentItem) {
295022
+ const children = [];
295023
+ const pluralKind = definitions_getPluralFromKind(kind);
295024
+ for await (const crItem of traverseCRCollection(pluralKind, parentItem.metadata.namespace)) {
295025
+ if ('needs' in crItem.spec &&
295026
+ crItem.spec.needs.name === parentItem.metadata.name &&
295027
+ crItem.spec.needs.kind === parentItem.kind) {
295028
+ children.push(crItem);
295029
+ }
295030
+ }
295031
+ return children;
295032
+ }
294425
295033
  async function renamed() {
294426
295034
  throw new Error('Renamed operation not prepared');
294427
295035
  }
@@ -294507,6 +295115,7 @@ async function* markedToDeletion(item, op, handler) {
294507
295115
  message: 'destroyed',
294508
295116
  };
294509
295117
  await handler.finalize(handler.pluralKind, item.metadata.namespace, item, 'firestartr.dev/finalizer');
295118
+ await manageDummyOwnershipPostDeletion(item, handler);
294510
295119
  void handler.success();
294511
295120
  }
294512
295121
  catch (e) {
@@ -295203,12 +295812,20 @@ async function startQueueMetrics(meter, attributes) {
295203
295812
  const nWorkItemsInDeadLetterHandling = meter.createObservableGauge('firestartr_workitems_dead_letter_handling_total', {
295204
295813
  description: 'Number of workitems of the queue handled by the Dead Letter Handler',
295205
295814
  });
295815
+ const nWorkItemsBlocked = meter.createObservableGauge('firestartr_workitems_blocked_total', {
295816
+ description: 'Number of workitems currently blocked (children still being deleted, or parent not yet created/provisioned)',
295817
+ });
295818
+ const nWorkItemsDeferred = meter.createObservableGauge('firestartr_workitems_deferred_total', {
295819
+ description: 'Number of workitems moved to the deferred segment after repeated blocking',
295820
+ });
295206
295821
  const queueMetrics = getQueueMetrics();
295207
295822
  let total = queueMetrics.nItems;
295208
295823
  let pending = queueMetrics.nItemsPending;
295209
295824
  let processing = queueMetrics.nItemsProcessing;
295210
295825
  let finished = queueMetrics.nItemsFinished;
295211
295826
  let inDeadLetterHandling = queueMetrics.nItemsInDeadLetterHandling;
295827
+ let nBlocked = queueMetrics.nItemsBlocked || 0;
295828
+ let nDeferred = queueMetrics.nItemsDeferred || 0;
295212
295829
  nWorkItemsCounter.addCallback((observer) => observer.observe(total, { ...attributes, ...queueMetrics.nItemsTypes }));
295213
295830
  nWorkItemsPendingCounter.addCallback((observer) => observer.observe(pending, { ...attributes, ...queueMetrics.nItemsTypes }));
295214
295831
  nWorkItemsProcessingCounter.addCallback((observer) => observer.observe(processing, {
@@ -295220,6 +295837,8 @@ async function startQueueMetrics(meter, attributes) {
295220
295837
  ...attributes,
295221
295838
  ...queueMetrics.nItemsTypes,
295222
295839
  }));
295840
+ nWorkItemsBlocked.addCallback((observer) => observer.observe(nBlocked, { ...attributes }));
295841
+ nWorkItemsDeferred.addCallback((observer) => observer.observe(nDeferred, { ...attributes }));
295223
295842
  setInterval(() => {
295224
295843
  const queueMetrics = getQueueMetrics();
295225
295844
  total = queueMetrics.nItems;
@@ -295227,6 +295846,8 @@ async function startQueueMetrics(meter, attributes) {
295227
295846
  processing = queueMetrics.nItemsProcessing;
295228
295847
  finished = queueMetrics.nItemsFinished;
295229
295848
  inDeadLetterHandling = queueMetrics.nItemsInDeadLetterHandling;
295849
+ nBlocked = queueMetrics.nItemsBlocked || 0;
295850
+ nDeferred = queueMetrics.nItemsDeferred || 0;
295230
295851
  }, 1000);
295231
295852
  }
295232
295853
  async function startMemoryMetrics(meter, attributes) {
@@ -295401,15 +296022,131 @@ class ProcessItemSlot {
295401
296022
  }
295402
296023
  }
295403
296024
 
295404
- ;// CONCATENATED MODULE: ../operator/src/processItem.ts
295405
-
295406
-
295407
-
295408
-
296025
+ ;// CONCATENATED MODULE: ../operator/src/parentDependency.ts
295409
296026
 
296027
+ const PARENT_KIND_MAP = {
296028
+ FirestartrGithubRepositoryFeature: 'FirestartrGithubRepository',
296029
+ FirestartrGithubRepositorySecretsSection: 'FirestartrGithubRepository',
296030
+ FirestartrDummyB: 'FirestartrDummyA',
296031
+ FirestartrDummyC: 'FirestartrDummyB',
296032
+ };
296033
+ const DEPENDENT_KINDS = new Set(Object.keys(PARENT_KIND_MAP));
296034
+ const RELEVANT_KINDS = new Set();
296035
+ for (const [child, parent] of Object.entries(PARENT_KIND_MAP)) {
296036
+ RELEVANT_KINDS.add(child);
296037
+ RELEVANT_KINDS.add(parent);
296038
+ }
296039
+ function getParentKindForDependent(kind) {
296040
+ return PARENT_KIND_MAP[kind];
296041
+ }
296042
+ function isDependentKind(kind) {
296043
+ return DEPENDENT_KINDS.has(kind);
296044
+ }
296045
+ function isRelevantKind(kind) {
296046
+ return RELEVANT_KINDS.has(kind);
296047
+ }
296048
+ function getParentRef(workItem) {
296049
+ const ref = workItem.item.spec?.repositoryTarget?.ref;
296050
+ if (ref?.kind && ref?.name) {
296051
+ return { kind: ref.kind, name: ref.name };
296052
+ }
296053
+ const needs = workItem.item.spec?.needs;
296054
+ if (needs?.kind && needs?.name) {
296055
+ return { kind: needs.kind, name: needs.name };
296056
+ }
296057
+ return null;
296058
+ }
296059
+ function buildActiveParentKeys(queue) {
296060
+ const keys = new Set();
296061
+ for (const w of queue) {
296062
+ if (w.workStatus === WorkStatus.PENDING || w.isPicked) {
296063
+ keys.add(`${w.item.kind}/${w.item.metadata?.name}`);
296064
+ }
296065
+ }
296066
+ return keys;
296067
+ }
296068
+ /**
296069
+ * Scan the queue for dependent children whose parent is not in the active set
296070
+ * and verify whether each parent exists in the K8s cluster and has been
296071
+ * provisioned. Parents that are absent from the queue and either missing from
296072
+ * the cluster OR not yet provisioned are added to a deferred set, which
296073
+ * `hasActiveParent` uses to block the child from being dispatched.
296074
+ *
296075
+ * A parent CR exists in the cluster immediately after `kubectl apply`, but it
296076
+ * is not usable until the operator has reconciled it and set PROVISIONED=True.
296077
+ * Checking only for cluster existence would let children slip through while
296078
+ * the parent is still being processed. This function also checks the parent's
296079
+ * status conditions so that children are deferred until the parent is fully
296080
+ * provisioned.
296081
+ *
296082
+ * @param getItemByItemPath - function to look up a CR in the K8s cluster by
296083
+ * its item path (namespace/pluralKind/name). Should return null (not throw)
296084
+ * when the resource is absent or not yet available (e.g. 404/409), so that
296085
+ * missing parents are deferred without generating spurious error logs.
296086
+ */
296087
+ async function buildDeferredParentKeys(queue, activeParentKeys, getItemByItemPath) {
296088
+ const deferred = new Set();
296089
+ const checked = new Set();
296090
+ for (const w of queue) {
296091
+ if (w.operation !== OperationType.CREATED)
296092
+ continue;
296093
+ if (!isDependentKind(w.item.kind))
296094
+ continue;
296095
+ const parentRef = getParentRef(w);
296096
+ if (!parentRef)
296097
+ continue;
296098
+ const parentKey = `${parentRef.kind}/${parentRef.name}`;
296099
+ if (checked.has(parentKey))
296100
+ continue;
296101
+ checked.add(parentKey);
296102
+ if (activeParentKeys.has(parentKey))
296103
+ continue;
296104
+ const namespace = w.item.metadata?.namespace || 'default';
296105
+ const pluralKind = definitions_getPluralFromKind(parentRef.kind);
296106
+ if (!pluralKind)
296107
+ continue;
296108
+ try {
296109
+ const parentCr = await getItemByItemPath(`${namespace}/${pluralKind}/${parentRef.name}`);
296110
+ const isProvisioned = parentCr?.status?.conditions?.some((c) => c.type === 'PROVISIONED' && c.status === 'True');
296111
+ if (!isProvisioned) {
296112
+ deferred.add(parentKey);
296113
+ }
296114
+ }
296115
+ catch {
296116
+ deferred.add(parentKey);
296117
+ }
296118
+ }
296119
+ return deferred;
296120
+ }
296121
+ function hasActiveParent(workItem, queueOrKeys, deferredParentKeys) {
296122
+ if (workItem.operation !== OperationType.CREATED)
296123
+ return false;
296124
+ if (!DEPENDENT_KINDS.has(workItem.item.kind))
296125
+ return false;
296126
+ const parentRef = getParentRef(workItem);
296127
+ if (!parentRef)
296128
+ return false;
296129
+ const { kind: parentKind, name: parentName } = parentRef;
296130
+ const parentKey = `${parentKind}/${parentName}`;
296131
+ if (queueOrKeys instanceof Set) {
296132
+ if (queueOrKeys.has(parentKey))
296133
+ return true;
296134
+ if (deferredParentKeys?.has(parentKey))
296135
+ return true;
296136
+ return false;
296137
+ }
296138
+ const parentActive = queueOrKeys.some((w) => w.item.kind === parentKind &&
296139
+ w.item.metadata?.name === parentName &&
296140
+ (w.workStatus === WorkStatus.PENDING || w.isPicked));
296141
+ if (parentActive)
296142
+ return true;
296143
+ if (deferredParentKeys?.has(parentKey))
296144
+ return true;
296145
+ return false;
296146
+ }
295410
296147
 
296148
+ ;// CONCATENATED MODULE: ../operator/src/queueSort.ts
295411
296149
 
295412
- const queue = [];
295413
296150
  const WEIGHTS = {
295414
296151
  RENAMED: 15,
295415
296152
  UPDATED: 10,
@@ -295419,6 +296156,73 @@ const WEIGHTS = {
295419
296156
  SYNC: 1,
295420
296157
  NOTHING: 0,
295421
296158
  };
296159
+ // we need to assign weight to the deletion operation
296160
+ // to avoid blockades
296161
+ // https://github.com/prefapp/gitops-k8s/issues/1864
296162
+ // ghrepo feat | grss -> ghrepo -> ghgroup -> membership
296163
+ const DELETION_WEIGHTS = {
296164
+ // Leaf children first: C before B before A
296165
+ FirestartrDummyC: 6,
296166
+ FirestartrDummyB: 5,
296167
+ FirestartrDummyA: 4,
296168
+ FirestartrGithubRepositoryFeature: 5,
296169
+ FirestartrGithubRepositorySecretsSection: 4,
296170
+ FirestartrGithubRepository: 3,
296171
+ FirestartrGithubGroup: 2,
296172
+ FirestartrGithubMembership: 1,
296173
+ FirestartrTerraformWorkspace: 1,
296174
+ FirestartrGithubOrgWebhook: 1,
296175
+ };
296176
+ const CREATION_WEIGHTS = {
296177
+ // DummyA is root parent; DummyB is both child-of-A and parent-of-C
296178
+ FirestartrDummyA: 2,
296179
+ FirestartrDummyB: 1,
296180
+ FirestartrGithubRepository: 1,
296181
+ };
296182
+ function sortQueue(queue) {
296183
+ const sortedQueue = queue.sort((wa, wb) => {
296184
+ const weightA = WEIGHTS[wa.operation];
296185
+ const weightB = WEIGHTS[wb.operation];
296186
+ if (weightA !== weightB) {
296187
+ return weightB - weightA;
296188
+ }
296189
+ if (wa.operation === 'MARKED_TO_DELETION' &&
296190
+ wb.operation === 'MARKED_TO_DELETION') {
296191
+ const deletionWeightA = DELETION_WEIGHTS[wa.item.kind] || 0;
296192
+ const deletionWeightB = DELETION_WEIGHTS[wb.item.kind] || 0;
296193
+ if (deletionWeightA !== deletionWeightB) {
296194
+ return deletionWeightB - deletionWeightA;
296195
+ }
296196
+ }
296197
+ if (wa.operation === 'CREATED' && wb.operation === 'CREATED') {
296198
+ if (isRelevantKind(wa.item.kind) && isRelevantKind(wb.item.kind)) {
296199
+ const creationWeightA = CREATION_WEIGHTS[wa.item.kind] || 0;
296200
+ const creationWeightB = CREATION_WEIGHTS[wb.item.kind] || 0;
296201
+ if (creationWeightA !== creationWeightB) {
296202
+ return creationWeightB - creationWeightA;
296203
+ }
296204
+ }
296205
+ }
296206
+ return wa.upsertTime - wb.upsertTime;
296207
+ });
296208
+ return sortedQueue;
296209
+ }
296210
+
296211
+ ;// CONCATENATED MODULE: ../operator/src/processItem.ts
296212
+
296213
+
296214
+
296215
+
296216
+
296217
+
296218
+
296219
+
296220
+
296221
+
296222
+ const queue = [];
296223
+ let _deferredBookkeeper = null;
296224
+ let _activeParentKeys = new Set();
296225
+ let _deferredParentKeys = new Set();
295422
296226
  // We get the number of max slots from the environment variable, if it is not set, we default to 1
295423
296227
  function getMaxSlotsFromEnvironment() {
295424
296228
  const rawMaxSlots = catalog_common/* default.environment.getFromEnvironment */.Z.environment.getFromEnvironment(catalog_common/* default.types.envVars.operatorNumberOfMaxSlots */.Z.types.envVars.operatorNumberOfMaxSlots);
@@ -295472,6 +296276,11 @@ function getQueueMetrics() {
295472
296276
  nItemsPending: queue.filter((workItem) => workItem.workStatus === WorkStatus.PENDING).length,
295473
296277
  nItemsProcessing: queue.filter((workItem) => workItem.workStatus === WorkStatus.PROCESSING).length,
295474
296278
  nItemsInDeadLetterHandling: queue.filter((workItem) => workItem.isDeadLetter === true).length,
296279
+ nItemsBlocked: queue.filter((workItem) => workItem.isBlocked === true ||
296280
+ hasActiveParent(workItem, _activeParentKeys, _deferredParentKeys)).length,
296281
+ nItemsDeferred: _deferredBookkeeper
296282
+ ? queue.filter((workItem) => _deferredBookkeeper.isDeferred(workItem)).length
296283
+ : 0,
295475
296284
  nItemsTypes: {
295476
296285
  nothing,
295477
296286
  retry,
@@ -295484,30 +296293,21 @@ function getQueueMetrics() {
295484
296293
  },
295485
296294
  };
295486
296295
  }
295487
- // we need to assign weight to the deletion operation
295488
- // to avoid blockades
295489
- // https://github.com/prefapp/gitops-k8s/issues/1864
295490
- // ghrepo feat | grss -> ghrepo -> ghgroup -> membership
295491
- const DELETION_WEIGHTS = {
295492
- FirestartrGithubRepositoryFeature: 5,
295493
- FirestartrGithubRepositorySecretsSection: 4,
295494
- FirestartrGithubRepository: 3,
295495
- FirestartrGithubGroup: 2,
295496
- FirestartrGithubMembership: 1,
295497
- FirestartrTerraformWorkspace: 1,
295498
- FirestartrGithubOrgWebhook: 1,
295499
- };
295500
- // Do the kinds need different weights for the operations?
295501
- // We need to discuss this with the team in this issue: https://github.com/prefapp/gitops-k8s/issues/524
295502
- // const KIND_WEIGHTS: any = {
295503
- // "FirestartrTerraformWorkspace": 1,
295504
- // "FirestartrGithubGroup": 1,
295505
- // "FirestartrGithubMembership": 1,
295506
- // "FirestartrGithubRepository": 1,
295507
- // "FirestartrGithubRepositoryFeature": 1,
295508
- // "FirestartrTerraformWorkspacePlan": 1,
295509
- // }
295510
296296
  let INIT = false;
296297
+ let podIsTerminating = false;
296298
+ const handleTerminationSignal = (signal) => {
296299
+ podIsTerminating = true;
296300
+ // If there is no processor loop and no queued work, exit immediately so we don't
296301
+ // wait on other event-loop handles (informer watches, keep-alives, etc.).
296302
+ if (!INIT && queue.length === 0) {
296303
+ operator_src_logger.info(`The processor is going to shut down (received ${signal}, no loop started)`);
296304
+ process.exit(0);
296305
+ }
296306
+ };
296307
+ initSignalsHandler(new Map([
296308
+ ['SIGTERM', () => handleTerminationSignal('SIGTERM')],
296309
+ ['SIGINT', () => handleTerminationSignal('SIGINT')],
296310
+ ]));
295511
296311
  /**
295512
296312
  * Pushes a WorkItem to the queue
295513
296313
  * @param {WorkItem} workItem - WorkItem to process
@@ -295528,8 +296328,8 @@ async function processItem(workItem) {
295528
296328
  */
295529
296329
  async function processItem_loop() {
295530
296330
  loopWorkItemDebug(queue);
295531
- let podIsTerminating = false;
295532
296331
  const deferredBookkeeper = new DeferredSchedulingBookkeeper();
296332
+ _deferredBookkeeper = deferredBookkeeper;
295533
296333
  const processItemSlotsManager = initProcessItemsSlots(MAX_SLOTS, true, (w) => deferredBookkeeper.incrementBlockedAttempt(w));
295534
296334
  if (process.env.GARBAGE_QUEUE_COLLECTOR) {
295535
296335
  void workItemGarbageCollector(queue, deferredBookkeeper);
@@ -295559,6 +296359,21 @@ async function processItem_loop() {
295559
296359
  process.exit(0);
295560
296360
  break;
295561
296361
  }
296362
+ // Compute sort/partition + parent-key sets once per scheduling round so
296363
+ // that buildDeferredParentKeys (which hits the API server) and the
296364
+ // sort/partition are not repeated for every idle slot in the same iteration.
296365
+ const sorted = sortQueue(queue);
296366
+ const { nonDeferred, deferred } = deferredBookkeeper.partitionQueueByDeferred(sorted);
296367
+ const activeParentKeys = buildActiveParentKeys(queue);
296368
+ const deferredParentKeys = await buildDeferredParentKeys(queue, activeParentKeys, getItemByItemPathOrNull);
296369
+ _activeParentKeys = activeParentKeys;
296370
+ _deferredParentKeys = deferredParentKeys;
296371
+ const pickEligible = (arr) => arr
296372
+ .filter((w) => !w.isBlocked &&
296373
+ !w.isPicked &&
296374
+ !processItemSlotsManager.isWorkItemBlocked(w) &&
296375
+ !hasActiveParent(w, activeParentKeys, deferredParentKeys))
296376
+ .find((w) => w.workStatus === WorkStatus.PENDING);
295562
296377
  // every time an idle slot is available, we check if there is a work item to process and if there is, we process it
295563
296378
  // if there are more idle slots than work items, the next iterations of the loop will just do nothing
295564
296379
  // until there are new work items to process
@@ -295566,7 +296381,7 @@ async function processItem_loop() {
295566
296381
  if (podIsTerminating) {
295567
296382
  break;
295568
296383
  }
295569
- const w = nextWorkItem();
296384
+ const w = pickEligible(nonDeferred) || pickEligible(deferred);
295570
296385
  if (w) {
295571
296386
  // synchronously mark the work item as picked
295572
296387
  w.isPicked = true;
@@ -295578,41 +296393,10 @@ async function processItem_loop() {
295578
296393
  void idleSlot.runWorkItem(w);
295579
296394
  }
295580
296395
  }
295581
- await wait();
296396
+ await wait(podIsTerminating ? 200 : 2000);
295582
296397
  }
295583
296398
  }
295584
- /**
295585
- * Sorts the queue based on the operation type
295586
- * @param {WorkItem[]} queue - store of WorkItems
295587
- * @returns {WorkItem[]} - sorted queue
295588
- */
295589
- function sortQueue(queue) {
295590
- const sortedQueue = queue.sort((wa, wb) => {
295591
- // --- PRIMARY SORT: By Weight (Descending) ---
295592
- const weightA = WEIGHTS[wa.operation];
295593
- const weightB = WEIGHTS[wb.operation];
295594
- // Check if weights are different
295595
- if (weightA !== weightB) {
295596
- // Sort in descending order (higher weight first)
295597
- // If weightA is larger, return -1 (a comes before b)
295598
- return weightB - weightA;
295599
- }
295600
- // in case of deletions we need to
295601
- // establish a secondary sort by kind
295602
- if (wa.operation === 'MARKED_TO_DELETION' &&
295603
- wb.operation === 'MARKED_TO_DELETION') {
295604
- const deletionWeightA = DELETION_WEIGHTS[wa.item.kind] || 0;
295605
- const deletionWeightB = DELETION_WEIGHTS[wb.item.kind] || 0;
295606
- if (deletionWeightA !== deletionWeightB) {
295607
- return deletionWeightB - deletionWeightA;
295608
- }
295609
- }
295610
- // --- 3rd SORT: By upsertTime (Ascending) ---
295611
- // If weights are equal, sort by the oldest upsertTime (ascending)
295612
- return wa.upsertTime - wb.upsertTime;
295613
- });
295614
- return sortedQueue;
295615
- }
296399
+
295616
296400
  /**
295617
296401
  * Wait for a given time
295618
296402
  * @param t Time to wait in milliseconds
@@ -297943,11 +298727,9 @@ function tf_checkrun_operatorProfile() {
297943
298727
  async function TFCheckRun(cmd, item) {
297944
298728
  try {
297945
298729
  const prInfo = extractPrInfo(item);
297946
- const kind = item.kind;
297947
298730
  const checkRun = await tf_checkrun_operatorProfile().feedback.createCheckRun(prInfo.org, prInfo.repo, helperCreateCheckRunName(cmd, item), {
297948
298731
  pullNumber: Number(prInfo.prNumber),
297949
- includeCheckRunComment: true,
297950
- checkRunComment: `The ${kind} is being processed (cmd=${cmd}). Details: `,
298732
+ // check-run comments removed: redundant with native checks widget (#1985)
297951
298733
  });
297952
298734
  checkRun.mdOptionsDetails({
297953
298735
  quotes: 'terraform',
@@ -299680,7 +300462,7 @@ async function ctx_buildContext(claim, namespace, command) {
299680
300462
  cr['metadata']['namespace'] = namespace;
299681
300463
  operator_src_logger.debug(`The Terraform workspace has finished rendering the custom resource '${cr.kind}/${cr.metadata.name}' in namespace '${cr.metadata.namespace}'.`);
299682
300464
  // Finally, we resolve the deps in the rendered CR
299683
- deps = await resolve(cr, getItemByItemPath, getSecret, namespace);
300465
+ deps = await resolve(cr, ctl_getItemByItemPath, getSecret, namespace);
299684
300466
  operator_src_logger.debug(`The Terraform workspace has finished resolving all dependencies for claim '${claim.name}'.`);
299685
300467
  };
299686
300468
  compute['dryRunExec'] = async () => {
@@ -299846,7 +300628,7 @@ const MODULES = {
299846
300628
  FirestartrGithubRepository: {
299847
300629
  module: 'git::https://github.com/prefapp/tfm.git//modules/github-repo',
299848
300630
  // github-repo-v0.7.0
299849
- ref: '6bdbcd9b813837bec9d1c576952bd88744508883',
300631
+ ref: 'd919ffbff4349c453f75a3b7246b8306a45b12e3',
299850
300632
  },
299851
300633
  FirestartrGithubRepositoryFeature: {
299852
300634
  module: 'git::https://github.com/prefapp/tfm.git//modules/github-files-set',
@@ -299863,6 +300645,11 @@ const MODULES = {
299863
300645
  // github-org-webhook-v0.2.0
299864
300646
  ref: '12d72ba15780647b2f9c2905938913344bfeaa4d',
299865
300647
  },
300648
+ FirestartrGithubOrganizationSettings: {
300649
+ module: 'git::https://github.com/prefapp/tfm.git//modules/github-org-settings',
300650
+ // feat/org-settings-module at 2026-06-16
300651
+ ref: '0e3f3f897ffff35a52285d0c681c0d81026d6d8a',
300652
+ },
299866
300653
  };
299867
300654
  function getFirestartrDefaultTFM(kind) {
299868
300655
  if (kind in MODULES) {
@@ -301393,6 +302180,72 @@ class EntityGHMembership extends base_Entity {
301393
302180
  }
301394
302181
  }
301395
302182
 
302183
+ ;// CONCATENATED MODULE: ../gh_provisioner/src/entities/ghorgsettings/index.ts
302184
+
302185
+
302186
+ class EntityGHOrgSettings extends base_Entity {
302187
+ constructor(artifact) {
302188
+ super(artifact, {
302189
+ config: {},
302190
+ });
302191
+ }
302192
+ async loadResources(tfOp) {
302193
+ gh_provisioner_src_logger.info(`[gh-provisioner] running ${tfOp} on ${this.k8sId}`);
302194
+ try {
302195
+ const cr = this.cr;
302196
+ this.patchData({
302197
+ path: '/config',
302198
+ op: PatchOperations.replace,
302199
+ value: {
302200
+ billingEmail: cr.spec.billingEmail,
302201
+ company: cr.spec.company,
302202
+ blog: cr.spec.blog,
302203
+ email: cr.spec.email,
302204
+ twitterUsername: cr.spec.twitterUsername,
302205
+ location: cr.spec.location,
302206
+ name: cr.spec.name,
302207
+ description: cr.spec.description,
302208
+ hasOrganizationProjects: cr.spec.hasOrganizationProjects,
302209
+ hasRepositoryProjects: cr.spec.hasRepositoryProjects,
302210
+ defaultRepositoryPermission: cr.spec.defaultRepositoryPermission,
302211
+ membersCanCreateRepositories: cr.spec.membersCanCreateRepositories,
302212
+ membersCanCreatePublicRepositories: cr.spec.membersCanCreatePublicRepositories,
302213
+ membersCanCreatePrivateRepositories: cr.spec.membersCanCreatePrivateRepositories,
302214
+ membersCanCreateInternalRepositories: cr.spec.membersCanCreateInternalRepositories,
302215
+ membersCanCreatePages: cr.spec.membersCanCreatePages,
302216
+ membersCanCreatePublicPages: cr.spec.membersCanCreatePublicPages,
302217
+ membersCanCreatePrivatePages: cr.spec.membersCanCreatePrivatePages,
302218
+ membersCanForkPrivateRepositories: cr.spec.membersCanForkPrivateRepositories,
302219
+ webCommitSignoffRequired: cr.spec.webCommitSignoffRequired,
302220
+ advancedSecurityEnabledForNewRepositories: cr.spec.advancedSecurityEnabledForNewRepositories,
302221
+ dependabotAlertsEnabledForNewRepositories: cr.spec.dependabotAlertsEnabledForNewRepositories,
302222
+ dependabotSecurityUpdatesEnabledForNewRepositories: cr.spec.dependabotSecurityUpdatesEnabledForNewRepositories,
302223
+ dependencyGraphEnabledForNewRepositories: cr.spec.dependencyGraphEnabledForNewRepositories,
302224
+ secretScanningEnabledForNewRepositories: cr.spec.secretScanningEnabledForNewRepositories,
302225
+ secretScanningPushProtectionEnabledForNewRepositories: cr.spec.secretScanningPushProtectionEnabledForNewRepositories,
302226
+ },
302227
+ });
302228
+ gh_provisioner_src_logger.debug(`[gh-provisioner] ${this.k8sId} loaded its data`);
302229
+ }
302230
+ catch (err) {
302231
+ const message = err instanceof Error ? err.message : String(err);
302232
+ gh_provisioner_src_logger.error(`[gh-provisioner] ${this.k8sId} error loading resources: ${message}`);
302233
+ throw new Error(`[gh-provisioner] ${this.k8sId} error loading resources: ${message}`);
302234
+ }
302235
+ }
302236
+ async postProvision(tfOp) { }
302237
+ async loadAddressesToImport() {
302238
+ this.patchImportData({
302239
+ op: PatchOperations.add,
302240
+ path: '/imports/-',
302241
+ value: {
302242
+ to: 'github_organization_settings.this',
302243
+ id: this.cr.spec.org,
302244
+ },
302245
+ });
302246
+ }
302247
+ }
302248
+
301396
302249
  ;// CONCATENATED MODULE: ../gh_provisioner/src/entities/ghorgwebhook/index.ts
301397
302250
 
301398
302251
 
@@ -301468,6 +302321,7 @@ class EntityGHOrgWebHook extends base_Entity {
301468
302321
 
301469
302322
 
301470
302323
 
302324
+
301471
302325
  function entities_getEntity(cr) {
301472
302326
  const entityClass = getEntityClass(cr.kind);
301473
302327
  return new entityClass(cr);
@@ -301486,6 +302340,8 @@ function getEntityClass(kind) {
301486
302340
  return EntityGHMembership;
301487
302341
  case 'FirestartrGithubOrgWebhook':
301488
302342
  return EntityGHOrgWebHook;
302343
+ case 'FirestartrGithubOrganizationSettings':
302344
+ return EntityGHOrgSettings;
301489
302345
  default:
301490
302346
  throw new Error(`kind ${kind} has no entity associated`);
301491
302347
  }
@@ -301898,6 +302754,7 @@ const GITHUB_RESOURCE_KINDS = [
301898
302754
  'FirestartrGithubRepositoryFeature',
301899
302755
  'FirestartrGithubRepositorySecretsSection',
301900
302756
  'FirestartrGithubOrgWebhook',
302757
+ 'FirestartrGithubOrganizationSettings',
301901
302758
  ];
301902
302759
  const GITHUB_REPOSITORY_DEPENDENT_KINDS = [
301903
302760
  'FirestartrGithubRepositoryFeature',
@@ -302132,7 +302989,7 @@ function getPrAwareItemByItemPath(opts, currentStatus) {
302132
302989
  const baseResource = await getBaseGithubResource(itemPath, opts);
302133
302990
  if (baseResource)
302134
302991
  return baseResource;
302135
- return getItemByItemPath(itemPath, apiGroup, apiVersion);
302992
+ return ctl_getItemByItemPath(itemPath, apiGroup, apiVersion);
302136
302993
  };
302137
302994
  }
302138
302995
  async function getBaseGithubResource(itemPath, opts) {
@@ -302293,40 +303150,64 @@ function getSafeCommandByStatus(status) {
302293
303150
  }
302294
303151
  }
302295
303152
 
302296
- ;// CONCATENATED MODULE: ../operator/src/ctl_collections.ts
303153
+ ;// CONCATENATED MODULE: ../operator/src/ownership.ts
302297
303154
 
302298
303155
 
302299
303156
 
302300
- // generator function to traverse elements
302301
- // it is async and iterable
302302
- async function* traverseCRCollection(pluralKind, namespace, options = {}, apiGroup = 'firestartr.dev', apiVersion = 'v1') {
302303
- const { limit = 300 } = options; // between 250-300
303157
+ async function getOwnerReferences(item) {
303158
+ return item.metadata?.ownerReferences || [];
303159
+ }
303160
+ async function ownership_setOwnerReference(itemPath, namespace, ownerKind, ownerName, blockOwnerDeletion = true) {
303161
+ let item = null;
302304
303162
  try {
302305
- let continueToken = undefined;
302306
- const { kc, opts } = await ctl_getConnection();
302307
- const k8sApi = kc.makeApiClient(client_node_dist.CustomObjectsApi);
302308
- const apiGroup = 'firestartr.dev';
302309
- const apiVersion = 'v1';
302310
- const apiPaths = `/apis/${apiGroup}/${apiVersion}/namespaces/${namespace}/${pluralKind}`;
302311
- do {
302312
- const res = await k8sApi.listNamespacedCustomObject(apiGroup, apiVersion, namespace, pluralKind, undefined, // pretty
302313
- undefined, // allowWatchBookmarks
302314
- continueToken, // _continue
302315
- undefined, // fieldSelector
302316
- undefined, // labelSelector
302317
- limit);
302318
- const body = res.body;
302319
- const items = body.items || [];
302320
- for (const item of items) {
302321
- yield item;
302322
- }
302323
- continueToken = body.metadata?.continue;
302324
- } while (continueToken);
303163
+ // we need to search for the owner's uuid
303164
+ const owner = await getItemByItemPath(`${namespace}/${ownerKind}/${ownerName}`);
303165
+ const ownerReference = {
303166
+ apiVersion: owner.apiVersion,
303167
+ kind: owner.kind,
303168
+ name: ownerName,
303169
+ controller: true,
303170
+ blockOwnerDeletion,
303171
+ uid: owner.metadata.uid,
303172
+ };
303173
+ // we get the item (to prevent race conditions)
303174
+ item = await getItemByItemPath(itemPath);
303175
+ const ownerReferences = item.metadata.ownerReferences ?? [];
303176
+ const existingRefIndex = ownerReferences.findIndex((ref) => ref.uid === ownerReference.uid);
303177
+ if (existingRefIndex === -1) {
303178
+ // Reference does not exist, add it
303179
+ ownerReferences.push(ownerReference);
303180
+ }
303181
+ else {
303182
+ ownerReferences[existingRefIndex] = ownerReference;
303183
+ }
303184
+ await writeOwnerReferences(getPluralFromKind(item.kind), item.metadata.namespace, item, ownerReferences);
302325
303185
  }
302326
303186
  catch (err) {
302327
- operator_src_logger.error(`Error traversing ${namespace}/${pluralKind}: ${err}`);
302328
- throw new Error(`Error traversing ${namespace}/${pluralKind}: ${err}`);
303187
+ log.error(err);
303188
+ throw `Setting OwnerReferences to ${item.kind}/${item.metadata.name}: ${err}`;
303189
+ }
303190
+ }
303191
+ async function writeOwnerReferences(kind, namespace, item, ownerReferences) {
303192
+ log.debug(`The ctl is setting the ownerReferences for '${kind}/${item.metadata.name}' in namespace '${namespace}'.`);
303193
+ const { kc, opts } = await getConnection();
303194
+ const url = `${kc.getCurrentCluster().server}/apis/firestartr.dev/v1/namespaces/${namespace}/${kind}/${item.metadata.name}`;
303195
+ opts.headers['Content-Type'] = 'application/json-patch+json';
303196
+ opts.headers['Accept'] = '*';
303197
+ const patch = {
303198
+ op: 'replace',
303199
+ path: '/metadata/ownerReferences',
303200
+ value: ownerReferences,
303201
+ };
303202
+ const r = await fetch(url, {
303203
+ method: 'PATCH',
303204
+ headers: opts.headers,
303205
+ body: JSON.stringify([patch]),
303206
+ });
303207
+ if (!r.ok) {
303208
+ throw `Error on setOwnerReferences: ${namespace}/${kind}/${item['metadata']['name']}: ${r.statusText}`;
302329
303209
  }
303210
+ return r.json();
302330
303211
  }
302331
303212
 
302332
303213
  ;// CONCATENATED MODULE: ../operator/src/children.ts
@@ -302373,7 +303254,7 @@ async function manageOwnershipReferences(item, handler, op) {
302373
303254
  *******************************************************************************/
302374
303255
  if (kindsWithFirestartrGithubRepositoryDependence.indexOf(item.kind) !== -1) {
302375
303256
  // we need the parent
302376
- const parentItem = await getItemByItemPath([
303257
+ const parentItem = await ctl_getItemByItemPath([
302377
303258
  item.metadata.namespace,
302378
303259
  definitions_getPluralFromKind('FirestartrGithubRepository'),
302379
303260
  item.spec.repositoryTarget.ref.name,
@@ -302384,24 +303265,24 @@ async function manageOwnershipReferences(item, handler, op) {
302384
303265
  async function manageOwnershipReferencesPostDeletion(item, handler, op) {
302385
303266
  // We will check if the repo has still some references left
302386
303267
  if (kindsWithFirestartrGithubRepositoryDependence.indexOf(item.kind) !== -1) {
302387
- await manageChildrenReferences(item, handler, op);
303268
+ await ownership_manageChildrenReferences(item, handler, op);
302388
303269
  }
302389
303270
  // if the parent is being deleted is ok to control there are no more children
302390
303271
  // for preventing a stuck deletion
302391
303272
  else if (kindsWithChildren.indexOf(item.kind) !== -1) {
302392
- await removeFinalizerIfNoMoreChildren(item, handler, op);
303273
+ await ownership_removeFinalizerIfNoMoreChildren(item, handler, op);
302393
303274
  }
302394
303275
  }
302395
- async function manageChildrenReferences(item, handler, op) {
303276
+ async function ownership_manageChildrenReferences(item, handler, op) {
302396
303277
  // for now is only FirestartrGithubRepository
302397
- const parentItem = await getItemByItemPath([
303278
+ const parentItem = await ctl_getItemByItemPath([
302398
303279
  item.metadata.namespace,
302399
303280
  definitions_getPluralFromKind('FirestartrGithubRepository'),
302400
303281
  item.spec.repositoryTarget.ref.name,
302401
303282
  ].join('/'));
302402
- await removeFinalizerIfNoMoreChildren(parentItem, handler, op);
303283
+ await ownership_removeFinalizerIfNoMoreChildren(parentItem, handler, op);
302403
303284
  }
302404
- async function removeFinalizerIfNoMoreChildren(parentItem, handler, op) {
303285
+ async function ownership_removeFinalizerIfNoMoreChildren(parentItem, handler, op) {
302405
303286
  try {
302406
303287
  let numberOfChildren = 0;
302407
303288
  for (const child of kindsWithFirestartrGithubRepositoryDependence) {
@@ -302411,7 +303292,17 @@ async function removeFinalizerIfNoMoreChildren(parentItem, handler, op) {
302411
303292
  operator_src_logger.error(`Number of children ${numberOfChildren}`);
302412
303293
  if (numberOfChildren === 0) {
302413
303294
  operator_src_logger.info(`${parentItem.kind}/${parentItem.metadata.name} has no more children. Removing finalizer of foreground-deletion`);
302414
- await unsetFinalizer(definitions_getPluralFromKind(parentItem.kind), parentItem.metadata.namespace, parentItem, 'firestartr.dev/foreground-deletion');
303295
+ try {
303296
+ await unsetFinalizer(definitions_getPluralFromKind(parentItem.kind), parentItem.metadata.namespace, parentItem, 'firestartr.dev/foreground-deletion');
303297
+ }
303298
+ catch (unsetErr) {
303299
+ if (typeof unsetErr === 'string' && unsetErr.includes('Not Found')) {
303300
+ operator_src_logger.info(`${parentItem.kind}/${parentItem.metadata.name} was already deleted; skipping finalizer removal`);
303301
+ }
303302
+ else {
303303
+ throw unsetErr;
303304
+ }
303305
+ }
302415
303306
  }
302416
303307
  }
302417
303308
  catch (err) {
@@ -302454,10 +303345,8 @@ async function GHCheckRun(cmd, item) {
302454
303345
  throw new Error('GHCheckRun: prNumber not retrievable');
302455
303346
  }
302456
303347
  const checkRun = await gh_checkrun_operatorProfile().feedback.createCheckRun(prInfo.org, prInfo.repo, gh_checkrun_helperCreateCheckRunName(cmd, item), {
302457
- //Number(pr_number),
302458
303348
  pullNumber: Number(prInfo.prNumber),
302459
- includeCheckRunComment: true,
302460
- checkRunComment: `The Github ${item.kind} is being processed (cmd=${cmd}). Details: `,
303349
+ // check-run comments removed: redundant with native checks widget (#1985)
302461
303350
  });
302462
303351
  checkRun.mdOptionsDetails({
302463
303352
  quotes: 'terraform',
@@ -303183,6 +304072,7 @@ function getProvisionImplementation(plural) {
303183
304072
  case 'githubrepositoryfeatures':
303184
304073
  case 'githubmemberships':
303185
304074
  case 'githuborgwebhooks':
304075
+ case 'githuborganizationsettings':
303186
304076
  implementation = process_operation_processOperation;
303187
304077
  break;
303188
304078
  case 'fsdummiesa':
@@ -303296,6 +304186,14 @@ const cdk8s_rendererSubcommands = {
303296
304186
  { name: 'disableRenames', type: Boolean, defaultValue: false },
303297
304187
  { name: 'claimRefsList', type: String, defaultValue: '' },
303298
304188
  { name: 'claimFilesList', type: String, defaultValue: '' },
304189
+ /**
304190
+ * Repository URL for backstage.io/edit-url annotation
304191
+ */
304192
+ { name: 'repositoryUrl', type: String },
304193
+ /**
304194
+ * Default branch for backstage.io/edit-url annotation
304195
+ */
304196
+ { name: 'defaultBranch', type: String, defaultValue: 'main' },
303299
304197
  /**
303300
304198
  * Path where the claims defaults are located
303301
304199
  */
@@ -303324,7 +304222,7 @@ const cdk8s_rendererSubcommands = {
303324
304222
  run: async (options) => {
303325
304223
  if (options['render']) {
303326
304224
  console.table(options);
303327
- await runRenderer(options['globals'], options['initializers'], options['claims'], options['previousCRs'], options['claimsDefaults'], options['outputCatalogDir'], options['outputCrDir'], !options['disableRenames'], options['provider'], options['excludePath'], options['validateReferentialIntegrity'], options['claimRefsList'], options['claimFilesList']);
304225
+ await runRenderer(options['globals'], options['initializers'], options['claims'], options['previousCRs'], options['claimsDefaults'], options['outputCatalogDir'], options['outputCrDir'], !options['disableRenames'], options['provider'], options['excludePath'], options['validateReferentialIntegrity'], options['claimRefsList'], options['claimFilesList'], options['repositoryUrl'], options['defaultBranch']);
303328
304226
  }
303329
304227
  else if (options['compare']) {
303330
304228
  await cdk8s_renderer.runComparer(options['claimsFromMain'], options['claimsFromPr'], options['claimsDefaults'], options['wetReposConfig'], options['outputComparer']);
@@ -303606,7 +304504,7 @@ const crs_analyzerSubcommand = {
303606
304504
  };
303607
304505
 
303608
304506
  ;// CONCATENATED MODULE: ./package.json
303609
- const package_namespaceObject = JSON.parse('{"i8":"2.7.0-snapshot-13"}');
304507
+ const package_namespaceObject = JSON.parse('{"i8":"2.7.0-snapshot-14"}');
303610
304508
  ;// CONCATENATED MODULE: ../../package.json
303611
304509
  const package_namespaceObject_1 = {"i8":"2.6.4"};
303612
304510
  ;// CONCATENATED MODULE: ./src/subcommands/index.ts