@firestartr/cli 1.53.0-snapshot-2 → 1.53.0-snapshot-4

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
@@ -354119,6 +354119,7 @@ async function getUserInfo(name) {
354119
354119
  });
354120
354120
 
354121
354121
  ;// CONCATENATED MODULE: ../github/src/sticky_comment.ts
354122
+
354122
354123
  const locks = new Map();
354123
354124
  async function withLock(key, fn) {
354124
354125
  const prev = locks.get(key) ?? Promise.resolve();
@@ -354152,6 +354153,7 @@ async function readStickyIdFromPrBody(octokit, owner, repo, pr, kind) {
354152
354153
  const prResp = await octokit.rest.pulls.get({ owner, repo, pull_number: pr });
354153
354154
  const body = prResp.data?.body ?? '';
354154
354155
  const m = body.match(prIdRegex(kind));
354156
+ github_src_logger.info(`readStickyIdFromPrBody: owner=${owner} repo=${repo} pr=${pr} kind=${kind} => id=${m ? m[1] : 'undefined'}`);
354155
354157
  return m ? Number(m[1]) : undefined;
354156
354158
  }
354157
354159
  async function writeStickyIdToPrBody(octokit, owner, repo, pr, kind, id) {
@@ -354159,6 +354161,7 @@ async function writeStickyIdToPrBody(octokit, owner, repo, pr, kind, id) {
354159
354161
  const body = get.data?.body ?? '';
354160
354162
  const rx = prIdRegex(kind);
354161
354163
  const marker = prIdMarker(kind, id);
354164
+ github_src_logger.info(`writeStickyIdToPrBody: owner=${owner} repo=${repo} pr=${pr} kind=${kind} id=${id}`);
354162
354165
  const next = rx.test(body)
354163
354166
  ? body.replace(rx, marker)
354164
354167
  : body
@@ -354181,6 +354184,7 @@ async function upsertStickyComment(octokit, params) {
354181
354184
  // 1) PR-body registry fast path
354182
354185
  const idFromPr = await readStickyIdFromPrBody(octokit, owner, repo, pullNumber, kind);
354183
354186
  if (idFromPr) {
354187
+ github_src_logger.info(`upsertStickyComment: found existing comment ID ${idFromPr} from PR body for kind=${kind}`);
354184
354188
  await octokit.rest.issues.updateComment({
354185
354189
  owner,
354186
354190
  repo,
@@ -354189,7 +354193,7 @@ async function upsertStickyComment(octokit, params) {
354189
354193
  });
354190
354194
  return;
354191
354195
  }
354192
- // 2) Try to find an existing comment by kind marker
354196
+ // 2) Try to find existing comments by kind marker
354193
354197
  try {
354194
354198
  const all = await octokit.paginate(octokit.rest.issues.listComments, {
354195
354199
  owner,
@@ -354198,20 +354202,42 @@ async function upsertStickyComment(octokit, params) {
354198
354202
  per_page: 100,
354199
354203
  });
354200
354204
  const marker = bodyMarker(kind);
354201
- const hit = all.find((c) => typeof c.body === 'string' && c.body.includes(marker));
354202
- if (hit?.id) {
354205
+ const matches = all.filter((c) => typeof c.body === 'string' && c.body.includes(marker));
354206
+ if (matches.length > 0) {
354207
+ // Sort by created_at to identify the oldest comment
354208
+ const sorted = matches.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
354209
+ const primaryComment = sorted[0];
354210
+ // Update the primary (oldest) comment
354211
+ github_src_logger.info(`upsertStickyComment: found existing comment ID ${primaryComment.id} by marker for kind=${kind}, updating it and deleting ${sorted.length - 1} duplicates`);
354203
354212
  await octokit.rest.issues.updateComment({
354204
354213
  owner,
354205
354214
  repo,
354206
- comment_id: hit.id,
354215
+ comment_id: primaryComment.id,
354207
354216
  body: fullBody,
354208
354217
  });
354209
- await writeStickyIdToPrBody(octokit, owner, repo, pullNumber, kind, hit.id);
354218
+ // Store its ID in PR body
354219
+ await writeStickyIdToPrBody(octokit, owner, repo, pullNumber, kind, primaryComment.id);
354220
+ // Delete all duplicate comments (from index 1 onwards)
354221
+ for (let i = 1; i < sorted.length; i++) {
354222
+ github_src_logger.info(`upsertStickyComment: deleting duplicate comment ID ${sorted[i].id} for kind=${kind}`);
354223
+ try {
354224
+ await octokit.rest.issues.deleteComment({
354225
+ owner,
354226
+ repo,
354227
+ comment_id: sorted[i].id,
354228
+ });
354229
+ }
354230
+ catch (deleteErr) {
354231
+ // Log but continue deleting others
354232
+ github_src_logger.warn(`Failed to delete duplicate comment ${sorted[i].id} for ${kind}: ${deleteErr}`);
354233
+ }
354234
+ }
354210
354235
  return;
354211
354236
  }
354212
354237
  }
354213
- catch {
354238
+ catch (err) {
354214
354239
  // if paginate/listComments not available, we'll fall back to creating
354240
+ github_src_logger.warn(`Failed to list comments for kind=${kind} on PR #${pullNumber}: ${err}`);
354215
354241
  }
354216
354242
  // 3) Create new comment and register
354217
354243
  const created = await octokit.rest.issues.createComment({
@@ -355535,9 +355561,32 @@ class GlobalDefault extends DefaultSection {
355535
355561
  }
355536
355562
  }
355537
355563
 
355564
+ ;// CONCATENATED MODULE: ../cdk8s_renderer/src/defaults/oneWayDefs.ts
355565
+ // this function ensures that there are some specs that have to be defined
355566
+ // anew and cannot be fed back from the previous CR
355567
+ //
355568
+ // The only definition is the one in the claim-level and the resulting rendered CR
355569
+ // Thus it performs a nullify of the designed patches
355570
+
355571
+
355572
+ const ONE_WAY_DEFINITIONS = ['/spec/vars'];
355573
+ function applyOneWayDefs(crSpecs) {
355574
+ const crSpecsClone = JSON.parse(JSON.stringify(crSpecs));
355575
+ for (const defPath of ONE_WAY_DEFINITIONS) {
355576
+ if (hasDeepPath(crSpecs, defPath)) {
355577
+ fast_json_patch_default().applyPatch(crSpecsClone, [{ op: 'remove', path: defPath }]);
355578
+ }
355579
+ }
355580
+ return crSpecsClone;
355581
+ }
355582
+ function hasDeepPath(data, deepPath) {
355583
+ return lodash_default().has(data, deepPath.replace(/\//g, '.').replace(/^\./, ''));
355584
+ }
355585
+
355538
355586
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/defaults/initializer.ts
355539
355587
 
355540
355588
 
355589
+
355541
355590
  /*
355542
355591
  * This class extends DefaultSection and recieves arbitrary CR data to
355543
355592
  * create a patch object (CustomResourceDefaultsPatch) capable of:
@@ -355608,10 +355657,11 @@ class InitializerDefault extends DefaultSection {
355608
355657
  let patchData = {};
355609
355658
  if (previousCR?.spec) {
355610
355659
  // This code add fields present in this.data but missing in
355611
- // previousCR.spec into the latter
355612
- const fieldsToAddPatches = fast_json_patch_default().compare(previousCR.spec, this.data)
355660
+ // previousCR.spec into the later
355661
+ const previousCRCurated = applyOneWayDefs(previousCR);
355662
+ const fieldsToAddPatches = fast_json_patch_default().compare(previousCRCurated.spec, this.data)
355613
355663
  .filter((op) => op.op === 'add');
355614
- patchData = fast_json_patch_default().applyPatch(previousCR.spec, fieldsToAddPatches).newDocument;
355664
+ patchData = fast_json_patch_default().applyPatch(previousCRCurated.spec, fieldsToAddPatches).newDocument;
355615
355665
  }
355616
355666
  else {
355617
355667
  patchData = this.data;
@@ -358900,7 +358950,7 @@ function applyBlockAwareDefaults(claim, defaultClaim) {
358900
358950
  // we remove the blocks entirely of the claim
358901
358951
  // to achieve an add copy
358902
358952
  for (const defaultBlockPath of defaultBlocksPaths) {
358903
- if (hasDeepPath(claimClone, defaultBlockPath) !== true)
358953
+ if (claimsDefaulter_hasDeepPath(claimClone, defaultBlockPath) !== true)
358904
358954
  continue;
358905
358955
  const originalValue = fast_json_patch_default().getValueByPointer(claimClone, defaultBlockPath);
358906
358956
  if (originalValue) {
@@ -358928,7 +358978,7 @@ function applyBlockAwareDefaults(claim, defaultClaim) {
358928
358978
  });
358929
358979
  return fast_json_patch_default().applyPatch(claimClone, jsonPatchOps).newDocument;
358930
358980
  }
358931
- function hasDeepPath(data, deepPath) {
358981
+ function claimsDefaulter_hasDeepPath(data, deepPath) {
358932
358982
  return lodash_default().has(data, deepPath.replace(/\//g, '.').replace(/^\./, ''));
358933
358983
  }
358934
358984
 
@@ -359440,6 +359490,9 @@ var ajv_default = /*#__PURE__*/__nccwpck_require__.n(dist_ajv);
359440
359490
  upgradable: {
359441
359491
  type: 'boolean',
359442
359492
  },
359493
+ target_branch: {
359494
+ type: 'string',
359495
+ },
359443
359496
  },
359444
359497
  required: ['dest', 'src'],
359445
359498
  title: 'File',
@@ -360344,6 +360397,7 @@ function render(featurePath, featureRenderPath, entity, firestartrConfig = {}, f
360344
360397
  // For now let's keep upgradeable flag for backward compatibility
360345
360398
  // by default it's false
360346
360399
  const userManaged = file.user_managed ?? file.upgradeable ?? false;
360400
+ const targetBranch = file.target_branch ?? '';
360347
360401
  features_renderer_src_logger.debug(`Rendering ${src} to ${dest}`);
360348
360402
  // render the content of the file
360349
360403
  const content = addTraceability(context, src, renderContent(external_fs_default().readFileSync(external_path_default().join(featurePath, 'templates', src)).toString(), context));
@@ -360356,6 +360410,7 @@ function render(featurePath, featureRenderPath, entity, firestartrConfig = {}, f
360356
360410
  localPath: destFilePath,
360357
360411
  repoPath: dest,
360358
360412
  userManaged: userManaged,
360413
+ targetBranch,
360359
360414
  });
360360
360415
  output.patches = context.config.patches;
360361
360416
  // Not used anymore
@@ -362519,6 +362574,7 @@ function toJson_FirestartrGithubRepositoryFeatureSpecFiles(obj) {
362519
362574
  'path': obj.path,
362520
362575
  'userManaged': obj.userManaged,
362521
362576
  'content': obj.content,
362577
+ 'targetBranch': obj.targetBranch,
362522
362578
  };
362523
362579
  // filter undefined values
362524
362580
  return Object.entries(result).reduce((r, i) => (i[1] === undefined) ? r : ({ ...r, [i[0]]: i[1] }), {});
@@ -363964,7 +364020,12 @@ class FeatureRepoChart extends BaseGithubChart {
363964
364020
  version: claim.feature.version,
363965
364021
  org: claim.org,
363966
364022
  repositoryTarget,
363967
- files: claim.files,
364023
+ files: claim.files.map((file) => {
364024
+ return {
364025
+ ...file,
364026
+ targetBranch: file.targetBranch,
364027
+ };
364028
+ }),
363968
364029
  firestartr: {
363969
364030
  tfStateKey: claim.firestartr.tfStateKey,
363970
364031
  },
@@ -364196,10 +364257,10 @@ class GithubRepositoryChart extends BaseGithubChart {
364196
364257
  this.set('features', features);
364197
364258
  }
364198
364259
  async postRenderSecretsSection(cr) {
364199
- const areThereSecrets = this.get('claim').providers?.github?.secrets ?? false;
364200
- if (!areThereSecrets) {
364201
- return;
364202
- }
364260
+ // we always render the secretsSection
364261
+ // even if it is empty because we don't have a proper
364262
+ // way to know if there were secrets and now they have been
364263
+ // erased
364203
364264
  const secretsSectionChart = await (await new RepoSecretsSectionChart(this, 'secrets-section', cr.spec.firestartr.tfStateKey, this.get('claim'), [], cr).render()).postRenderer([]);
364204
364265
  this.set('secrets_section', {
364205
364266
  claim: {
@@ -367305,7 +367366,7 @@ async function writePlanInGithubPR(prUrl, planText) {
367305
367366
  ${planText}
367306
367367
  \`\`\`
367307
367368
  `;
367308
- await github_0.pulls.commentInPR(message, +pr_number, repo, owner, 'logs');
367369
+ await github_0.pulls.commentInPR(message, +pr_number, repo, owner, 'terraform:plan');
367309
367370
  }
367310
367371
  catch (err) {
367311
367372
  operator_src_logger.error(`writePlanInGithubPR: Cannot write plan in PR: ${err}`);
@@ -369306,13 +369367,16 @@ function provisionFeatureFiles(scope, feature) {
369306
369367
  provisioner_src_logger.info(`Provisioning feature ${feature.spec.type} for ${feature.spec.repositoryTarget.name}`);
369307
369368
  provisioner_src_logger.debug('Feature output json: %O', feature);
369308
369369
  if (feature.spec.files) {
369370
+ const defaultBranchName = feature.spec.repositoryTarget.branch;
369309
369371
  for (const file of feature.spec.files) {
369310
369372
  provisioner_src_logger.debug('Provisioning file %O', file);
369311
369373
  const lifecycleArg = file.userManaged
369312
369374
  ? { ignoreChanges: ['content'] }
369313
369375
  : {};
369314
369376
  const repoConfig = {
369315
- branch: feature.spec.repositoryTarget.branch,
369377
+ branch: file.targetBranch.length === 0
369378
+ ? defaultBranchName
369379
+ : file.targetBranch,
369316
369380
  commitMessage: `feat: ${feature.spec.type} ${feature.spec.version}`,
369317
369381
  content: cdktf_lib.Fn.base64decode(file.content),
369318
369382
  file: file.path,
@@ -370796,9 +370860,10 @@ if (process.env.RUN_PROVISIONER) {
370796
370860
  ;// CONCATENATED MODULE: ../operator/src/user-feedback-ops/user-feedback-ops.ts
370797
370861
 
370798
370862
 
370863
+ const LAST_STATE_PR_ANNOTATION = 'firestartr.dev/last-state-pr';
370799
370864
  async function tryPublishApply(item, planOutput, kind) {
370800
370865
  try {
370801
- if (!('firestartr.dev/last-state-pr' in item.metadata.annotations)) {
370866
+ if (!(LAST_STATE_PR_ANNOTATION in item.metadata.annotations)) {
370802
370867
  operator_src_logger.debug(`The user feedback for the '${kind}/${item.metadata.name}' apply operation could not be published because the last state was not found.`);
370803
370868
  return;
370804
370869
  }
@@ -370842,7 +370907,7 @@ ${commentContent}
370842
370907
  \`\`\`
370843
370908
  </details>`;
370844
370909
  operator_src_logger.debug(`The user feedback for item '${item.kind}/${item.metadata.name}' is being published as a comment on pull request '${lastPr.number}' for repository '${repo}' in organization '${org}'.`);
370845
- await github_0.pulls.commentInPR(comment, lastPr.number, repo, org, 'logs');
370910
+ await github_0.pulls.commentInPR(comment, lastPr.number, repo, org, 'tfworkspace:destroy');
370846
370911
  operator_src_logger.debug(`The user feedback for the '${item.kind}/${item.metadata.name}' destroy operation is being published as a comment on pull request '${lastPr.number}'.`);
370847
370912
  currentCommentNo += 1;
370848
370913
  }
@@ -370868,7 +370933,7 @@ async function publishApply(item, applyOutput, kind) {
370868
370933
  ${commentContent}
370869
370934
  \`\`\`
370870
370935
  </details>`;
370871
- await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org, 'logs');
370936
+ await github_0.pulls.commentInPR(comment, prNumber, repo, org, 'apply');
370872
370937
  currentCommentNo += 1;
370873
370938
  }
370874
370939
  }
@@ -370889,8 +370954,10 @@ function tryCreateErrorSummary(title, errorMsg) {
370889
370954
  return `Error when getting error summary: ${e}`;
370890
370955
  }
370891
370956
  }
370892
- function extractPrInfo(item) {
370893
- const prInfo = item.metadata.annotations['firestartr.dev/last-state-pr'];
370957
+ function extractPrInfo(item, annotation = LAST_STATE_PR_ANNOTATION) {
370958
+ const prInfo = item.metadata.annotations[annotation];
370959
+ if (!prInfo)
370960
+ throw new Error(`No ${annotation} annotation found in CR`);
370894
370961
  const prNumber = prInfo.split('#')[1];
370895
370962
  if (!prNumber)
370896
370963
  throw new Error('No PR number found in CR');
@@ -370900,7 +370967,11 @@ function extractPrInfo(item) {
370900
370967
  const repo = prInfo.split('#')[0].split('/')[1];
370901
370968
  if (!repo)
370902
370969
  throw new Error('No repo found in CR');
370903
- return { prNumber, repo, org };
370970
+ const prNumberInt = parseInt(prNumber, 10);
370971
+ if (isNaN(prNumberInt)) {
370972
+ throw new Error(`Invalid PR number found in CR: '${prNumber}'`);
370973
+ }
370974
+ return { prNumber: prNumberInt, repo, org };
370904
370975
  }
370905
370976
  async function tryPublishError(item, reason, message) {
370906
370977
  try {
@@ -370917,7 +370988,7 @@ async function publishError(item, reason, message) {
370917
370988
  #### ℹ️ Details:
370918
370989
  ${message}
370919
370990
  `;
370920
- await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org, 'logs');
370991
+ await github_0.pulls.commentInPR(comment, prNumber, repo, org, 'logs');
370921
370992
  }
370922
370993
  async function publishPlan(item, planOutput, prNumber, repo, org) {
370923
370994
  try {
@@ -370936,7 +371007,7 @@ async function publishPlan(item, planOutput, prNumber, repo, org) {
370936
371007
  ${commentContent}
370937
371008
  \`\`\`
370938
371009
  </details>`;
370939
- await github_0.pulls.commentInPR(comment, prNumber, repo, org, 'logs');
371010
+ await github_0.pulls.commentInPR(comment, prNumber, repo, org, 'tfworkspace:plan');
370940
371011
  currentCommentNo += 1;
370941
371012
  }
370942
371013
  }
@@ -370947,8 +371018,9 @@ ${commentContent}
370947
371018
 
370948
371019
  ;// CONCATENATED MODULE: ../operator/src/user-feedback-ops/gh-checkrun.ts
370949
371020
 
371021
+
370950
371022
  async function GHCheckRun(cmd, item) {
370951
- const prInfo = gh_checkrun_extractPrInfo(item);
371023
+ const prInfo = extractPrInfo(item);
370952
371024
  if (!prInfo.prNumber) {
370953
371025
  throw new Error('TFCheckRun: prNumber not retrievable');
370954
371026
  }
@@ -370977,20 +371049,6 @@ async function GHCheckRun(cmd, item) {
370977
371049
  function helperCreateCheckRunName(cmd, item) {
370978
371050
  return `${item.kind} - ${cmd}`;
370979
371051
  }
370980
- function gh_checkrun_extractPrInfo(item) {
370981
- const prInfo = item.metadata.annotations['firestartr.dev/last-state-pr'];
370982
- const prNumber = prInfo.split('#')[1];
370983
- if (!prNumber)
370984
- throw new Error('No PR number found in CR');
370985
- const orgRepo = prInfo.split('#')[0];
370986
- const org = orgRepo.split('/')[0];
370987
- if (!org)
370988
- throw new Error('No org found in CR');
370989
- const repo = orgRepo.split('/')[1];
370990
- if (!repo)
370991
- throw new Error('No repo found in CR');
370992
- return { prNumber, repo, org };
370993
- }
370994
371052
 
370995
371053
  ;// CONCATENATED MODULE: ../operator/cdktf.ts
370996
371054
 
@@ -372291,9 +372349,10 @@ async function* errorPolicyCompatibility(syncPolicy, generalPolicy, item, op) {
372291
372349
  ;// CONCATENATED MODULE: ../operator/src/user-feedback-ops/tf-checkrun.ts
372292
372350
 
372293
372351
 
372352
+
372294
372353
  async function TFCheckRun(cmd, item) {
372295
372354
  try {
372296
- const prInfo = tf_checkrun_extractPrInfo(item);
372355
+ const prInfo = extractPrInfo(item);
372297
372356
  const checkRun = await github_0.feedback.createCheckRun(prInfo.org, prInfo.repo, tf_checkrun_helperCreateCheckRunName(cmd), {
372298
372357
  pullNumber: Number(prInfo.prNumber),
372299
372358
  includeCheckRunComment: true,
@@ -372310,7 +372369,7 @@ async function TFCheckRun(cmd, item) {
372310
372369
  fnEnd: () => {
372311
372370
  checkRun.close('OK', true);
372312
372371
  },
372313
- fnOnError: (err) => {
372372
+ fnOnError: (_) => {
372314
372373
  checkRun.close('KO', false);
372315
372374
  },
372316
372375
  };
@@ -372319,30 +372378,15 @@ async function TFCheckRun(cmd, item) {
372319
372378
  // log error and return empty fns
372320
372379
  logger_logger.warn('Error in TFCheckRun:', e);
372321
372380
  return {
372322
- fnData: (d) => { },
372381
+ fnData: (_) => { },
372323
372382
  fnEnd: () => { },
372324
- fnOnError: (err) => { },
372383
+ fnOnError: (_) => { },
372325
372384
  };
372326
372385
  }
372327
372386
  }
372328
372387
  function tf_checkrun_helperCreateCheckRunName(cmd) {
372329
372388
  return `TFWorkspace - ${cmd}`;
372330
372389
  }
372331
- function tf_checkrun_extractPrInfo(item) {
372332
- const prInfo = item.metadata.annotations['firestartr.dev/last-state-pr'];
372333
- if (!prInfo)
372334
- throw new Error('No firestartr.dev/last-state-pr field in CR');
372335
- const prNumber = prInfo.split('#')[1];
372336
- if (!prNumber)
372337
- throw new Error('No PR number found in CR');
372338
- const org = prInfo.split('#')[0].split('/')[0];
372339
- if (!org)
372340
- throw new Error('No org found in CR');
372341
- const repo = prInfo.split('#')[0].split('/')[1];
372342
- if (!repo)
372343
- throw new Error('No repo found in CR');
372344
- return { prNumber, repo, org };
372345
- }
372346
372390
 
372347
372391
  ;// CONCATENATED MODULE: ../operator/src/utils/index.ts
372348
372392
  const secretRegex = /\$\{\{ secrets\.(.*?) \}\}/g;
@@ -373212,7 +373256,6 @@ async function acquireLease(namespace, cb, interval = 10000) {
373212
373256
 
373213
373257
 
373214
373258
 
373215
-
373216
373259
  const processOperationPlan_TF_PROJECTS_PATH = '/tmp/tfworkspaces';
373217
373260
  function processOperationPlan(item, op, handler) {
373218
373261
  try {
@@ -373288,7 +373331,8 @@ async function* doPlanPlainTextFormat(item, op, handler, action) {
373288
373331
  await addPlanStatusCheck(item.metadata.annotations['firestartr.dev/last-state-pr'], 'Terraform plan in progress...');
373289
373332
  }
373290
373333
  const tfPlanOutput = await runTerraformProvisioner(context, action);
373291
- await processOperationPlan_publishPlan(item, tfPlanOutput);
373334
+ const { prNumber, repo, org } = extractPrInfo(item, 'firestartr.dev/pull-request-plan');
373335
+ await publishPlan(item, tfPlanOutput, prNumber, repo, org);
373292
373336
  yield {
373293
373337
  item,
373294
373338
  reason: op,
@@ -373315,7 +373359,8 @@ async function* doPlanPlainTextFormat(item, op, handler, action) {
373315
373359
  }
373316
373360
  }
373317
373361
  catch (e) {
373318
- await processOperationPlan_publishPlan(item, JSON.stringify(e));
373362
+ const { prNumber, repo, org } = extractPrInfo(item, 'firestartr.dev/pull-request-plan');
373363
+ await publishPlan(item, JSON.stringify(e), prNumber, repo, org);
373319
373364
  operator_src_logger.error('TFWORKSPACE_PROCESSOR_PLAN_OBSERVING_ERROR', {
373320
373365
  metadata: { item, error: e },
373321
373366
  });
@@ -373630,7 +373675,6 @@ function processOperationPlan_clearLocalTfProjects() {
373630
373675
  external_fs_.rmSync(processOperationPlan_TF_PROJECTS_PATH, { recursive: true, force: true });
373631
373676
  }
373632
373677
  function processOperationPlan_getErrorOutputMessage(cr, key, ref) {
373633
- const result = '';
373634
373678
  if (cr.spec.source === 'Remote') {
373635
373679
  return `
373636
373680
 
@@ -373663,43 +373707,6 @@ function processOperationPlan_getErrorOutputMessage(cr, key, ref) {
373663
373707
  throw new Error(`❌ Source ${cr.spec.source} not supported`);
373664
373708
  }
373665
373709
  }
373666
- async function processOperationPlan_publishPlan(item, planOutput) {
373667
- try {
373668
- const prInfo = item.metadata.annotations['firestartr.dev/pull-request-plan'];
373669
- if (!prInfo)
373670
- throw new Error('No PR info found in CR');
373671
- const prNumber = prInfo.split('#')[1];
373672
- if (!prNumber)
373673
- throw new Error('No PR number found in CR');
373674
- const org = prInfo.split('#')[0].split('/')[0];
373675
- if (!org)
373676
- throw new Error('No org found in CR');
373677
- const repo = prInfo.split('#')[0].split('/')[1];
373678
- if (!repo)
373679
- throw new Error('No repo found in CR');
373680
- const dividedOutput = github_0.pulls.divideCommentIntoChunks(planOutput, 250);
373681
- let currentCommentNo = 1;
373682
- for (const commentContent of dividedOutput) {
373683
- const comment = `<h1>
373684
- <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Plan Finished
373685
- </h1>
373686
- <p><b>TFWorkspace: </b>${item.metadata.name}</p>
373687
-
373688
- <details id=github>
373689
- <summary>PLAN LOGS ${dividedOutput.length > 1 ? '(Part ' + currentCommentNo + ')' : ''}</summary>
373690
-
373691
- \`\`\`shell
373692
- ${commentContent}
373693
- \`\`\`
373694
- </details>`;
373695
- await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org, 'logs');
373696
- currentCommentNo += 1;
373697
- }
373698
- }
373699
- catch (e) {
373700
- console.error(e);
373701
- }
373702
- }
373703
373710
  function processOperationPlan_getPolicy(item) {
373704
373711
  const policy = item.metadata.annotations &&
373705
373712
  item.metadata.annotations['firestartr.dev/policy'];
@@ -374167,6 +374174,8 @@ async function startCRStates(meter, kindList, namespace) {
374167
374174
  }
374168
374175
  }
374169
374176
 
374177
+ // EXTERNAL MODULE: external "util"
374178
+ var external_util_ = __nccwpck_require__(73837);
374170
374179
  ;// CONCATENATED MODULE: ../operator/src/cmd/tf_planner.ts
374171
374180
 
374172
374181
 
@@ -374174,9 +374183,10 @@ async function startCRStates(meter, kindList, namespace) {
374174
374183
 
374175
374184
 
374176
374185
 
374186
+
374177
374187
  const deploymentName = catalog_common.environment.getFromEnvironment(catalog_common.types.envVars.operatorDeploymentName) || 'firestartr-firestartr-controller';
374178
374188
  const DEFAULT_OPERATOR_DEPLOY = (/* unused pure expression or super */ null && (deploymentName));
374179
- async function tfPlanner(claimFilePath, claim, namespace, debug, jobTtl = 300, cmd = 'plan') {
374189
+ async function tfPlanner(claimFilePath, claim, namespace, debug, jobTtl = 300, cmd = 'plan', callbackApi = function (ctl) { }) {
374180
374190
  const { kc } = await getConnection();
374181
374191
  const k8sApi = kc.makeApiClient(client.AppsV1Api);
374182
374192
  const batchV1Api = kc.makeApiClient(client.BatchV1Api);
@@ -374202,6 +374212,7 @@ async function tfPlanner(claimFilePath, claim, namespace, debug, jobTtl = 300, c
374202
374212
  // set activeDeadlineSeconds to force terminate jobs that exceed this time
374203
374213
  // see https://kubernetes.io/docs/concepts/workloads/controllers/job/#job-termination-and-cleanup
374204
374214
  job.spec.activeDeadlineSeconds = 3600;
374215
+ job.spec.template.spec.containers[0].env = [{ name: 'CI', value: 'True' }];
374205
374216
  job.spec.template.spec.containers[0].command = [
374206
374217
  'sh',
374207
374218
  '-c',
@@ -374213,13 +374224,39 @@ async function tfPlanner(claimFilePath, claim, namespace, debug, jobTtl = 300, c
374213
374224
  }
374214
374225
  job.spec.template.spec.restartPolicy = 'Never';
374215
374226
  job.metadata = metadata;
374227
+ // we limit the number of retries
374228
+ // to 1
374229
+ job.spec.backoffLimit = 1;
374216
374230
  // we exclude logs to be sent to datadog
374217
374231
  job.spec.template.metadata.annotations = {
374218
374232
  'ad.datadoghq.com/logs_exclude': 'true',
374219
374233
  };
374234
+ callbackApi({
374235
+ ctlCleanUp: () => cleanUp(namespace, metadata.name),
374236
+ });
374220
374237
  await batchV1Api.createNamespacedJob(namespace, job);
374221
374238
  await copyClaimAndGetLogs(namespace, job.metadata.name, claimFilePath);
374222
374239
  }
374240
+ async function cleanUp(namespace, jobName) {
374241
+ try {
374242
+ console.log('Cleaning up the job');
374243
+ const { kc } = await getConnection();
374244
+ const batchV1Api = kc.makeApiClient(client.BatchV1Api);
374245
+ console.log('Deleting job and its associated pods');
374246
+ await batchV1Api.deleteNamespacedJob(jobName, namespace, undefined, // pretty output
374247
+ undefined, // dryRun
374248
+ 1 * 60, // 60 segs of grace period
374249
+ undefined, 'Foreground');
374250
+ }
374251
+ catch (err) {
374252
+ const cleanError = util.inspect(err, {
374253
+ showHidden: false,
374254
+ depth: 1,
374255
+ colors: false,
374256
+ });
374257
+ console.error(cleanError);
374258
+ }
374259
+ }
374223
374260
  async function copyClaimAndGetLogs(namespace, jobName, sourcePath) {
374224
374261
  const { kc } = await getConnection();
374225
374262
  const k8sApi = kc.makeApiClient(client.CoreV1Api);
@@ -374268,11 +374305,12 @@ async function copyClaimAndGetLogs(namespace, jobName, sourcePath) {
374268
374305
  timestamps: false,
374269
374306
  });
374270
374307
  let podFinished = false;
374271
- setInterval(async () => {
374308
+ const interval = setInterval(async () => {
374272
374309
  await awaitPodStatus((phase) => {
374273
374310
  if (phase !== 'Running') {
374274
374311
  podFinished = true;
374275
374312
  req.abort();
374313
+ clearInterval(interval);
374276
374314
  return true;
374277
374315
  }
374278
374316
  else {
@@ -374286,7 +374324,12 @@ async function copyClaimAndGetLogs(namespace, jobName, sourcePath) {
374286
374324
  }
374287
374325
  }
374288
374326
  catch (err) {
374289
- console.error(err);
374327
+ const cleanError = util.inspect(err, {
374328
+ showHidden: false,
374329
+ depth: 1,
374330
+ colors: false,
374331
+ });
374332
+ console.error(cleanError);
374290
374333
  return;
374291
374334
  }
374292
374335
  }
@@ -1581,6 +1581,10 @@ export interface FirestartrGithubRepositoryFeatureSpecFiles {
1581
1581
  * @schema FirestartrGithubRepositoryFeatureSpecFiles#content
1582
1582
  */
1583
1583
  readonly content: string;
1584
+ /**
1585
+ * @schema FirestartrGithubRepositoryFeatureSpecFiles#targetBranch
1586
+ */
1587
+ readonly targetBranch?: string;
1584
1588
  }
1585
1589
  /**
1586
1590
  * Converts an object of type 'FirestartrGithubRepositoryFeatureSpecFiles' to JSON representation.
@@ -27,5 +27,6 @@ interface IGithubRepositoryFeatureFileClaim {
27
27
  path: string;
28
28
  userManaged: boolean;
29
29
  content: string;
30
+ targetBranch: string;
30
31
  }
31
32
  export {};
@@ -0,0 +1 @@
1
+ export declare function applyOneWayDefs(crSpecs: any): any;
@@ -77,6 +77,9 @@ declare const _default: {
77
77
  upgradable: {
78
78
  type: string;
79
79
  };
80
+ target_branch: {
81
+ type: string;
82
+ };
80
83
  };
81
84
  required: string[];
82
85
  title: string;
@@ -1,2 +1,2 @@
1
- export declare function tfPlanner(claimFilePath: string, claim: any, namespace: string, debug: boolean, jobTtl?: number, cmd?: string): Promise<void>;
1
+ export declare function tfPlanner(claimFilePath: string, claim: any, namespace: string, debug: boolean, jobTtl?: number, cmd?: string, callbackApi?: (ctl: any) => void): Promise<void>;
2
2
  export declare function kubectlCp(sourcePath: string, namespace: string, podName: string, podFilePath?: string): void;
@@ -1,5 +1,5 @@
1
1
  export declare function TFCheckRun(cmd: string, item: any): Promise<{
2
2
  fnData: (d: any) => void;
3
3
  fnEnd: () => void;
4
- fnOnError: (err: any) => void;
4
+ fnOnError: (_: any) => void;
5
5
  }>;
@@ -2,6 +2,11 @@ export declare function tryPublishApply(item: any, planOutput: string, kind: str
2
2
  export declare function tryPublishDestroy(item: any, destroyOutput: string): Promise<void>;
3
3
  export declare function publishApply(item: any, applyOutput: string, kind: string): Promise<void>;
4
4
  export declare function tryCreateErrorSummary(title: string, errorMsg: string): string;
5
+ export declare function extractPrInfo(item: any, annotation?: 'firestartr.dev/last-state-pr' | 'firestartr.dev/pull-request-plan'): {
6
+ prNumber: number;
7
+ repo: string;
8
+ org: string;
9
+ };
5
10
  export declare function tryPublishError(item: any, reason: string, message: string): Promise<void>;
6
11
  export declare function publishError(item: any, reason: string, message: string): Promise<void>;
7
12
  export declare function publishPlan(item: any, planOutput: string, prNumber: number, repo: string, org: string): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firestartr/cli",
3
- "version": "1.53.0-snapshot-2",
3
+ "version": "1.53.0-snapshot-4",
4
4
  "private": false,
5
5
  "description": "Commandline tool",
6
6
  "main": "build/main.js",