@firestartr/cli 2.10.0 → 2.11.0-objects-in-patches

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js CHANGED
@@ -284613,6 +284613,17 @@ async function doPaginatedRequest(options) {
284613
284613
  'Cache-Control': 'no-cache',
284614
284614
  });
284615
284615
  }
284616
+ async function getOrgVariable(org, variableName, octokit) {
284617
+ logger.info(`Getting org variable ${variableName} for org ${org}`);
284618
+ if (!octokit) {
284619
+ octokit = await getOctokitForOrg(org);
284620
+ }
284621
+ const response = await octokit.rest.actions.getOrgVariable({
284622
+ org,
284623
+ name: variableName,
284624
+ });
284625
+ return response.data;
284626
+ }
284616
284627
  /* harmony default export */ const organization = ({
284617
284628
  getRepositoryList,
284618
284629
  getTeamList,
@@ -284623,6 +284634,7 @@ async function doPaginatedRequest(options) {
284623
284634
  getOrgTeamsDirectAccess,
284624
284635
  getOrgPlanName,
284625
284636
  getWebhookList,
284637
+ getOrgVariable,
284626
284638
  });
284627
284639
 
284628
284640
  // EXTERNAL MODULE: external "fs"
@@ -286115,6 +286127,10 @@ function createFacade(profileName) {
286115
286127
  const octokit = await getOctokitForOrg(orgName);
286116
286128
  return getOrgPlanName(orgName, octokit);
286117
286129
  },
286130
+ getOrgVariable: async (orgName, variableName) => {
286131
+ const octokit = await getOctokitForOrg(orgName);
286132
+ return getOrgVariable(orgName, variableName, octokit);
286133
+ },
286118
286134
  },
