@firestartr/cli 1.50.1-snapshot-31 → 1.50.1-snapshot-33

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
@@ -289786,18 +289786,12 @@ function fromYaml(data) {
289786
289786
  }
289787
289787
  function toYaml(data, opts = {}) {
289788
289788
  src_logger.debug('opts', opts);
289789
- const result = yaml_dist.stringify(data, {
289790
- defaultKeyType: 'PLAIN',
289791
- defaultStringType: 'QUOTE_DOUBLE',
289792
- });
289789
+ const result = yaml_dist.stringify(data);
289793
289790
  return result;
289794
289791
  }
289795
289792
  function dumpYaml(data) {
289796
289793
  src_logger.debug('Dumping object data to YAML %O', data);
289797
- return yaml_dist.stringify(data, {
289798
- defaultKeyType: 'PLAIN',
289799
- defaultStringType: 'QUOTE_DOUBLE',
289800
- });
289794
+ return yaml_dist.stringify(data);
289801
289795
  }
289802
289796
 
289803
289797
  // EXTERNAL MODULE: external "child_process"
@@ -298377,16 +298371,13 @@ async function getOrgTeamsDirectAccess(org) {
298377
298371
  }
298378
298372
  }
298379
298373
  }`);
298380
- console.dir("--- 🚀 GraphQL response:");
298381
- console.dir(response, { depth: null });
298382
298374
  return transformGraphQLResponse(response);
298383
298375
  }
298384
- ;
298385
298376
  function transformGraphQLResponse(response) {
298386
298377
  const teams = response?.organization?.teams?.nodes;
298387
298378
  if (!teams)
298388
298379
  return {};
298389
- let result = {
298380
+ const result = {
298390
298381
  repositories: {},
298391
298382
  teams: {},
298392
298383
  };
@@ -298404,8 +298395,6 @@ function transformGraphQLResponse(response) {
298404
298395
  result.repositories[repoName][teamName] = permission;
298405
298396
  });
298406
298397
  });
298407
- console.log("--- 🚀 Transformed GraphQL response:");
298408
- console.dir(result, { depth: null });
298409
298398
  return result;
298410
298399
  }
298411
298400
  async function getOrgPlanName(org) {
@@ -298701,20 +298690,141 @@ async function getUserInfo(name) {
298701
298690
  getUserInfo,
298702
298691
  });
298703
298692
 
298693
+ ;// CONCATENATED MODULE: ../github/src/sticky_comment.ts
298694
+ const locks = new Map();
298695
+ async function withLock(key, fn) {
298696
+ const prev = locks.get(key) ?? Promise.resolve();
298697
+ let release;
298698
+ const next = new Promise((r) => (release = r));
298699
+ locks.set(key, prev.then(() => next));
298700
+ await prev;
298701
+ try {
298702
+ return await fn();
298703
+ }
298704
+ finally {
298705
+ release();
298706
+ if (locks.get(key) === next)
298707
+ locks.delete(key);
298708
+ }
298709
+ }
298710
+ // helpers
298711
+ function escapeForRegex(s) {
298712
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
298713
+ }
298714
+ function prIdRegex(kind) {
298715
+ return new RegExp(`<!-- sticky-id:${escapeForRegex(kind)}=(\\d+) -->`);
298716
+ }
298717
+ function prIdMarker(kind, id) {
298718
+ return `<!-- sticky-id:${kind}=${id} -->`;
298719
+ }
298720
+ function bodyMarker(kind) {
298721
+ return `<!-- sticky:kind=${kind} -->`;
298722
+ }
298723
+ async function readStickyIdFromPrBody(octokit, owner, repo, pr, kind) {
298724
+ const prResp = await octokit.rest.pulls.get({ owner, repo, pull_number: pr });
298725
+ const body = prResp.data?.body ?? '';
298726
+ const m = body.match(prIdRegex(kind));
298727
+ return m ? Number(m[1]) : undefined;
298728
+ }
298729
+ async function writeStickyIdToPrBody(octokit, owner, repo, pr, kind, id) {
298730
+ const get = await octokit.rest.pulls.get({ owner, repo, pull_number: pr });
298731
+ const body = get.data?.body ?? '';
298732
+ const rx = prIdRegex(kind);
298733
+ const marker = prIdMarker(kind, id);
298734
+ const next = rx.test(body)
298735
+ ? body.replace(rx, marker)
298736
+ : body
298737
+ ? `${body}\n${marker}`
298738
+ : marker;
298739
+ if (next !== body) {
298740
+ await octokit.rest.pulls.update({
298741
+ owner,
298742
+ repo,
298743
+ pull_number: pr,
298744
+ body: next,
298745
+ });
298746
+ }
298747
+ }
298748
+ async function upsertStickyComment(octokit, params) {
298749
+ const { owner, repo, pullNumber, kind } = params;
298750
+ const fullBody = `${params.body}\n\n${bodyMarker(kind)}`;
298751
+ const lockKey = `${owner}/${repo}#${pullNumber}#${kind}`;
298752
+ await withLock(lockKey, async () => {
298753
+ // 1) PR-body registry fast path
298754
+ const idFromPr = await readStickyIdFromPrBody(octokit, owner, repo, pullNumber, kind);
298755
+ if (idFromPr) {
298756
+ await octokit.rest.issues.updateComment({
298757
+ owner,
298758
+ repo,
298759
+ comment_id: idFromPr,
298760
+ body: fullBody,
298761
+ });
298762
+ return;
298763
+ }
298764
+ // 2) Try to find an existing comment by kind marker
298765
+ try {
298766
+ const all = await octokit.paginate(octokit.rest.issues.listComments, {
298767
+ owner,
298768
+ repo,
298769
+ issue_number: pullNumber,
298770
+ per_page: 100,
298771
+ });
298772
+ const marker = bodyMarker(kind);
298773
+ const hit = all.find((c) => typeof c.body === 'string' && c.body.includes(marker));
298774
+ if (hit?.id) {
298775
+ await octokit.rest.issues.updateComment({
298776
+ owner,
298777
+ repo,
298778
+ comment_id: hit.id,
298779
+ body: fullBody,
298780
+ });
298781
+ await writeStickyIdToPrBody(octokit, owner, repo, pullNumber, kind, hit.id);
298782
+ return;
298783
+ }
298784
+ }
298785
+ catch {
298786
+ // if paginate/listComments not available, we'll fall back to creating
298787
+ }
298788
+ // 3) Create new comment and register
298789
+ const created = await octokit.rest.issues.createComment({
298790
+ owner,
298791
+ repo,
298792
+ issue_number: pullNumber,
298793
+ body: fullBody,
298794
+ });
298795
+ const newId = created?.data?.id;
298796
+ if (newId !== undefined) {
298797
+ await writeStickyIdToPrBody(octokit, owner, repo, pullNumber, kind, newId);
298798
+ }
298799
+ });
298800
+ }
298801
+
298704
298802
  ;// CONCATENATED MODULE: ../github/src/pull_request.ts
298705
298803
 
298706
298804
 
298805
+
298707
298806
  const commentMaxSize = 65535;
298708
- async function commentInPR(comment, pr_number, repo, owner = 'prefapp') {
298807
+ async function commentInPR(comment, pr_number, repo, owner = 'prefapp', stickyKind) {
298709
298808
  try {
298710
298809
  github_src_logger.info(`Commenting ${comment} in PR ${pr_number} of ${owner}/${repo}`);
298711
298810
  const octokit = await getOctokitForOrg(owner);
298712
- await octokit.rest.issues.createComment({
298713
- owner,
298714
- repo,
298715
- issue_number: pr_number,
298716
- body: comment,
298717
- });
298811
+ if (stickyKind) {
298812
+ await upsertStickyComment(octokit, {
298813
+ owner,
298814
+ repo,
298815
+ pullNumber: pr_number,
298816
+ kind: stickyKind,
298817
+ body: comment,
298818
+ });
298819
+ }
298820
+ else {
298821
+ await octokit.rest.issues.createComment({
298822
+ owner,
298823
+ repo,
298824
+ issue_number: pr_number,
298825
+ body: comment,
298826
+ });
298827
+ }
298718
298828
  }
298719
298829
  catch (e) {
298720
298830
  console.error(`Error commenting in PR: ${e}`);
@@ -298944,6 +299054,7 @@ async function createOrphanBranch(repo, branch, owner = 'prefapp') {
298944
299054
 
298945
299055
 
298946
299056
 
299057
+
298947
299058
  const FLUSH_TIMEOUT = 4; // seconds
298948
299059
  const GITHUB_OUTPUT_TEXT_LIMIT = 65000; // ~65k hard limit for output.text
298949
299060
  /**
@@ -299078,6 +299189,15 @@ class GithubCheckRun {
299078
299189
  text,
299079
299190
  },
299080
299191
  });
299192
+ if (this.includeCheckRunComment && this.pullNumber !== undefined) {
299193
+ try {
299194
+ await this.__ensureAndUpdateStickyComment(this.__buildCheckRunUrl());
299195
+ this.hasCommented = true;
299196
+ }
299197
+ catch {
299198
+ github_src_logger.warn('Error creating check run comment');
299199
+ }
299200
+ }
299081
299201
  this.closed = true;
299082
299202
  }
299083
299203
  catch (e) {
@@ -299091,42 +299211,36 @@ class GithubCheckRun {
299091
299211
  async __ensureCreated() {
299092
299212
  if (this.checkRunId)
299093
299213
  return;
299094
- const startedAt = new Date().toISOString();
299095
- const res = await this.octokit.rest.checks.create({
299096
- owner: this.owner,
299097
- repo: this.repo,
299098
- name: this.name,
299099
- head_sha: this.headSHA,
299100
- status: 'in_progress',
299101
- started_at: startedAt,
299102
- details_url: this.detailsUrl,
299103
- output: {
299104
- title: this.title,
299105
- summary: this._summaryOverride ?? '',
299106
- text: undefined,
299107
- },
299108
- });
299109
- this.checkRunId = res.data.id;
299110
- if (this.includeCheckRunComment &&
299111
- this.pullNumber !== undefined &&
299112
- !this.hasCommented) {
299113
- const link = this.__buildCheckRunUrl();
299114
- const formattedLink = `[here](${link})`;
299115
- const base = this.checkRunComment ?? '';
299116
- const body = base ? `${base}${formattedLink}` : formattedLink;
299117
- await this.octokit.rest.issues.createComment({
299214
+ if (this.creatingPromise)
299215
+ return this.creatingPromise;
299216
+ this.creatingPromise = (async () => {
299217
+ const startedAt = new Date().toISOString();
299218
+ const res = await this.octokit.rest.checks.create({
299118
299219
  owner: this.owner,
299119
299220
  repo: this.repo,
299120
- issue_number: this.pullNumber,
299121
- body,
299221
+ name: this.name,
299222
+ head_sha: this.headSHA,
299223
+ status: 'in_progress',
299224
+ started_at: startedAt,
299225
+ details_url: this.detailsUrl,
299226
+ output: {
299227
+ title: this.title,
299228
+ summary: this._summaryOverride ?? '',
299229
+ text: undefined,
299230
+ },
299122
299231
  });
299123
- this.hasCommented = true;
299232
+ this.checkRunId = res.data.id;
299233
+ })();
299234
+ try {
299235
+ await this.creatingPromise;
299236
+ }
299237
+ finally {
299238
+ this.creatingPromise = undefined;
299124
299239
  }
299125
299240
  }
299126
299241
  async __updateCheckRun(allContent) {
299127
299242
  if (this.closed || this.closing)
299128
299243
  return;
299129
- await this.__ensureCreated();
299130
299244
  const { text, summary } = this.buildOutputTextAndSummary(allContent);
299131
299245
  await this.octokit.rest.checks.update({
299132
299246
  owner: this.owner,
@@ -299139,6 +299253,14 @@ class GithubCheckRun {
299139
299253
  text,
299140
299254
  },
299141
299255
  });
299256
+ if (this.includeCheckRunComment && this.pullNumber !== undefined) {
299257
+ try {
299258
+ await this.__ensureAndUpdateStickyComment(this.__buildCheckRunUrl());
299259
+ }
299260
+ catch (e) {
299261
+ github_src_logger.warn('Error updating check run comment:', e);
299262
+ }
299263
+ }
299142
299264
  }
299143
299265
  __buildCheckRunUrl() {
299144
299266
  if (this.checkRunId) {
@@ -299168,6 +299290,20 @@ class GithubCheckRun {
299168
299290
  }
299169
299291
  return { text, summary };
299170
299292
  }
299293
+ // Ensure a sticky comment exists and rewrite it entirely with the latest content.
299294
+ async __ensureAndUpdateStickyComment(link) {
299295
+ if (!this.includeCheckRunComment || this.pullNumber === undefined)
299296
+ return;
299297
+ const base = this.checkRunComment ?? '';
299298
+ const linkLine = base ? `${base}[here](${link})` : `[here](${link})`;
299299
+ await upsertStickyComment(this.octokit, {
299300
+ owner: this.owner,
299301
+ repo: this.repo,
299302
+ pullNumber: this.pullNumber,
299303
+ kind: `check-run:${this.name}`,
299304
+ body: linkLine,
299305
+ });
299306
+ }
299171
299307
  }
299172
299308
  // -------------------- Helpers --------------------
299173
299309
  function truncateRight(s, max) {
@@ -299185,11 +299321,12 @@ async function createCheckRunForOrg(org, owner, repo, name, opts) {
299185
299321
  const pr = opts?.pullNumber;
299186
299322
  const hasValidPrNumber = typeof pr === 'number' && Number.isInteger(pr) && pr > 0;
299187
299323
  if (!headSHA && hasValidPrNumber) {
299188
- headSHA = await getPrMergeCommitSHA(opts.pullNumber, repo, owner);
299324
+ headSHA = await getPrMergeCommitSHA(pr, repo, owner);
299189
299325
  }
299190
299326
  if (!headSHA) {
299191
299327
  throw new Error('createCheckRunForOrg: either opts.headSHA or opts.pullNumber must be provided');
299192
299328
  }
299329
+ github_src_logger.debug(`Creating check run ${name} in ${owner}/${repo} at ${headSHA}`);
299193
299330
  return new GithubCheckRun(octokit, {
299194
299331
  owner,
299195
299332
  repo,
@@ -299204,6 +299341,7 @@ async function createCheckRunForOrg(org, owner, repo, name, opts) {
299204
299341
  });
299205
299342
  }
299206
299343
  async function createCheckRun(owner, repo, name, opts) {
299344
+ github_src_logger.debug(`Creating check run ${name} in ${owner}/${repo}`);
299207
299345
  return createCheckRunForOrg(owner, owner, repo, name, opts);
299208
299346
  }
299209
299347
  const CheckRun = GithubCheckRun;
@@ -310215,9 +310353,6 @@ class RepoGithubDecanter extends GithubDecanter {
310215
310353
  }
310216
310354
  }
310217
310355
  __decantRelations() {
310218
- importer_src_logger.debug("Decanting repo's relations...");
310219
- console.dir(this.data.teamsAndMembers, { depth: null });
310220
- importer_src_logger.debug("Decanting maintainers...");
310221
310356
  const directMaintainers = this.data.teamsAndMembers.directMembers
310222
310357
  .filter((member) => member.role === 'maintain')
310223
310358
  .map((member) => {
@@ -310243,7 +310378,6 @@ class RepoGithubDecanter extends GithubDecanter {
310243
310378
  path: '/maintainedBy',
310244
310379
  });
310245
310380
  }
310246
- importer_src_logger.debug("Decanting admins...");
310247
310381
  const directAdmins = this.data.teamsAndMembers.directMembers
310248
310382
  .filter((member) => member.role === 'admin')
310249
310383
  .map((member) => {
@@ -310279,7 +310413,6 @@ class RepoGithubDecanter extends GithubDecanter {
310279
310413
  path: '/providers/github/overrides',
310280
310414
  });
310281
310415
  }
310282
- importer_src_logger.debug("Decanting writers...");
310283
310416
  const directWriters = this.data.teamsAndMembers.directMembers
310284
310417
  .filter((member) => member.role === 'push')
310285
310418
  .map((member) => {
@@ -310304,7 +310437,6 @@ class RepoGithubDecanter extends GithubDecanter {
310304
310437
  path: '/providers/github/overrides',
310305
310438
  });
310306
310439
  }
310307
- importer_src_logger.debug("Decanting readers...");
310308
310440
  const directReaders = this.data.teamsAndMembers.directMembers
310309
310441
  .filter((member) => member.role === 'pull')
310310
310442
  .map((member) => {
@@ -310333,13 +310465,11 @@ class RepoGithubDecanter extends GithubDecanter {
310333
310465
  async __gatherRepoTeamsAndMembers() {
310334
310466
  this.data['teamsAndMembers'] = {};
310335
310467
  const directMembers = (await github_0.repo.getCollaborators(this.data.repoDetails.owner.login, this.data.repoDetails.name, 'direct')).map((member) => {
310336
- return { name: member.login, slug: member.slug, role: member.role_name };
310468
+ return { name: member.login, role: member.role_name };
310337
310469
  });
310338
310470
  const outsideMembers = (await github_0.repo.getCollaborators(this.data.repoDetails.owner.login, this.data.repoDetails.name, 'outside')).map((member) => {
310339
310471
  return { name: member.login, role: member.role_name };
310340
310472
  });
310341
- console.debug("--- 🚀 Gathered repo's teams and members:");
310342
- console.dir(this.githubTeams, { depth: null });
310343
310473
  const teams = Object.keys(this.githubTeams).map((teamName) => {
310344
310474
  return {
310345
310475
  name: teamName,
@@ -310504,8 +310634,6 @@ class RepoCollectionGithubDecanter extends GithubDecanter {
310504
310634
  const filteredRepos = await this.filter(RepoCollectionGithubDecanter.collectionKind, filters, repoList.map((repo) => repo.name));
310505
310635
  for (const repoName of filteredRepos) {
310506
310636
  const repoInfo = await this.github.repo.getRepoInfo(this.org, repoName);
310507
- console.log(`--- 🚀 Processing repo: ${repoName}`);
310508
- console.dir(directAccessRepos, { depth: null });
310509
310637
  repos.push(new RepoGithubDecanter({ repoDetails: repoInfo }, this.org, directAccessRepos?.[repoName]));
310510
310638
  }
310511
310639
  this.data['collection'] = repos;
@@ -311529,7 +311657,7 @@ async function writePlanInGithubPR(prUrl, planText) {
311529
311657
  ${planText}
311530
311658
  \`\`\`
311531
311659
  `;
311532
- await github_0.pulls.commentInPR(message, +pr_number, repo, owner);
311660
+ await github_0.pulls.commentInPR(message, +pr_number, repo, owner, 'logs');
311533
311661
  }
311534
311662
  catch (err) {
311535
311663
  operator_src_logger.error(`writePlanInGithubPR: Cannot write plan in PR: ${err}`);
@@ -311627,7 +311755,6 @@ async function updateDryRun(manifest, namespace) {
311627
311755
 
311628
311756
 
311629
311757
 
311630
-
311631
311758
  /**
311632
311759
  * Execute the callbacks for each item in the store
311633
311760
  * @param {string} plural - Kind to observe
@@ -311684,7 +311811,9 @@ async function observe(plural, namespace, onAdd, onChange, onDelete, _onRename)
311684
311811
  operator_src_logger.error(`An error occurred in the reflector for '${plural}' in namespace '${namespace}': '${err}'.`);
311685
311812
  setTimeout(async () => {
311686
311813
  try {
311814
+ operator_src_logger.warn(`Trying to recover from the error: "${err}" for '${plural}' in '${namespace}'`);
311687
311815
  await informer.start();
311816
+ operator_src_logger.warn(`Recovered from the error: "${err}" for '${plural}' in '${namespace}'`);
311688
311817
  }
311689
311818
  catch (err) {
311690
311819
  operator_src_logger.error(`Failed to start the reflector informer for '${plural}' in namespace '${namespace}': '${err}'.`);
@@ -311694,9 +311823,8 @@ async function observe(plural, namespace, onAdd, onChange, onDelete, _onRename)
311694
311823
  await informer.start();
311695
311824
  }
311696
311825
  catch (err) {
311697
- console.error(`Observing: ${plural}: ${err}`);
311698
- catalog_common.io.writeFunctionLog('observer', `Error Observing: ${plural}: ${err}`);
311699
- throw `Observing: ${plural}: ${err}`;
311826
+ operator_src_logger.error(`Observing: ${plural}: ${err}`);
311827
+ throw new Error(`Observing: ${plural}: ${err}`);
311700
311828
  }
311701
311829
  }
311702
311830
 
@@ -314651,7 +314779,7 @@ async function tryPublishDestroy(item, destroyOutput) {
314651
314779
  let currentCommentNo = 1;
314652
314780
  for (const commentContent of dividedOutput) {
314653
314781
  const comment = `<h1>
314654
- <img width="25" src="https://static-00.iconduck.com/assets.00/file-type-terraform-icon-1821x2048-mbxeegff.png"> Terraform destroy
314782
+ <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Destroy Finished
314655
314783
  </h1>
314656
314784
  <p><b>TFWorkspace: </b>${item.metadata.name}</p>
314657
314785
 
@@ -314663,7 +314791,7 @@ ${commentContent}
314663
314791
  \`\`\`
314664
314792
  </details>`;
314665
314793
  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}'.`);
314666
- await github_0.pulls.commentInPR(comment, lastPr.number, repo, org);
314794
+ await github_0.pulls.commentInPR(comment, lastPr.number, repo, org, 'logs');
314667
314795
  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}'.`);
314668
314796
  currentCommentNo += 1;
314669
314797
  }
@@ -314678,7 +314806,7 @@ async function publishApply(item, applyOutput, kind) {
314678
314806
  let currentCommentNo = 1;
314679
314807
  for (const commentContent of dividedOutput) {
314680
314808
  const comment = `<h1>
314681
- <img width="25" src="https://static-00.iconduck.com/assets.00/file-type-terraform-icon-1821x2048-mbxeegff.png"> Terraform apply
314809
+ <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Apply Finished
314682
314810
  </h1>
314683
314811
  <p><b>${kind}: </b>${item.metadata.name}</p>
314684
314812
 
@@ -314689,7 +314817,7 @@ async function publishApply(item, applyOutput, kind) {
314689
314817
  ${commentContent}
314690
314818
  \`\`\`
314691
314819
  </details>`;
314692
- await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org);
314820
+ await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org, 'logs');
314693
314821
  currentCommentNo += 1;
314694
314822
  }
314695
314823
  }
@@ -314738,7 +314866,7 @@ async function publishError(item, reason, message) {
314738
314866
  #### â„šī¸ Details:
314739
314867
  ${message}
314740
314868
  `;
314741
- await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org);
314869
+ await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org, 'logs');
314742
314870
  }
314743
314871
  async function publishPlan(item, planOutput, prNumber, repo, org) {
314744
314872
  try {
@@ -314746,7 +314874,7 @@ async function publishPlan(item, planOutput, prNumber, repo, org) {
314746
314874
  let currentCommentNo = 1;
314747
314875
  for (const commentContent of dividedOutput) {
314748
314876
  const comment = `<h1>
314749
- <img width="25" src="https://static-00.iconduck.com/assets.00/file-type-terraform-icon-1821x2048-mbxeegff.png"> Terraform plan
314877
+ <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Plan Finished
314750
314878
  </h1>
314751
314879
  <p><b>TFWorkspace: </b>${item.metadata.name}</p>
314752
314880
 
@@ -314757,7 +314885,7 @@ async function publishPlan(item, planOutput, prNumber, repo, org) {
314757
314885
  ${commentContent}
314758
314886
  \`\`\`
314759
314887
  </details>`;
314760
- await github_0.pulls.commentInPR(comment, prNumber, repo, org);
314888
+ await github_0.pulls.commentInPR(comment, prNumber, repo, org, 'logs');
314761
314889
  currentCommentNo += 1;
314762
314890
  }
314763
314891
  }
@@ -314796,7 +314924,7 @@ async function GHCheckRun(cmd, item) {
314796
314924
  };
314797
314925
  }
314798
314926
  function helperCreateCheckRunName(cmd, item) {
314799
- return `Github Provisioner / ${item.kind} - ${cmd}`;
314927
+ return `${item.kind} - ${cmd}`;
314800
314928
  }
314801
314929
  function gh_checkrun_extractPrInfo(item) {
314802
314930
  const prInfo = item.metadata.annotations['firestartr.dev/last-state-pr'];
@@ -314949,7 +315077,7 @@ async function* markedToDeletion(item, op, handler) {
314949
315077
  },
314950
315078
  logStreamCallbacksTF: {
314951
315079
  prepare: async () => {
314952
- checkRunCtl = await GHCheckRun('terraform destroy', item);
315080
+ checkRunCtl = await GHCheckRun('destroy', item);
314953
315081
  return checkRunCtl;
314954
315082
  },
314955
315083
  },
@@ -315073,7 +315201,7 @@ async function* doApply(item, op, handler) {
315073
315201
  },
315074
315202
  logStreamCallbacksTF: {
315075
315203
  prepare: async () => {
315076
- checkRunCtl = await GHCheckRun('terraform apply', item);
315204
+ checkRunCtl = await GHCheckRun('apply', item);
315077
315205
  return checkRunCtl;
315078
315206
  },
315079
315207
  },
@@ -317509,7 +317637,7 @@ async function processOperationPlan_publishPlan(item, planOutput) {
317509
317637
  let currentCommentNo = 1;
317510
317638
  for (const commentContent of dividedOutput) {
317511
317639
  const comment = `<h1>
317512
- <img width="25" src="https://static-00.iconduck.com/assets.00/file-type-terraform-icon-1821x2048-mbxeegff.png"> Terraform plan
317640
+ <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Plan Finished
317513
317641
  </h1>
317514
317642
  <p><b>TFWorkspace: </b>${item.metadata.name}</p>
317515
317643
 
@@ -317520,7 +317648,7 @@ async function processOperationPlan_publishPlan(item, planOutput) {
317520
317648
  ${commentContent}
317521
317649
  \`\`\`
317522
317650
  </details>`;
317523
- await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org);
317651
+ await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org, 'logs');
317524
317652
  currentCommentNo += 1;
317525
317653
  }
317526
317654
  }
@@ -25,6 +25,7 @@ export declare class GithubCheckRun {
25
25
  private readonly includeCheckRunComment;
26
26
  private readonly checkRunComment?;
27
27
  private hasCommented;
28
+ private creatingPromise?;
28
29
  private closing;
29
30
  private closed;
30
31
  private buffer;
@@ -58,6 +59,7 @@ export declare class GithubCheckRun {
58
59
  private __updateCheckRun;
59
60
  private __buildCheckRunUrl;
60
61
  private buildOutputTextAndSummary;
62
+ private __ensureAndUpdateStickyComment;
61
63
  }
62
64
  /**
63
65
  * Factory: build a GithubCheckRun using an installation token for the given org.
@@ -1,4 +1,4 @@
1
- export declare function commentInPR(comment: string, pr_number: number, repo: string, owner?: string): Promise<void>;
1
+ export declare function commentInPR(comment: string, pr_number: number, repo: string, owner?: string, stickyKind?: string): Promise<void>;
2
2
  export declare function getPrLastCommitSHA(pull_number: number, repo: string, owner?: string): Promise<string>;
3
3
  export declare function getPrMergeCommitSHA(pull_number: number, repo: string, owner?: string): Promise<string>;
4
4
  export declare function divideCommentIntoChunks(comment: string, sizeReduction?: number): string[];
@@ -0,0 +1,13 @@
1
+ import type { Octokit } from '@octokit/rest';
2
+ export interface UpsertStickyParams {
3
+ owner: string;
4
+ repo: string;
5
+ pullNumber: number;
6
+ /**
7
+ * Kind discriminator: one sticky comment per kind
8
+ * e.g., "plan" | "apply" | "destroy" | "logs" | "check-run:<name>"
9
+ */
10
+ kind: string;
11
+ body: string;
12
+ }
13
+ export declare function upsertStickyComment(octokit: Octokit, params: UpsertStickyParams): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firestartr/cli",
3
- "version": "1.50.1-snapshot-31",
3
+ "version": "1.50.1-snapshot-33",
4
4
  "private": false,
5
5
  "description": "Commandline tool",
6
6
  "main": "build/main.js",