286119
286135
  repo: {
286120
286136
  addStatusCheck: async (output, isFailure, headSha, name, status, repoName, owner) => {
@@ -319522,9 +319538,14 @@ class UUIDInitializer extends InitializerPatches {
319522
319538
  },
319523
319539
  apply(cr) {
319524
319540
  const ctx = helperCTX(this);
319525
- const uuid = previousCR?.spec?.firestartr?.tfStateKey ||
319526
- claim.providers?.[ctx.provider]?.tfStateKey ||
319527
- (0,wrapper.v4)();
319541
+ const reusePrevious = previousCR && previousCR.kind === ctx.kind;
319542
+ const uuid = reusePrevious
319543
+ ? previousCR?.spec?.firestartr?.tfStateKey ||
319544
+ claim.providers?.[ctx.provider]?.tfStateKey ||
319545
+ (0,wrapper.v4)()
319546
+ : cr.spec?.firestartr?.tfStateKey ||
319547
+ claim.providers?.[ctx.provider]?.tfStateKey ||
319548
+ (0,wrapper.v4)();
319528
319549
  if (!cr.spec)
319529
319550
  cr.spec = {};
319530
319551
  if (!cr.spec.firestartr)
@@ -320066,6 +320087,7 @@ const ONE_WAY_DEFINITIONS = [
320066
320087
  '/spec/vars',
320067
320088
  '/spec/actions/oidc',
320068
320089
  '/spec/repo/labels',
320090
+ '/spec/actionsVariables',
320069
320091
  ];
320070
320092
  function applyOneWayDefs(crSpecs) {
320071
320093
  const crSpecsClone = JSON.parse(JSON.stringify(crSpecs));
@@ -322064,6 +322086,25 @@ function extractAllRefs(claimData) {
322064
322086
  refs.push(...secretsRefs);
322065
322087
  break;
322066
322088
  }
322089
+ case 'OrgSettingsClaim': {
322090
+ const actionsVariables = parsedClaim.providers?.github?.actions_variables;
322091
+ if (Array.isArray(actionsVariables)) {
322092
+ for (const variable of actionsVariables) {
322093
+ if (variable.visibility !== 'selected')
322094
+ continue;
322095
+ const selectedRepos = variable.selected_repositories;
322096
+ if (!Array.isArray(selectedRepos))
322097
+ continue;
322098
+ for (const repoRef of selectedRepos) {
322099
+ const match = repoRef.match(/^component:(.+)$/);
322100
+ if (match) {
322101
+ refs.push(`ComponentClaim-${match[1]}`);
322102
+ }
322103
+ }
322104
+ }
322105
+ }
322106
+ break;
322107
+ }
322067
322108
  }
322068
322109
  logger.info(`Refs for ${parsedClaim.kind}-${parsedClaim.name}: ${[...new Set(refs)].join(',')}`);
322069
322110
  return [...new Set(refs)];
@@ -323190,6 +323231,49 @@ const organizationSettingsProperties = {
323190
323231
  secret_scanning_push_protection_enabled_for_new_repositories: {
323191
323232
  type: 'boolean',
323192
323233
  },
323234
+ actions_variables: {
323235
+ type: 'array',
323236
+ items: {
323237
+ type: 'object',
323238
+ properties: {
323239
+ name: {
323240
+ type: 'string',
323241
+ pattern: '^[A-Za-z0-9_]+$',
323242
+ },
323243
+ value: {
323244
+ type: 'string',
323245
+ },
323246
+ visibility: {
323247
+ type: 'string',
323248
+ enum: ['all', 'private', 'selected'],
323249
+ },
323250
+ selected_repositories: {
323251
+ type: 'array',
323252
+ items: {
323253
+ $ref: 'firestartr.dev://common/FirestartrComponentRef',
323254
+ },
323255
+ },
323256
+ },
323257
+ required: ['name', 'value', 'visibility'],
323258
+ additionalProperties: false,
323259
+ allOf: [
323260
+ {
323261
+ if: {
323262
+ properties: {
323263
+ visibility: { const: 'selected' },
323264
+ },
323265
+ required: ['visibility'],
323266
+ },
323267
+ then: {},
323268
+ else: {
323269
+ properties: {
323270
+ selected_repositories: { type: 'array', maxItems: 0 },
323271
+ },
323272
+ },
323273
+ },
323274
+ ],
323275
+ },
323276
+ },
323193
323277
  };
323194
323278
  /* harmony default export */ const github_orgsettings_schema = ({
323195
323279
  $schema: SCHEMA,
@@ -324874,6 +324958,9 @@ var ajv_default = /*#__PURE__*/__nccwpck_require__.n(dist_ajv);
324874
324958
  $arg: {
324875
324959
  type: 'string',
324876
324960
  },
324961
+ $format: {
324962
+ type: 'string',
324963
+ },
324877
324964
  $template: {
324878
324965
  type: 'string',
324879
324966
  },
@@ -325803,6 +325890,268 @@ function addTraceabilityStamp(context, content) {
325803
325890
  }
325804
325891
  }
325805
325892
 
325893
+ // EXTERNAL MODULE: external "node:path"
325894
+ var external_node_path_ = __nccwpck_require__(49411);
325895
+ // EXTERNAL MODULE: external "node:fs"
325896
+ var external_node_fs_ = __nccwpck_require__(87561);
325897
+ ;// CONCATENATED MODULE: external "node:os"
325898
+ const external_node_os_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:os");
325899
+ ;// CONCATENATED MODULE: ../features_renderer/src/auxiliar.ts
325900
+ // src/auxiliar.ts
325901
+
325902
+
325903
+
325904
+
325905
+
325906
+
325907
+
325908
+ const renderTestsSchema = {
325909
+ $schema: 'http://json-schema.org/draft-07/schema#',
325910
+ type: 'object',
325911
+ additionalProperties: false,
325912
+ required: ['tests'],
325913
+ properties: {
325914
+ tests: {
325915
+ type: 'array',
325916
+ minItems: 1,
325917
+ items: {
325918
+ type: 'object',
325919
+ additionalProperties: false,
325920
+ required: ['name', 'cr'],
325921
+ properties: {
325922
+ name: { type: 'string', minLength: 1 },
325923
+ cr: { type: 'string', minLength: 1 },
325924
+ args: { type: 'object' },
325925
+ },
325926
+ },
325927
+ },
325928
+ },
325929
+ };
325930
+ const YAML_FILE_REGEX = /\.[yY]a?ml$/;
325931
+ /* ---------- Core helpers ---------- */
325932
+ function formatAjvErrors(errors) {
325933
+ if (!errors || errors.length === 0)
325934
+ return 'Unknown schema error';
325935
+ return errors
325936
+ .map((e) => {
325937
+ const where = e.instancePath && e.instancePath.length ? e.instancePath : '/';
325938
+ const msg = e.message ?? 'validation error';
325939
+ return `- ${where} ${msg}`;
325940
+ })
325941
+ .join('\n');
325942
+ }
325943
+ function ensureUniqueTestNames(doc) {
325944
+ const seen = new Set();
325945
+ for (const t of doc.tests) {
325946
+ if (seen.has(t.name)) {
325947
+ throw new Error(`Duplicate test name "${t.name}" in render_tests.yaml`);
325948
+ }
325949
+ seen.add(t.name);
325950
+ }
325951
+ }
325952
+ function loadAndValidateRenderTests(featurePath) {
325953
+ const file = external_node_path_.join(featurePath, 'render_tests.yaml');
325954
+ if (!external_node_fs_.existsSync(file)) {
325955
+ throw new Error(`render_tests.yaml is required but not found at ${file}`);
325956
+ }
325957
+ const raw = loadYaml(file);
325958
+ const ajv = new (ajv_default())({ allErrors: true, strict: true, allowUnionTypes: true });
325959
+ const validate = ajv.compile(renderTestsSchema);
325960
+ const ok = validate(raw);
325961
+ if (!ok) {
325962
+ throw new Error(`render_tests.yaml schema validation failed:\n${formatAjvErrors(validate.errors ?? [])}`);
325963
+ }
325964
+ const doc = raw;
325965
+ ensureUniqueTestNames(doc);
325966
+ return doc;
325967
+ }
325968
+ function resolveCrPath(featurePath, crRelPath) {
325969
+ if (external_node_path_.isAbsolute(crRelPath)) {
325970
+ throw new Error(`CR path must be relative to the feature root, got absolute: ${crRelPath}`);
325971
+ }
325972
+ const resolved = external_node_path_.resolve(featurePath, crRelPath);
325973
+ if (!external_node_fs_.existsSync(resolved)) {
325974
+ throw new Error(`CR file not found (resolved from "${crRelPath}"): ${resolved}`);
325975
+ }
325976
+ return resolved;
325977
+ }
325978
+ function listYamlFiles(dir) {
325979
+ if (!fs.existsSync(dir))
325980
+ return [];
325981
+ let entries;
325982
+ try {
325983
+ entries = fs.readdirSync(dir, { withFileTypes: true });
325984
+ }
325985
+ catch (e) {
325986
+ const msg = e instanceof Error ? e.message : String(e);
325987
+ throw new Error(`Failed to read directory "${dir}": ${msg}`);
325988
+ }
325989
+ return entries
325990
+ .filter((e) => e.isFile() && YAML_FILE_REGEX.test(e.name))
325991
+ .map((e) => path.join(dir, e.name));
325992
+ }
325993
+ function loadYaml(file) {
325994
+ try {
325995
+ const configDataRaw = common_slurpFile(external_node_path_.join(file));
325996
+ return catalog_common/* default.io.fromYaml */.Z.io.fromYaml(configDataRaw);
325997
+ }
325998
+ catch (e) {
325999
+ const msg = e instanceof Error ? e.message : String(e);
326000
+ throw new Error(`Failed to parse YAML "${file}": ${msg}`);
326001
+ }
326002
+ }
326003
+ function ensureSafeTmpNames(name) {
326004
+ if (typeof name !== 'string' || !name.trim()) {
326005
+ throw new Error('Test "name" must be a non-empty string');
326006
+ }
326007
+ if (name.length > 128) {
326008
+ throw new Error('Test "name" is too long (max 128 characters)');
326009
+ }
326010
+ if (external_node_path_.isAbsolute(name)) {
326011
+ throw new Error(`Test "name" must be relative, got absolute: "${name}"`);
326012
+ }
326013
+ if (name.includes('..')) {
326014
+ throw new Error('Test "name" must not contain ".."');
326015
+ }
326016
+ if (!/^[A-Za-z0-9._-]+$/.test(name)) {
326017
+ throw new Error('Test "name" may only contain letters, numbers, ".", "_", or "-"');
326018
+ }
326019
+ }
326020
+ async function mkNamedTmp(...names) {
326021
+ for (const name of names) {
326022
+ ensureSafeTmpNames(name);
326023
+ }
326024
+ const dir = external_node_path_.join(external_node_os_namespaceObject.tmpdir(), ...names);
326025
+ await promises_.rm(dir, { recursive: true, force: true });
326026
+ await promises_.mkdir(dir, { recursive: true });
326027
+ return dir;
326028
+ }
326029
+ async function mkTmp(prefix = 'feature-render-') {
326030
+ return await fsp.mkdtemp(path.join(os.tmpdir(), prefix));
326031
+ }
326032
+ function buildExpectedOutput(config, renderDir) {
326033
+ const files = (config.files || []).map((f) => ({
326034
+ localPath: external_node_path_.join(renderDir, f.dest),
326035
+ repoPath: f.dest,
326036
+ userManaged: f.user_managed ?? f.upgradable ?? false,
326037
+ targetBranch: f.target_branch ?? '',
326038
+ }));
326039
+ return {
326040
+ files,
326041
+ patches: config.patches || [],
326042
+ };
326043
+ }
326044
+ /* ---------- Context-style API for a render temp dir ---------- */
326045
+ async function createRenderContext(prefix = 'feature-render-') {
326046
+ const dir = await mkTmp(prefix);
326047
+ const join = (...p) => path.join(dir, ...p);
326048
+ return {
326049
+ getContextPath: () => dir,
326050
+ join,
326051
+ getFile: async (relPath, { yaml: asYaml = false, json: asJson = false, } = {}) => {
326052
+ const data = await fsp.readFile(join(relPath), 'utf8');
326053
+ if (asYaml)
326054
+ return common.io.fromYaml(data);
326055
+ if (asJson)
326056
+ return JSON.parse(data);
326057
+ return data;
326058
+ },
326059
+ getFilePath: (relPath) => join(relPath),
326060
+ setFile: async (relPath, contents) => {
326061
+ await fsp.mkdir(path.dirname(join(relPath)), { recursive: true });
326062
+ await fsp.writeFile(join(relPath), contents);
326063
+ },
326064
+ exists: async (relPath) => {
326065
+ try {
326066
+ await fsp.access(join(relPath));
326067
+ return true;
326068
+ }
326069
+ catch {
326070
+ return false;
326071
+ }
326072
+ },
326073
+ getOutputJson: async () => {
326074
+ const p = join('output.json');
326075
+ const raw = await fsp.readFile(p, 'utf8');
326076
+ return JSON.parse(raw);
326077
+ },
326078
+ list: async (relPath = '.') => {
326079
+ const entries = await fsp.readdir(join(relPath), {
326080
+ withFileTypes: true,
326081
+ });
326082
+ return entries.map((e) => ({ name: e.name, isDir: e.isDirectory() }));
326083
+ },
326084
+ remove: async () => {
326085
+ await fsp.rm(dir, { recursive: true, force: true });
326086
+ },
326087
+ };
326088
+ }
326089
+ /* harmony default export */ const auxiliar = ({
326090
+ mkNamedTmp,
326091
+ loadYaml,
326092
+ buildExpectedOutput,
326093
+ loadAndValidateRenderTests,
326094
+ resolveCrPath,
326095
+ });
326096
+
326097
+ ;// CONCATENATED MODULE: ../features_renderer/src/featureArgsValidation.ts
326098
+
326099
+
326100
+
326101
+
326102
+
326103
+ /**
326104
+ * Validates user-supplied feature args against the feature's on-disk
326105
+ * `schema.json` (generated by prefapp/features from the feature's config.yaml).
326106
+ *
326107
+ * The downloader-injected `traceability` key is stripped before validation so it
326108
+ * never trips the unknown-key check. `additionalProperties: false` is injected
326109
+ * into a shallow copy of the schema before compiling; the on-disk file is never
326110
+ * mutated. A feature that ships no schema skips validation with a warning so
326111
+ * legacy, `ref`-fetched, and template features keep rendering.
326112
+ *
326113
+ * @param featurePath - Absolute path to the extracted feature.
326114
+ * @param featureArgs - The raw user-supplied feature args.
326115
+ */
326116
+ function validateFeatureArgs(featurePath, featureArgs) {
326117
+ const schemaPath = external_node_path_.join(featurePath, 'schema.json');
326118
+ if (!isFile(schemaPath)) {
326119
+ src_logger.warn(`Feature ${featurePath} has no schema.json; skipping feature args validation`);
326120
+ return;
326121
+ }
326122
+ let schema;
326123
+ try {
326124
+ schema = JSON.parse(common_slurpFile(schemaPath));
326125
+ }
326126
+ catch (error) {
326127
+ const message = error instanceof Error ? error.message : String(error);
326128
+ throw new Error(`Feature: loading schema.json at "${schemaPath}": ${message}`);
326129
+ }
326130
+ const argsToValidate = { ...featureArgs };
326131
+ delete argsToValidate['traceability'];
326132
+ const ajv = new (ajv_default())({ allErrors: true, strictSchema: false });
326133
+ const validate = ajv.compile({ ...schema, additionalProperties: false });
326134
+ if (validate(argsToValidate)) {
326135
+ return;
326136
+ }
326137
+ const lines = (validate.errors ?? []).map((error) => {
326138
+ const key = resolveOffendingKey(error);
326139
+ const where = key ? `/${key}` : '/';
326140
+ const value = key ? argsToValidate[key] : argsToValidate;
326141
+ return `${formatAjvErrors([{ ...error, instancePath: where }])} (got ${JSON.stringify(value)})`;
326142
+ });
326143
+ throw new Error(`Feature args invalid for "${featurePath}":\n${lines.join('\n')}`);
326144
+ }
326145
+ function resolveOffendingKey(error) {
326146
+ if (typeof error.params?.additionalProperty === 'string') {
326147
+ return error.params.additionalProperty;
326148
+ }
326149
+ if (error.instancePath) {
326150
+ return error.instancePath.replace(/^\//, '');
326151
+ }
326152
+ return undefined;
326153
+ }
326154
+
325806
326155
  ;// CONCATENATED MODULE: ../features_renderer/src/render.ts
325807
326156
 
325808
326157
 
@@ -325812,8 +326161,10 @@ function addTraceabilityStamp(context, content) {
325812
326161
 
325813
326162
 
325814
326163
 
326164
+
325815
326165
  function render(featurePath, featureRenderPath, entity, firestartrConfig = {}, featureArgs = {}) {
325816
326166
  const configData = validate(featurePath);
326167
+ validateFeatureArgs(featurePath, featureArgs);
325817
326168
  const context = buildContext(entity, configData.args, firestartrConfig, featureArgs);
325818
326169
  context.config = JSON.parse(renderContent(JSON.stringify(configData), context));
325819
326170
  if ('filesTemplates' in context.config) {
@@ -325993,210 +326344,6 @@ function allowsNonAnchoredPaths(configData) {
325993
326344
  return configData?.meta?.allow_non_anchored_paths === true;
325994
326345
  }
325995
326346
 
325996
- // EXTERNAL MODULE: external "node:fs"
325997
- var external_node_fs_ = __nccwpck_require__(87561);
325998
- // EXTERNAL MODULE: external "node:path"
325999
- var external_node_path_ = __nccwpck_require__(49411);
326000
- ;// CONCATENATED MODULE: external "node:os"
326001
- const external_node_os_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:os");
326002
- ;// CONCATENATED MODULE: ../features_renderer/src/auxiliar.ts
326003
- // src/auxiliar.ts
326004
-
326005
-
326006
-
326007
-
326008
-
326009
-
326010
-
326011
- const renderTestsSchema = {
326012
- $schema: 'http://json-schema.org/draft-07/schema#',
326013
- type: 'object',
326014
- additionalProperties: false,
326015
- required: ['tests'],
326016
- properties: {
326017
- tests: {
326018
- type: 'array',
326019
- minItems: 1,
326020
- items: {
326021
- type: 'object',
326022
- additionalProperties: false,
326023
- required: ['name', 'cr'],
326024
- properties: {
326025
- name: { type: 'string', minLength: 1 },
326026
- cr: { type: 'string', minLength: 1 },
326027
- args: { type: 'object' },
326028
- },
326029
- },
326030
- },
326031
- },
326032
- };
326033
- const YAML_FILE_REGEX = /\.[yY]a?ml$/;
326034
- /* ---------- Core helpers ---------- */
326035
- function formatAjvErrors(errors) {
326036
- if (!errors || errors.length === 0)
326037
- return 'Unknown schema error';
326038
- return errors
326039
- .map((e) => {
326040
- const where = e.instancePath && e.instancePath.length ? e.instancePath : '/';
326041
- const msg = e.message ?? 'validation error';
326042
- return `- ${where} ${msg}`;
326043
- })
326044
- .join('\n');
326045
- }
326046
- function ensureUniqueTestNames(doc) {
326047
- const seen = new Set();
326048
- for (const t of doc.tests) {
326049
- if (seen.has(t.name)) {
326050
- throw new Error(`Duplicate test name "${t.name}" in render_tests.yaml`);
326051
- }
326052
- seen.add(t.name);
326053
- }
326054
- }
326055
- function loadAndValidateRenderTests(featurePath) {
326056
- const file = external_node_path_.join(featurePath, 'render_tests.yaml');
326057
- if (!external_node_fs_.existsSync(file)) {
326058
- throw new Error(`render_tests.yaml is required but not found at ${file}`);
326059
- }
326060
- const raw = loadYaml(file);
326061
- const ajv = new (ajv_default())({ allErrors: true, strict: true, allowUnionTypes: true });
326062
- const validate = ajv.compile(renderTestsSchema);
326063
- const ok = validate(raw);
326064
- if (!ok) {
326065
- throw new Error(`render_tests.yaml schema validation failed:\n${formatAjvErrors(validate.errors ?? [])}`);
326066
- }
326067
- const doc = raw;
326068
- ensureUniqueTestNames(doc);
326069
- return doc;
326070
- }
326071
- function resolveCrPath(featurePath, crRelPath) {
326072
- if (external_node_path_.isAbsolute(crRelPath)) {
326073
- throw new Error(`CR path must be relative to the feature root, got absolute: ${crRelPath}`);
326074
- }
326075
- const resolved = external_node_path_.resolve(featurePath, crRelPath);
326076
- if (!external_node_fs_.existsSync(resolved)) {
326077
- throw new Error(`CR file not found (resolved from "${crRelPath}"): ${resolved}`);
326078
- }
326079
- return resolved;
326080
- }
326081
- function listYamlFiles(dir) {
326082
- if (!fs.existsSync(dir))
326083
- return [];
326084
- let entries;
326085
- try {
326086
- entries = fs.readdirSync(dir, { withFileTypes: true });
326087
- }
326088
- catch (e) {
326089
- const msg = e instanceof Error ? e.message : String(e);
326090
- throw new Error(`Failed to read directory "${dir}": ${msg}`);
326091
- }
326092
- return entries
326093
- .filter((e) => e.isFile() && YAML_FILE_REGEX.test(e.name))
326094
- .map((e) => path.join(dir, e.name));
326095
- }
326096
- function loadYaml(file) {
326097
- try {
326098
- const configDataRaw = common_slurpFile(external_node_path_.join(file));
326099
- return catalog_common/* default.io.fromYaml */.Z.io.fromYaml(configDataRaw);
326100
- }
326101
- catch (e) {
326102
- const msg = e instanceof Error ? e.message : String(e);
326103
- throw new Error(`Failed to parse YAML "${file}": ${msg}`);
326104
- }
326105
- }
326106
- function ensureSafeTmpNames(name) {
326107
- if (typeof name !== 'string' || !name.trim()) {
326108
- throw new Error('Test "name" must be a non-empty string');
326109
- }
326110
- if (name.length > 128) {
326111
- throw new Error('Test "name" is too long (max 128 characters)');
326112
- }
326113
- if (external_node_path_.isAbsolute(name)) {
326114
- throw new Error(`Test "name" must be relative, got absolute: "${name}"`);
326115
- }
326116
- if (name.includes('..')) {
326117
- throw new Error('Test "name" must not contain ".."');
326118
- }
326119
- if (!/^[A-Za-z0-9._-]+$/.test(name)) {
326120
- throw new Error('Test "name" may only contain letters, numbers, ".", "_", or "-"');
326121
- }
326122
- }
326123
- async function mkNamedTmp(...names) {
326124
- for (const name of names) {
326125
- ensureSafeTmpNames(name);
326126
- }
326127
- const dir = external_node_path_.join(external_node_os_namespaceObject.tmpdir(), ...names);
326128
- await promises_.rm(dir, { recursive: true, force: true });
326129
- await promises_.mkdir(dir, { recursive: true });
326130
- return dir;
326131
- }
326132
- async function mkTmp(prefix = 'feature-render-') {
326133
- return await fsp.mkdtemp(path.join(os.tmpdir(), prefix));
326134
- }
326135
- function buildExpectedOutput(config, renderDir) {
326136
- const files = (config.files || []).map((f) => ({
326137
- localPath: external_node_path_.join(renderDir, f.dest),
326138
- repoPath: f.dest,
326139
- userManaged: f.user_managed ?? f.upgradable ?? false,
326140
- targetBranch: f.target_branch ?? '',
326141
- }));
326142
- return {
326143
- files,
326144
- patches: config.patches || [],
326145
- };
326146
- }
326147
- /* ---------- Context-style API for a render temp dir ---------- */
326148
- async function createRenderContext(prefix = 'feature-render-') {
326149
- const dir = await mkTmp(prefix);
326150
- const join = (...p) => path.join(dir, ...p);
326151
- return {
326152
- getContextPath: () => dir,
326153
- join,
326154
- getFile: async (relPath, { yaml: asYaml = false, json: asJson = false, } = {}) => {
326155
- const data = await fsp.readFile(join(relPath), 'utf8');
326156
- if (asYaml)
326157
- return common.io.fromYaml(data);
326158
- if (asJson)
326159
- return JSON.parse(data);
326160
- return data;
326161
- },
326162
- getFilePath: (relPath) => join(relPath),
326163
- setFile: async (relPath, contents) => {
326164
- await fsp.mkdir(path.dirname(join(relPath)), { recursive: true });
326165
- await fsp.writeFile(join(relPath), contents);
326166
- },
326167
- exists: async (relPath) => {
326168
- try {
326169
- await fsp.access(join(relPath));
326170
- return true;
326171
- }
326172
- catch {
326173
- return false;
326174
- }
326175
- },
326176
- getOutputJson: async () => {
326177
- const p = join('output.json');
326178
- const raw = await fsp.readFile(p, 'utf8');
326179
- return JSON.parse(raw);
326180
- },
326181
- list: async (relPath = '.') => {
326182
- const entries = await fsp.readdir(join(relPath), {
326183
- withFileTypes: true,
326184
- });
326185
- return entries.map((e) => ({ name: e.name, isDir: e.isDirectory() }));
326186
- },
326187
- remove: async () => {
326188
- await fsp.rm(dir, { recursive: true, force: true });
326189
- },
326190
- };
326191
- }
326192
- /* harmony default export */ const auxiliar = ({
326193
- mkNamedTmp,
326194
- loadYaml,
326195
- buildExpectedOutput,
326196
- loadAndValidateRenderTests,
326197
- resolveCrPath,
326198
- });
326199
-
326200
326347
  ;// CONCATENATED MODULE: ../features_renderer/src/update_file.ts
326201
326348
 
326202
326349
 
@@ -326209,6 +326356,7 @@ function updateFileContent(featureRenderPath, filePath, content) {
326209
326356
 
326210
326357
 
326211
326358
 
326359
+
326212
326360
  /* harmony default export */ const features_renderer = ({
326213
326361
  validate: validate,
326214
326362
  render: render,
@@ -326217,6 +326365,7 @@ function updateFileContent(featureRenderPath, filePath, content) {
326217
326365
  buildContext: buildContext,
326218
326366
  renderContent: renderContent,
326219
326367
  expandFiles: expandFiles,
326368
+ validateFeatureArgs: validateFeatureArgs,
326220
326369
  });
326221
326370
 
326222
326371
  ;// CONCATENATED MODULE: ../features_preparer/src/logger.ts
@@ -326574,7 +326723,7 @@ const VARIANT_OF_ANNOTATION = 'firestartr.dev/variant-of';
326574
326723
  function isVariantCR(cr) {
326575
326724
  return cr.metadata?.annotations?.[VARIANT_OF_ANNOTATION] !== undefined;
326576
326725
  }
326577
- function getPreviousCRfromClaim(claim, previousCRs) {
326726
+ function getPreviousCRfromClaim(claim, previousCRs, expectedKind) {
326578
326727
  const previousCRsKeys = Object.keys(previousCRs);
326579
326728
  const isVariantClaim = !!claim._parentClaimName;
326580
326729
  for (const previousCRKey of previousCRsKeys) {
@@ -326583,6 +326732,8 @@ function getPreviousCRfromClaim(claim, previousCRs) {
326583
326732
  continue;
326584
326733
  if (isExcludedFromPreviousCR(previousCR.kind))
326585
326734
  continue;
326735
+ if (expectedKind && previousCR.kind !== expectedKind)
326736
+ continue;
326586
326737
  const crVariant = isVariantCR(previousCR);
326587
326738
  if (isVariantClaim && !crVariant)
326588
326739
  continue;
@@ -327597,6 +327748,254 @@ var FirestartrGithubOrganizationSettingsSpecContextProviderRefKind;
327597
327748
  /** FirestartrProviderConfig */
327598
327749
  FirestartrGithubOrganizationSettingsSpecContextProviderRefKind["FIRESTARTR_PROVIDER_CONFIG"] = "FirestartrProviderConfig";
327599
327750
  })(FirestartrGithubOrganizationSettingsSpecContextProviderRefKind || (FirestartrGithubOrganizationSettingsSpecContextProviderRefKind = {}));
327751
+ /**
327752
+ * A resource to handle GitHub Organization Actions Variables.
327753
+ *
327754
+ * @schema FirestartrGithubOrganizationVariableSection
327755
+ */
327756
+ class FirestartrGithubOrganizationVariableSection extends lib.ApiObject {
327757
+ /**
327758
+ * Renders a Kubernetes manifest for "FirestartrGithubOrganizationVariableSection".
327759
+ *
327760
+ * This can be used to inline resource manifests inside other objects (e.g. as templates).
327761
+ *
327762
+ * @param props initialization props
327763
+ */
327764
+ static manifest(props) {
327765
+ return {
327766
+ ...FirestartrGithubOrganizationVariableSection.GVK,
327767
+ ...toJson_FirestartrGithubOrganizationVariableSectionProps(props),
327768
+ };
327769
+ }
327770
+ /**
327771
+ * Defines a "FirestartrGithubOrganizationVariableSection" API object
327772
+ * @param scope the scope in which to define this object
327773
+ * @param id a scope-local name for the object
327774
+ * @param props initialization props
327775
+ */
327776
+ constructor(scope, id, props) {
327777
+ super(scope, id, {
327778
+ ...FirestartrGithubOrganizationVariableSection.GVK,
327779
+ ...props,
327780
+ });
327781
+ }
327782
+ /**
327783
+ * Renders the object to Kubernetes JSON.
327784
+ */
327785
+ toJson() {
327786
+ const resolved = super.toJson();
327787
+ return {
327788
+ ...FirestartrGithubOrganizationVariableSection.GVK,
327789
+ ...toJson_FirestartrGithubOrganizationVariableSectionProps(resolved),
327790
+ };
327791
+ }
327792
+ }
327793
+ /**
327794
+ * Returns the apiVersion and kind for "FirestartrGithubOrganizationVariableSection"
327795
+ */
327796
+ FirestartrGithubOrganizationVariableSection.GVK = {
327797
+ apiVersion: 'firestartr.dev/v1',
327798
+ kind: 'FirestartrGithubOrganizationVariableSection',
327799
+ };
327800
+
327801
+ /**
327802
+ * Converts an object of type 'FirestartrGithubOrganizationVariableSectionProps' to JSON representation.
327803
+ */
327804
+ /* eslint-disable max-len, @stylistic/max-len, quote-props, @stylistic/quote-props */
327805
+ function toJson_FirestartrGithubOrganizationVariableSectionProps(obj) {
327806
+ if (obj === undefined) {
327807
+ return undefined;
327808
+ }
327809
+ const result = {
327810
+ 'metadata': obj.metadata,
327811
+ 'spec': toJson_FirestartrGithubOrganizationVariableSectionSpec(obj.spec),
327812
+ };
327813
+ // filter undefined values
327814
+ return Object.entries(result).reduce((r, i) => (i[1] === undefined) ? r : ({ ...r, [i[0]]: i[1] }), {});
327815
+ }
327816
+ /**
327817
+ * Converts an object of type 'FirestartrGithubOrganizationVariableSectionSpec' to JSON representation.
327818
+ */
327819
+ /* eslint-disable max-len, @stylistic/max-len, quote-props, @stylistic/quote-props */
327820
+ function toJson_FirestartrGithubOrganizationVariableSectionSpec(obj) {
327821
+ if (obj === undefined) {
327822
+ return undefined;
327823
+ }
327824
+ const result = {
327825
+ 'org': obj.org,
327826
+ 'actionsVariables': obj.actionsVariables?.map(y => toJson_FirestartrGithubOrganizationVariableSectionSpecActionsVariables(y)),
327827
+ 'context': toJson_FirestartrGithubOrganizationVariableSectionSpecContext(obj.context),
327828
+ 'firestartr': toJson_FirestartrGithubOrganizationVariableSectionSpecFirestartr(obj.firestartr),
327829
+ 'writeConnectionSecretToRef': toJson_FirestartrGithubOrganizationVariableSectionSpecWriteConnectionSecretToRef(obj.writeConnectionSecretToRef),
327830
+ };
327831
+ // filter undefined values
327832
+ return Object.entries(result).reduce((r, i) => (i[1] === undefined) ? r : ({ ...r, [i[0]]: i[1] }), {});
327833
+ }
327834
+ /**
327835
+ * Converts an object of type 'FirestartrGithubOrganizationVariableSectionSpecActionsVariables' to JSON representation.
327836
+ */
327837
+ /* eslint-disable max-len, @stylistic/max-len, quote-props, @stylistic/quote-props */
327838
+ function toJson_FirestartrGithubOrganizationVariableSectionSpecActionsVariables(obj) {
327839
+ if (obj === undefined) {
327840
+ return undefined;
327841
+ }
327842
+ const result = {
327843
+ 'name': obj.name,
327844
+ 'value': obj.value,
327845
+ 'visibility': obj.visibility,
327846
+ 'selectedRepositories': obj.selectedRepositories?.map(y => y),
327847
+ };
327848
+ // filter undefined values
327849
+ return Object.entries(result).reduce((r, i) => (i[1] === undefined) ? r : ({ ...r, [i[0]]: i[1] }), {});
327850
+ }
327851
+ /**
327852
+ * Converts an object of type 'FirestartrGithubOrganizationVariableSectionSpecContext' to JSON representation.
327853
+ */
327854
+ /* eslint-disable max-len, @stylistic/max-len, quote-props, @stylistic/quote-props */
327855
+ function toJson_FirestartrGithubOrganizationVariableSectionSpecContext(obj) {
327856
+ if (obj === undefined) {
327857
+ return undefined;
327858
+ }
327859
+ const result = {
327860
+ 'backend': toJson_FirestartrGithubOrganizationVariableSectionSpecContextBackend(obj.backend),
327861
+ 'provider': toJson_FirestartrGithubOrganizationVariableSectionSpecContextProvider(obj.provider),
327862
+ };
327863
+ // filter undefined values
327864
+ return Object.entries(result).reduce((r, i) => (i[1] === undefined) ? r : ({ ...r, [i[0]]: i[1] }), {});
327865
+ }
327866
+ /**
327867
+ * Converts an object of type 'FirestartrGithubOrganizationVariableSectionSpecFirestartr' to JSON representation.
327868
+ */
327869
+ /* eslint-disable max-len, @stylistic/max-len, quote-props, @stylistic/quote-props */
327870
+ function toJson_FirestartrGithubOrganizationVariableSectionSpecFirestartr(obj) {
327871
+ if (obj === undefined) {
327872
+ return undefined;
327873
+ }
327874
+ const result = {
327875
+ 'tfStateKey': obj.tfStateKey,
327876
+ };
327877
+ // filter undefined values
327878
+ return Object.entries(result).reduce((r, i) => (i[1] === undefined) ? r : ({ ...r, [i[0]]: i[1] }), {});
327879
+ }
327880
+ /**
327881
+ * Converts an object of type 'FirestartrGithubOrganizationVariableSectionSpecWriteConnectionSecretToRef' to JSON representation.
327882
+ */
327883
+ /* eslint-disable max-len, @stylistic/max-len, quote-props, @stylistic/quote-props */
327884
+ function toJson_FirestartrGithubOrganizationVariableSectionSpecWriteConnectionSecretToRef(obj) {
327885
+ if (obj === undefined) {
327886
+ return undefined;
327887
+ }
327888
+ const result = {
327889
+ 'name': obj.name,
327890
+ 'outputs': obj.outputs?.map(y => toJson_FirestartrGithubOrganizationVariableSectionSpecWriteConnectionSecretToRefOutputs(y)),
327891
+ };
327892
+ // filter undefined values
327893
+ return Object.entries(result).reduce((r, i) => (i[1] === undefined) ? r : ({ ...r, [i[0]]: i[1] }), {});
327894
+ }
327895
+ /* eslint-enable max-len, @stylistic/max-len, quote-props, @stylistic/quote-props */
327896
+ /**
327897
+ * Visibility of the variable
327898
+ *
327899
+ * @schema FirestartrGithubOrganizationVariableSectionSpecActionsVariablesVisibility
327900
+ */
327901
+ var FirestartrGithubOrganizationVariableSectionSpecActionsVariablesVisibility;
327902
+ (function (FirestartrGithubOrganizationVariableSectionSpecActionsVariablesVisibility) {
327903
+ /** all */
327904
+ FirestartrGithubOrganizationVariableSectionSpecActionsVariablesVisibility["ALL"] = "all";
327905
+ /** private */
327906
+ FirestartrGithubOrganizationVariableSectionSpecActionsVariablesVisibility["PRIVATE"] = "private";
327907
+ /** selected */
327908
+ FirestartrGithubOrganizationVariableSectionSpecActionsVariablesVisibility["SELECTED"] = "selected";
327909
+ })(FirestartrGithubOrganizationVariableSectionSpecActionsVariablesVisibility || (FirestartrGithubOrganizationVariableSectionSpecActionsVariablesVisibility = {}));
327910
+ /**
327911
+ * Converts an object of type 'FirestartrGithubOrganizationVariableSectionSpecContextBackend' to JSON representation.
327912
+ */
327913
+ /* eslint-disable max-len, @stylistic/max-len, quote-props, @stylistic/quote-props */
327914
+ function toJson_FirestartrGithubOrganizationVariableSectionSpecContextBackend(obj) {
327915
+ if (obj === undefined) {
327916
+ return undefined;
327917
+ }
327918
+ const result = {
327919
+ 'ref': toJson_FirestartrGithubOrganizationVariableSectionSpecContextBackendRef(obj.ref),
327920
+ };
327921
+ // filter undefined values
327922
+ return Object.entries(result).reduce((r, i) => (i[1] === undefined) ? r : ({ ...r, [i[0]]: i[1] }), {});
327923
+ }
327924
+ /**
327925
+ * Converts an object of type 'FirestartrGithubOrganizationVariableSectionSpecContextProvider' to JSON representation.
327926
+ */
327927
+ /* eslint-disable max-len, @stylistic/max-len, quote-props, @stylistic/quote-props */
327928
+ function toJson_FirestartrGithubOrganizationVariableSectionSpecContextProvider(obj) {
327929
+ if (obj === undefined) {
327930
+ return undefined;
327931
+ }
327932
+ const result = {
327933
+ 'ref': toJson_FirestartrGithubOrganizationVariableSectionSpecContextProviderRef(obj.ref),
327934
+ };
327935
+ // filter undefined values
327936
+ return Object.entries(result).reduce((r, i) => (i[1] === undefined) ? r : ({ ...r, [i[0]]: i[1] }), {});
327937
+ }
327938
+ /**
327939
+ * Converts an object of type 'FirestartrGithubOrganizationVariableSectionSpecWriteConnectionSecretToRefOutputs' to JSON representation.
327940
+ */
327941
+ /* eslint-disable max-len, @stylistic/max-len, quote-props, @stylistic/quote-props */
327942
+ function toJson_FirestartrGithubOrganizationVariableSectionSpecWriteConnectionSecretToRefOutputs(obj) {
327943
+ if (obj === undefined) {
327944
+ return undefined;
327945
+ }
327946
+ const result = {
327947
+ 'key': obj.key,
327948
+ };
327949
+ // filter undefined values
327950
+ return Object.entries(result).reduce((r, i) => (i[1] === undefined) ? r : ({ ...r, [i[0]]: i[1] }), {});
327951
+ }
327952
+ /**
327953
+ * Converts an object of type 'FirestartrGithubOrganizationVariableSectionSpecContextBackendRef' to JSON representation.
327954
+ */
327955
+ /* eslint-disable max-len, @stylistic/max-len, quote-props, @stylistic/quote-props */
327956
+ function toJson_FirestartrGithubOrganizationVariableSectionSpecContextBackendRef(obj) {
327957
+ if (obj === undefined) {
327958
+ return undefined;
327959
+ }
327960
+ const result = {
327961
+ 'kind': obj.kind,
327962
+ 'name': obj.name,
327963
+ };
327964
+ // filter undefined values
327965
+ return Object.entries(result).reduce((r, i) => (i[1] === undefined) ? r : ({ ...r, [i[0]]: i[1] }), {});
327966
+ }
327967
+ /**
327968
+ * Converts an object of type 'FirestartrGithubOrganizationVariableSectionSpecContextProviderRef' to JSON representation.
327969
+ */
327970
+ /* eslint-disable max-len, @stylistic/max-len, quote-props, @stylistic/quote-props */
327971
+ function toJson_FirestartrGithubOrganizationVariableSectionSpecContextProviderRef(obj) {
327972
+ if (obj === undefined) {
327973
+ return undefined;
327974
+ }
327975
+ const result = {
327976
+ 'kind': obj.kind,
327977
+ 'name': obj.name,
327978
+ };
327979
+ // filter undefined values
327980
+ return Object.entries(result).reduce((r, i) => (i[1] === undefined) ? r : ({ ...r, [i[0]]: i[1] }), {});
327981
+ }
327982
+ /* eslint-enable max-len, @stylistic/max-len, quote-props, @stylistic/quote-props */
327983
+ /**
327984
+ * @schema FirestartrGithubOrganizationVariableSectionSpecContextBackendRefKind
327985
+ */
327986
+ var FirestartrGithubOrganizationVariableSectionSpecContextBackendRefKind;
327987
+ (function (FirestartrGithubOrganizationVariableSectionSpecContextBackendRefKind) {
327988
+ /** FirestartrProviderConfig */
327989
+ FirestartrGithubOrganizationVariableSectionSpecContextBackendRefKind["FIRESTARTR_PROVIDER_CONFIG"] = "FirestartrProviderConfig";
327990
+ })(FirestartrGithubOrganizationVariableSectionSpecContextBackendRefKind || (FirestartrGithubOrganizationVariableSectionSpecContextBackendRefKind = {}));
327991
+ /**
327992
+ * @schema FirestartrGithubOrganizationVariableSectionSpecContextProviderRefKind
327993
+ */
327994
+ var FirestartrGithubOrganizationVariableSectionSpecContextProviderRefKind;
327995
+ (function (FirestartrGithubOrganizationVariableSectionSpecContextProviderRefKind) {
327996
+ /** FirestartrProviderConfig */
327997
+ FirestartrGithubOrganizationVariableSectionSpecContextProviderRefKind["FIRESTARTR_PROVIDER_CONFIG"] = "FirestartrProviderConfig";
327998
+ })(FirestartrGithubOrganizationVariableSectionSpecContextProviderRefKind || (FirestartrGithubOrganizationVariableSectionSpecContextProviderRefKind = {}));
327600
327999
  /**
327601
328000
  * A resource to handle GitHub Organization Webhooks
327602
328001
  *
@@ -330446,6 +330845,65 @@ class GithubOrgSettingsChart extends BaseGithubChart {
330446
330845
  }
330447
330846
  }
330448
330847
 
330848
+ ;// CONCATENATED MODULE: ../cdk8s_renderer/src/charts/github/orgVariableSectionChart.ts
330849
+
330850
+
330851
+
330852
+ class GithubOrgVariableSectionChart extends BaseGithubChart {
330853
+ template() {
330854
+ const claim = this.get('claim');
330855
+ const firestartrId = this.get('firestartrId');
330856
+ const githubProvider = claim.providers.github;
330857
+ const actionsVariables = (githubProvider.actions_variables || []).map((v) => {
330858
+ const entry = {
330859
+ name: v.name,
330860
+ value: v.value,
330861
+ visibility: v.visibility,
330862
+ };
330863
+ if (v.selected_repositories && v.selected_repositories.length > 0) {
330864
+ entry.selectedRepositories = v.selected_repositories.map((ref) => {
330865
+ const match = ref.match(/^component:(.+)$/);
330866
+ if (!match) {
330867
+ throw new ChartRenderError('OrgSettingsClaim', claim.name, `Invalid component ref "${ref}" in selected_repositories. Expected format: component:<name>`);
330868
+ }
330869
+ const componentName = match[1];
330870
+ const resolvedCr = this.refResolver('ComponentClaim', componentName);
330871
+ const org = resolvedCr?.spec?.org;
330872
+ const repoName = resolvedCr?.metadata?.annotations?.['firestartr.dev/external-name'] || resolvedCr?.metadata?.name?.replace(/-[0-9a-f-]{36}$/, '');
330873
+ if (!org || !repoName) {
330874
+ throw new ChartRenderError('OrgSettingsClaim', claim.name, `Referenced component "${componentName}" has no GitHub provider configured`);
330875
+ }
330876
+ return `${org}/${repoName}`;
330877
+ });
330878
+ }
330879
+ return entry;
330880
+ });
330881
+ const template = {
330882
+ metadata: {
330883
+ name: githubProvider.name,
330884
+ },
330885
+ spec: {
330886
+ org: githubProvider.org,
330887
+ actionsVariables,
330888
+ firestartr: {
330889
+ tfStateKey: firestartrId,
330890
+ },
330891
+ writeConnectionSecretToRef: {
330892
+ name: `firestartrgithuborganizationvariablesection-${githubProvider.name}-outputs`.toLowerCase(),
330893
+ outputs: [{ key: 'managed_variables' }, { key: 'variable_ids' }],
330894
+ },
330895
+ },
330896
+ };
330897
+ return JSON.parse(JSON.stringify(template));
330898
+ }
330899
+ gvk() {
330900
+ return FirestartrGithubOrganizationVariableSection.GVK;
330901
+ }
330902
+ instanceApiObject(template) {
330903
+ return new FirestartrGithubOrganizationVariableSection(this, template.metadata.name, template);
330904
+ }
330905
+ }
330906
+
330449
330907
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/charts/github/index.ts
330450
330908
 
330451
330909
 
@@ -330453,6 +330911,7 @@ class GithubOrgSettingsChart extends BaseGithubChart {
330453
330911
 
330454
330912
 
330455
330913
 
330914
+
330456
330915
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/charts/catalog/base.ts
330457
330916
 
330458
330917
  class BaseCatalogChart extends BaseChart {
@@ -331200,6 +331659,7 @@ class SecretsChart extends BaseSecretsChart {
331200
331659
  SecretsChart: SecretsChart,
331201
331660
  GithubOrgWebhookChart: GithubOrgWebhookChart,
331202
331661
  GithubOrgSettingsChart: GithubOrgSettingsChart,
331662
+ GithubOrgVariableSectionChart: GithubOrgVariableSectionChart,
331203
331663
  });
331204
331664
 
331205
331665
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/renderer/claims-render.ts
@@ -331244,13 +331704,23 @@ async function renderClaims(catalogScope, firestartrScope, data) {
331244
331704
  if (configuredProvider !== AllowedProviders.all.toString()) {
331245
331705
  providers = providers.filter((provider) => provider === configuredProvider);
331246
331706
  }
331247
- const previousCR = getPreviousCRfromClaim(claim, crs);
331707
+ const expectedKind = claim.kind === 'OrgSettingsClaim'
331708
+ ? 'FirestartrGithubOrganizationSettings'
331709
+ : undefined;
331710
+ const previousCR = getPreviousCRfromClaim(claim, crs, expectedKind);
331711
+ const variableSectionPreviousCR = claim.kind === 'OrgSettingsClaim'
331712
+ ? getPreviousCRfromClaim({ kind: claim.kind, name: `${claim.name}-variable-section` }, crs, 'FirestartrGithubOrganizationVariableSection')
331713
+ : false;
331248
331714
  const patches = await extractPatches(renderClaims[claimKey], previousCR);
331715
+ let variableSectionPatches = undefined;
331716
+ if (claim.kind === 'OrgSettingsClaim') {
331717
+ variableSectionPatches = await extractPatches(renderClaims[claimKey], variableSectionPreviousCR);
331718
+ }
331249
331719
  if (!previousCR) {
331250
331720
  logger.debug(`No CR found for claim ${claimKey}, it will be rendered from scratch`);
331251
331721
  }
331252
331722
  const claimPath = renderClaims[claimKey].claimPath;
331253
- const { firestartrEntity, extraCharts, catalogEntity } = await renderClaim(catalogScope, firestartrScope, claim, patches, previousCR, claimPath);
331723
+ const { firestartrEntity, extraCharts, catalogEntity } = await renderClaim(catalogScope, firestartrScope, claim, patches, previousCR, claimPath, variableSectionPreviousCR, variableSectionPatches);
331254
331724
  if (catalogEntity) {
331255
331725
  result[`${catalogEntity.kind}-${catalogEntity.metadata.name}`] =
331256
331726
  catalogEntity.toJson();
@@ -331279,7 +331749,7 @@ async function renderClaims(catalogScope, firestartrScope, data) {
331279
331749
  }
331280
331750
  return result;
331281
331751
  }
331282
- async function renderClaim(catalogScope, firestartrScope, claim, patches, previousCR = null, claimPath) {
331752
+ async function renderClaim(catalogScope, firestartrScope, claim, patches, previousCR = null, claimPath, variableSectionPreviousCR = false, variableSectionPatches) {
331283
331753
  let catalogEntity = undefined;
331284
331754
  let firestartrEntity = undefined;
331285
331755
  const extraCharts = [];
@@ -331427,6 +331897,27 @@ async function renderClaim(catalogScope, firestartrScope, claim, patches, previo
331427
331897
  case 'OrgSettingsClaim':
331428
331898
  if (loadGithub) {
331429
331899
  firestartrEntity = new charts.GithubOrgSettingsChart(firestartrScope, `github-${chartId}`, firestartrId, claim, renderPatches);
331900
+ const variableSectionFirestartrId = variableSectionPreviousCR
331901
+ ? variableSectionPreviousCR.spec?.firestartr?.tfStateKey
331902
+ : firestartrId
331903
+ ? `${firestartrId}-variables`
331904
+ : null;
331905
+ const vsRenderPatches = variableSectionPatches
331906
+ ? variableSectionPatches.filter((patch) => !patch.isPostPatch)
331907
+ : renderPatches;
331908
+ const vsPostPatches = variableSectionPatches
331909
+ ? variableSectionPatches.filter((patch) => patch.isPostPatch)
331910
+ : postPatches;
331911
+ const variableSectionChart = new charts.GithubOrgVariableSectionChart(firestartrScope, `github-variables-${chartId}`, variableSectionFirestartrId, claim, vsRenderPatches);
331912
+ await variableSectionChart.render();
331913
+ const variableSectionObject = await variableSectionChart.postRenderer(vsPostPatches);
331914
+ extraCharts.push({
331915
+ claim: {
331916
+ kind: claim.kind,
331917
+ name: `${claim.name}-variable-section`,
331918
+ },
331919
+ chart: variableSectionObject,
331920
+ });
331430
331921
  }
331431
331922
  break;
331432
331923
  default:
@@ -331486,12 +331977,16 @@ function renameVariantCrFiles(outputDir, renderedMap) {
331486
331977
 
331487
331978
  const IS_COMPONENT_CLAIM_REF = new RegExp(/^ComponentClaim-/);
331488
331979
  const IS_TF_WORKSPACE = new RegExp(/^TFWorkspaceClaim-/);
331980
+ const IS_ORG_SETTINGS_CLAIM = new RegExp(/^OrgSettingsClaim-/);
331981
+ const COMPONENT_REF_PATTERN = /^component:(.+)$/;
331489
331982
  function validateSubReferences(renderClaims) {
331490
331983
  for (const ref of Object.keys(renderClaims)) {
331491
331984
  if (IS_COMPONENT_CLAIM_REF.test(ref))
331492
331985
  validateClaimsSecretsRefs(ref, renderClaims);
331493
331986
  else if (IS_TF_WORKSPACE.test(ref))
331494
331987
  validateTFClaimsSecretsRefs(ref, renderClaims);
331988
+ else if (IS_ORG_SETTINGS_CLAIM.test(ref))
331989
+ validateOrgSettingsComponentRefs(ref, renderClaims);
331495
331990
  }
331496
331991
  }
331497
331992
  function validateTFClaimsSecretsRefs(ref, renderClaims) {
@@ -331543,6 +332038,32 @@ function searchSecretKey(secretClaim, key) {
331543
332038
  }
331544
332039
  return found;
331545
332040
  }
332041
+ function validateOrgSettingsComponentRefs(ref, renderClaims) {
332042
+ const claim = renderClaims[ref].claim;
332043
+ validateActionsVariablesSelectedRepositories(claim, renderClaims);
332044
+ }
332045
+ function validateActionsVariablesSelectedRepositories(claim, renderClaims) {
332046
+ const actionsVariables = claim?.providers?.github?.actions_variables;
332047
+ if (!Array.isArray(actionsVariables))
332048
+ return;
332049
+ for (const variable of actionsVariables) {
332050
+ if (variable.visibility !== 'selected')
332051
+ continue;
332052
+ const selectedRepos = variable.selected_repositories;
332053
+ if (!Array.isArray(selectedRepos) || selectedRepos.length === 0)
332054
+ continue;
332055
+ for (const ref of selectedRepos) {
332056
+ const match = ref.match(COMPONENT_REF_PATTERN);
332057
+ if (!match)
332058
+ continue;
332059
+ const componentName = match[1];
332060
+ const expectedKey = `ComponentClaim-${componentName}`;
332061
+ if (!renderClaims[expectedKey]) {
332062
+ throw new Error(`CrossReference error: OrgSettingsClaim/${claim.name} references a non-existent component "${componentName}" in actions_variables.${variable.name}.selected_repositories`);
332063
+ }
332064
+ }
332065
+ }
332066
+ }
331546
332067
 
331547
332068
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/validations/componentPagesPath.ts
331548
332069
  /**
@@ -331591,6 +332112,66 @@ function validateGithubOrgSettingsSingleton(crs) {
331591
332112
  }
331592
332113
  }
331593
332114
 
332115
+ ;// CONCATENATED MODULE: ../cdk8s_renderer/src/validations/githubOrgVariableSection.ts
332116
+ const GITHUB_ORG_VARIABLE_SECTION_KIND = 'FirestartrGithubOrganizationVariableSection';
332117
+ const githubOrgVariableSection_FIRESTARTR_CLAIM_REF_ANNOTATION = 'firestartr.dev/claim-ref';
332118
+ const githubOrgVariableSection_CLAIM_REF_LABEL = 'claim-ref';
332119
+ function githubOrgVariableSection_formatResourceRef(name, claimRef) {
332120
+ return claimRef ? `${name} (claim: ${claimRef})` : name;
332121
+ }
332122
+ function validateGithubOrgVariableSectionSingleton(crs) {
332123
+ const refsByOrg = new Map();
332124
+ const seenClaimRefs = new Map();
332125
+ for (const crKey of Object.keys(crs)) {
332126
+ const cr = crs[crKey];
332127
+ if (cr.kind !== GITHUB_ORG_VARIABLE_SECTION_KIND)
332128
+ continue;
332129
+ const org = cr.spec?.org;
332130
+ if (typeof org !== 'string' || !org)
332131
+ continue;
332132
+ const name = cr.metadata?.name || crKey;
332133
+ const claimRef = cr.metadata?.annotations?.[githubOrgVariableSection_FIRESTARTR_CLAIM_REF_ANNOTATION] ||
332134
+ cr.metadata?.labels?.[githubOrgVariableSection_CLAIM_REF_LABEL];
332135
+ const normalizedOrg = org.toLowerCase();
332136
+ if (claimRef) {
332137
+ const seen = seenClaimRefs.get(normalizedOrg) || new Set();
332138
+ if (seen.has(claimRef))
332139
+ continue;
332140
+ seen.add(claimRef);
332141
+ seenClaimRefs.set(normalizedOrg, seen);
332142
+ }
332143
+ const refs = refsByOrg.get(normalizedOrg) || [];
332144
+ refs.push(githubOrgVariableSection_formatResourceRef(name, claimRef));
332145
+ refsByOrg.set(normalizedOrg, refs);
332146
+ }
332147
+ for (const [org, refs] of refsByOrg.entries()) {
332148
+ if (refs.length < 2)
332149
+ continue;
332150
+ throw new Error(`Duplicate ${GITHUB_ORG_VARIABLE_SECTION_KIND} resources found for GitHub organization "${org}": ${refs.join(', ')}`);
332151
+ }
332152
+ }
332153
+ function validateActionsVariablesUniqueness(crs) {
332154
+ for (const crKey of Object.keys(crs)) {
332155
+ const cr = crs[crKey];
332156
+ if (cr.kind !== GITHUB_ORG_VARIABLE_SECTION_KIND)
332157
+ continue;
332158
+ const actionsVariables = cr.spec?.actionsVariables;
332159
+ if (!Array.isArray(actionsVariables))
332160
+ continue;
332161
+ const names = new Set();
332162
+ for (const variable of actionsVariables) {
332163
+ const varName = variable?.name;
332164
+ if (!varName)
332165
+ continue;
332166
+ if (names.has(varName)) {
332167
+ const org = cr.spec?.org || 'unknown';
332168
+ throw new Error(`Duplicate action variable name "${varName}" found in ${GITHUB_ORG_VARIABLE_SECTION_KIND} for organization "${org}"`);
332169
+ }
332170
+ names.add(varName);
332171
+ }
332172
+ }
332173
+ }
332174
+
331594
332175
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/renderer/renderer.ts
331595
332176
 
331596
332177
 
@@ -331601,6 +332182,7 @@ function validateGithubOrgSettingsSingleton(crs) {
331601
332182
 
331602
332183
 
331603
332184
 
332185
+
331604
332186
  /*
331605
332187
  * Function called when rendering but not importing
331606
332188
  *
@@ -331624,6 +332206,8 @@ async function renderer_render(catalogScope, firestartrScope, claimList) {
331624
332206
  validateComponentPagesPath(data.renderClaims);
331625
332207
  validateTfStateKeyUniqueness(result);
331626
332208
  validateGithubOrgSettingsSingleton(fullCrSet);
332209
+ validateGithubOrgVariableSectionSingleton(fullCrSet);
332210
+ validateActionsVariablesUniqueness(result);
331627
332211
  validateCrSizes(result);
331628
332212
  validatePermissionsUniqueness(result);
331629
332213
  }
@@ -333955,6 +334539,7 @@ const kindPluralMap = {
333955
334539
  terraformmodules: 'FirestartrTerraformModule',
333956
334540
  githuborgwebhooks: 'FirestartrGithubOrgWebhook',
333957
334541
  githuborganizationsettings: 'FirestartrGithubOrganizationSettings',
334542
+ githuborganizationvariablesections: 'FirestartrGithubOrganizationVariableSection',
333958
334543
  terraformworkspaces: 'FirestartrTerraformWorkspace',
333959
334544
  terraformworkspaceplans: 'FirestartrTerraformWorkspacePlan',
333960
334545
  providerconfigs: 'FirestartrProviderConfig',
@@ -335932,6 +336517,7 @@ const kindsWithFinalizer = [
335932
336517
  'FirestartrGithubRepositoryFeature',
335933
336518
  'FirestartrGithubOrgWebhook',
335934
336519
  'FirestartrGithubOrganizationSettings',
336520
+ 'FirestartrGithubOrganizationVariableSection',
335935
336521
  'FirestartrGithubRepositorySecretsSection',
335936
336522
  ];
335937
336523
  const kindsWithDependants = [
@@ -342473,6 +343059,11 @@ const MODULES = {
342473
343059
  // github-org-settings-v0.1.0
342474
343060
  ref: 'c30c5dfdaddf2bca9e966a726d45970c98576e9e',
342475
343061
  },
343062
+ FirestartrGithubOrganizationVariableSection: {
343063
+ module: 'git::https://github.com/prefapp/tfm.git//modules/github-org-variables-section',
343064
+ // github-org-variables-section-v0.1.0
343065
+ ref: 'fb9c01d0a1e03e5134479da13d0faf55891dfedf',
343066
+ },
342476
343067
  };
342477
343068
  function getFirestartrDefaultTFM(kind) {
342478
343069
  if (kind in MODULES) {
@@ -344275,6 +344866,94 @@ class EntityGHOrgSettings extends base_Entity {
344275
344866
  }
344276
344867
  }
344277
344868
 
344869
+ ;// CONCATENATED MODULE: ../gh_provisioner/src/entities/ghorgvarsection/index.ts
344870
+
344871
+
344872
+
344873
+ class EntityGHOrgVarsSection extends base_Entity {
344874
+ constructor(artifact) {
344875
+ super(artifact, {
344876
+ config: {
344877
+ variables: {},
344878
+ },
344879
+ });
344880
+ }
344881
+ async loadResources(tfOp) {
344882
+ gh_provisioner_src_logger.info(`[gh-provisioner] running ${tfOp} on ${this.k8sId}`);
344883
+ try {
344884
+ const cr = this.cr;
344885
+ const actionsVariables = cr.spec.actionsVariables || [];
344886
+ const variables = {};
344887
+ for (const v of actionsVariables) {
344888
+ const entry = {
344889
+ value: v.value,
344890
+ visibility: v.visibility,
344891
+ };
344892
+ if (v.visibility === 'selected' && v.selectedRepositories) {
344893
+ entry.selectedRepositoryIds = v.selectedRepositories;
344894
+ }
344895
+ variables[v.name] = entry;
344896
+ }
344897
+ this.patchData({
344898
+ op: PatchOperations.replace,
344899
+ path: '/config/variables',
344900
+ value: variables,
344901
+ });
344902
+ if (tfOp === 'apply') {
344903
+ await this.adoptVariablesIfNeeded(actionsVariables);
344904
+ }
344905
+ gh_provisioner_src_logger.debug(`[gh-provisioner] ${this.k8sId} loaded its data`);
344906
+ }
344907
+ catch (err) {
344908
+ const message = err instanceof Error ? err.message : String(err);
344909
+ gh_provisioner_src_logger.error(`[gh-provisioner] ${this.k8sId} error loading resources: ${message}`);
344910
+ throw new Error(`[gh-provisioner] ${this.k8sId} error loading resources: ${message}`);
344911
+ }
344912
+ }
344913
+ async adoptVariablesIfNeeded(declaredVars) {
344914
+ const cr = this.cr;
344915
+ const managedVariables = this.cr.fResolveSelfOutputs('managed_variables') || [];
344916
+ const declaredNames = declaredVars.map((v) => v.name);
344917
+ const newToModule = declaredNames.filter((name) => !managedVariables.includes(name));
344918
+ if (newToModule.length === 0) {
344919
+ gh_provisioner_src_logger.debug(`[gh-provisioner] ${this.k8sId} all declared variables are already managed, no adoption needed`);
344920
+ return;
344921
+ }
344922
+ if (managedVariables.length === 0) {
344923
+ gh_provisioner_src_logger.info(`[gh-provisioner] ${this.k8sId} no managed_variables output — first reconciliation, treating all ${newToModule.length} declared variable(s) as new to module`);
344924
+ }
344925
+ for (const varName of newToModule) {
344926
+ try {
344927
+ await this.runWithGithubProvider(async () => {
344928
+ await github["default"].org.getOrgVariable(cr.spec.org, varName);
344929
+ });
344930
+ gh_provisioner_src_logger.info(`[gh-provisioner] ${this.k8sId} adopting pre-existing variable '${varName}' on GitHub org '${cr.spec.org}'`);
344931
+ this.patchImportData({
344932
+ op: PatchOperations.add,
344933
+ path: '/imports/-',
344934
+ value: {
344935
+ to: `github_actions_organization_variable.this["${varName}"]`,
344936
+ id: varName,
344937
+ },
344938
+ });
344939
+ }
344940
+ catch (err) {
344941
+ if (err && err.status === 404) {
344942
+ gh_provisioner_src_logger.info(`[gh-provisioner] ${this.k8sId} variable '${varName}' not found on GitHub org '${cr.spec.org}' — will be created by TFM`);
344943
+ }
344944
+ else if (err && (err.status === 401 || err.status === 403)) {
344945
+ gh_provisioner_src_logger.warn(`[gh-provisioner] ${this.k8sId} token lacks scope to check variable '${varName}' on org '${cr.spec.org}' — skipping adoption gracefully`);
344946
+ }
344947
+ else {
344948
+ gh_provisioner_src_logger.error(`[gh-provisioner] ${this.k8sId} unexpected error checking variable '${varName}' on org '${cr.spec.org}': ${err instanceof Error ? err.message : String(err)}`);
344949
+ }
344950
+ }
344951
+ }
344952
+ }
344953
+ async postProvision(tfOp) { }
344954
+ async loadAddressesToImport() { }
344955
+ }
344956
+
344278
344957
  ;// CONCATENATED MODULE: ../gh_provisioner/src/entities/ghorgwebhook/index.ts
344279
344958
 
344280
344959
 
@@ -344351,6 +345030,7 @@ class EntityGHOrgWebHook extends base_Entity {
344351
345030
 
344352
345031
 
344353
345032
 
345033
+
344354
345034
  function entities_getEntity(cr) {
344355
345035
  const entityClass = getEntityClass(cr.kind);
344356
345036
  return new entityClass(cr);
@@ -344371,6 +345051,8 @@ function getEntityClass(kind) {
344371
345051
  return EntityGHOrgWebHook;
344372
345052
  case 'FirestartrGithubOrganizationSettings':
344373
345053
  return EntityGHOrgSettings;
345054
+ case 'FirestartrGithubOrganizationVariableSection':
345055
+ return EntityGHOrgVarsSection;
344374
345056
  default:
344375
345057
  throw new Error(`kind ${kind} has no entity associated`);
344376
345058
  }
@@ -344784,6 +345466,7 @@ const GITHUB_RESOURCE_KINDS = [
344784
345466
  'FirestartrGithubRepositorySecretsSection',
344785
345467
  'FirestartrGithubOrgWebhook',
344786
345468
  'FirestartrGithubOrganizationSettings',
345469
+ 'FirestartrGithubOrganizationVariableSection',
344787
345470
  ];
344788
345471
  const GITHUB_REPOSITORY_DEPENDENT_KINDS = [
344789
345472
  'FirestartrGithubRepositoryFeature',
@@ -346042,6 +346725,9 @@ function isObserveModeActive() {
346042
346725
  function runOperator(opts) {
346043
346726
  const { ignoreLease, dummyExec, namespace, kindList, importMode, importModeSkipPlan, observeMode, withMetrics, } = opts;
346044
346727
  const implementedKinds = filterImplementedKinds(kindList);
346728
+ operator_src_logger.info(`operator kindList: ${JSON.stringify(kindList)}`);
346729
+ operator_src_logger.info(`operator implementedKinds: ${JSON.stringify(implementedKinds)}`);
346730
+ operator_src_logger.info(`operator ignoring kinds: ${JSON.stringify(kindList.filter((k) => !implementedKinds.includes(k)))}`);
346045
346731
  if (observeMode)
346046
346732
  observeModeActive = true;
346047
346733
  if (withMetrics)
@@ -346115,6 +346801,7 @@ const provisionImplementations = {
346115
346801
  githubmemberships: process_operation_processOperation,
346116
346802
  githuborgwebhooks: process_operation_processOperation,
346117
346803
  githuborganizationsettings: process_operation_processOperation,
346804
+ githuborganizationvariablesections: process_operation_processOperation,
346118
346805
  fsdummiesa: processFirestartrDummies,
346119
346806
  fsdummiesb: processFirestartrDummies,
346120
346807
  fsdummiesc: processFirestartrDummies,
@@ -524933,7 +525620,7 @@ const crsStatusSubcommand = {
524933
525620
  };
524934
525621
 
524935
525622
  ;// CONCATENATED MODULE: ./package.json
524936
- const package_namespaceObject = {"i8":"2.10.0"};
525623
+ const package_namespaceObject = JSON.parse('{"i8":"2.11.0-objects-in-patches"}');
524937
525624
  ;// CONCATENATED MODULE: ../../package.json
524938
525625
  const package_namespaceObject_1 = {"i8":"2.10.0"};
524939
525626
  // EXTERNAL MODULE: ../../node_modules/semver/index.js