@firestartr/cli 1.50.1-snapshot-32 → 1.50.1-snapshot-36

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"
@@ -298289,12 +298283,14 @@ async function getOctokitForOrg(org, paginated = false, genGithubAppToken = gene
298289
298283
  });
298290
298284
  const options = { auth: auth };
298291
298285
  if (paginated) {
298292
- options.plugins = [dist_bundle_paginateRest, paginateGraphQL];
298286
+ options.plugins = [dist_bundle_paginateRest];
298293
298287
  }
298294
- return new dist_src_Octokit(options);
298288
+ const OctokitWithGraphQL = dist_src_Octokit.plugin(paginateGraphQL);
298289
+ return new OctokitWithGraphQL(options);
298295
298290
  }
298296
298291
  async function getOctokitFromPat(envVar) {
298297
- return new dist_src_Octokit({
298292
+ const OctokitWithGraphQL = dist_src_Octokit.plugin(paginateGraphQL);
298293
+ return new OctokitWithGraphQL({
298298
298294
  auth: process.env[envVar],
298299
298295
  });
298300
298296
  }
@@ -298359,12 +298355,13 @@ async function getOrgInfo(org) {
298359
298355
  async function getOrgTeamsDirectAccess(org) {
298360
298356
  github_src_logger.info(`Getting teams for org ${org}`);
298361
298357
  const octokit = await getOctokitForOrg(org);
298362
- const response = await octokit.graphql(`{
298363
- organization(login: "${org}") {
298364
- teams(first: 30) {
298365
- nodes {
298366
- id
298367
- name
298358
+ const response = await octokit.graphql.paginate(`
298359
+ query paginate($cursor: String, $org: String!) {
298360
+ organization(login: \$org) {
298361
+ teams(first: 20, after: $cursor) {
298362
+ nodes {
298363
+ id
298364
+ name
298368
298365
  repositories {
298369
298366
  edges {
298370
298367
  permission
@@ -298376,17 +298373,14 @@ async function getOrgTeamsDirectAccess(org) {
298376
298373
  }
298377
298374
  }
298378
298375
  }
298379
- }`);
298380
- console.dir("--- 🚀 GraphQL response:");
298381
- console.dir(response, { depth: null });
298376
+ }`, { org });
298382
298377
  return transformGraphQLResponse(response);
298383
298378
  }
298384
- ;
298385
298379
  function transformGraphQLResponse(response) {
298386
298380
  const teams = response?.organization?.teams?.nodes;
298387
298381
  if (!teams)
298388
298382
  return {};
298389
- let result = {
298383
+ const result = {
298390
298384
  repositories: {},
298391
298385
  teams: {},
298392
298386
  };
@@ -298404,8 +298398,6 @@ function transformGraphQLResponse(response) {
298404
298398
  result.repositories[repoName][teamName] = permission;
298405
298399
  });
298406
298400
  });
298407
- console.log("--- 🚀 Transformed GraphQL response:");
298408
- console.dir(result, { depth: null });
298409
298401
  return result;
298410
298402
  }
298411
298403
  async function getOrgPlanName(org) {
@@ -298701,20 +298693,141 @@ async function getUserInfo(name) {
298701
298693
  getUserInfo,
298702
298694
  });
298703
298695
 
298696
+ ;// CONCATENATED MODULE: ../github/src/sticky_comment.ts
298697
+ const locks = new Map();
298698
+ async function withLock(key, fn) {
298699
+ const prev = locks.get(key) ?? Promise.resolve();
298700
+ let release;
298701
+ const next = new Promise((r) => (release = r));
298702
+ locks.set(key, prev.then(() => next));
298703
+ await prev;
298704
+ try {
298705
+ return await fn();
298706
+ }
298707
+ finally {
298708
+ release();
298709
+ if (locks.get(key) === next)
298710
+ locks.delete(key);
298711
+ }
298712
+ }
298713
+ // helpers
298714
+ function escapeForRegex(s) {
298715
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
298716
+ }
298717
+ function prIdRegex(kind) {
298718
+ return new RegExp(`<!-- sticky-id:${escapeForRegex(kind)}=(\\d+) -->`);
298719
+ }
298720
+ function prIdMarker(kind, id) {
298721
+ return `<!-- sticky-id:${kind}=${id} -->`;
298722
+ }
298723
+ function bodyMarker(kind) {
298724
+ return `<!-- sticky:kind=${kind} -->`;
298725
+ }
298726
+ async function readStickyIdFromPrBody(octokit, owner, repo, pr, kind) {
298727
+ const prResp = await octokit.rest.pulls.get({ owner, repo, pull_number: pr });
298728
+ const body = prResp.data?.body ?? '';
298729
+ const m = body.match(prIdRegex(kind));
298730
+ return m ? Number(m[1]) : undefined;
298731
+ }
298732
+ async function writeStickyIdToPrBody(octokit, owner, repo, pr, kind, id) {
298733
+ const get = await octokit.rest.pulls.get({ owner, repo, pull_number: pr });
298734
+ const body = get.data?.body ?? '';
298735
+ const rx = prIdRegex(kind);
298736
+ const marker = prIdMarker(kind, id);
298737
+ const next = rx.test(body)
298738
+ ? body.replace(rx, marker)
298739
+ : body
298740
+ ? `${body}\n${marker}`
298741
+ : marker;
298742
+ if (next !== body) {
298743
+ await octokit.rest.pulls.update({
298744
+ owner,
298745
+ repo,
298746
+ pull_number: pr,
298747
+ body: next,
298748
+ });
298749
+ }
298750
+ }
298751
+ async function upsertStickyComment(octokit, params) {
298752
+ const { owner, repo, pullNumber, kind } = params;
298753
+ const fullBody = `${params.body}\n\n${bodyMarker(kind)}`;
298754
+ const lockKey = `${owner}/${repo}#${pullNumber}#${kind}`;
298755
+ await withLock(lockKey, async () => {
298756
+ // 1) PR-body registry fast path
298757
+ const idFromPr = await readStickyIdFromPrBody(octokit, owner, repo, pullNumber, kind);
298758
+ if (idFromPr) {
298759
+ await octokit.rest.issues.updateComment({
298760
+ owner,
298761
+ repo,
298762
+ comment_id: idFromPr,
298763
+ body: fullBody,
298764
+ });
298765
+ return;
298766
+ }
298767
+ // 2) Try to find an existing comment by kind marker
298768
+ try {
298769
+ const all = await octokit.paginate(octokit.rest.issues.listComments, {
298770
+ owner,
298771
+ repo,
298772
+ issue_number: pullNumber,
298773
+ per_page: 100,
298774
+ });
298775
+ const marker = bodyMarker(kind);
298776
+ const hit = all.find((c) => typeof c.body === 'string' && c.body.includes(marker));
298777
+ if (hit?.id) {
298778
+ await octokit.rest.issues.updateComment({
298779
+ owner,
298780
+ repo,
298781
+ comment_id: hit.id,
298782
+ body: fullBody,
298783
+ });
298784
+ await writeStickyIdToPrBody(octokit, owner, repo, pullNumber, kind, hit.id);
298785
+ return;
298786
+ }
298787
+ }
298788
+ catch {
298789
+ // if paginate/listComments not available, we'll fall back to creating
298790
+ }
298791
+ // 3) Create new comment and register
298792
+ const created = await octokit.rest.issues.createComment({
298793
+ owner,
298794
+ repo,
298795
+ issue_number: pullNumber,
298796
+ body: fullBody,
298797
+ });
298798
+ const newId = created?.data?.id;
298799
+ if (newId !== undefined) {
298800
+ await writeStickyIdToPrBody(octokit, owner, repo, pullNumber, kind, newId);
298801
+ }
298802
+ });
298803
+ }
298804
+
298704
298805
  ;// CONCATENATED MODULE: ../github/src/pull_request.ts
298705
298806
 
298706
298807
 
298808
+
298707
298809
  const commentMaxSize = 65535;
298708
- async function commentInPR(comment, pr_number, repo, owner = 'prefapp') {
298810
+ async function commentInPR(comment, pr_number, repo, owner = 'prefapp', stickyKind) {
298709
298811
  try {
298710
298812
  github_src_logger.info(`Commenting ${comment} in PR ${pr_number} of ${owner}/${repo}`);
298711
298813
  const octokit = await getOctokitForOrg(owner);
298712
- await octokit.rest.issues.createComment({
298713
- owner,
298714
- repo,
298715
- issue_number: pr_number,
298716
- body: comment,
298717
- });
298814
+ if (stickyKind) {
298815
+ await upsertStickyComment(octokit, {
298816
+ owner,
298817
+ repo,
298818
+ pullNumber: pr_number,
298819
+ kind: stickyKind,
298820
+ body: comment,
298821
+ });
298822
+ }
298823
+ else {
298824
+ await octokit.rest.issues.createComment({
298825
+ owner,
298826
+ repo,
298827
+ issue_number: pr_number,
298828
+ body: comment,
298829
+ });
298830
+ }
298718
298831
  }
298719
298832
  catch (e) {
298720
298833
  console.error(`Error commenting in PR: ${e}`);
@@ -298944,6 +299057,7 @@ async function createOrphanBranch(repo, branch, owner = 'prefapp') {
298944
299057
 
298945
299058
 
298946
299059
 
299060
+
298947
299061
  const FLUSH_TIMEOUT = 4; // seconds
298948
299062
  const GITHUB_OUTPUT_TEXT_LIMIT = 65000; // ~65k hard limit for output.text
298949
299063
  /**
@@ -299078,6 +299192,15 @@ class GithubCheckRun {
299078
299192
  text,
299079
299193
  },
299080
299194
  });
299195
+ if (this.includeCheckRunComment && this.pullNumber !== undefined) {
299196
+ try {
299197
+ await this.__ensureAndUpdateStickyComment(this.__buildCheckRunUrl());
299198
+ this.hasCommented = true;
299199
+ }
299200
+ catch {
299201
+ github_src_logger.warn('Error creating check run comment');
299202
+ }
299203
+ }
299081
299204
  this.closed = true;
299082
299205
  }
299083
299206
  catch (e) {
@@ -299091,42 +299214,36 @@ class GithubCheckRun {
299091
299214
  async __ensureCreated() {
299092
299215
  if (this.checkRunId)
299093
299216
  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({
299217
+ if (this.creatingPromise)
299218
+ return this.creatingPromise;
299219
+ this.creatingPromise = (async () => {
299220
+ const startedAt = new Date().toISOString();
299221
+ const res = await this.octokit.rest.checks.create({
299118
299222
  owner: this.owner,
299119
299223
  repo: this.repo,
299120
- issue_number: this.pullNumber,
299121
- body,
299224
+ name: this.name,
299225
+ head_sha: this.headSHA,
299226
+ status: 'in_progress',
299227
+ started_at: startedAt,
299228
+ details_url: this.detailsUrl,
299229
+ output: {
299230
+ title: this.title,
299231
+ summary: this._summaryOverride ?? '',
299232
+ text: undefined,
299233
+ },
299122
299234
  });
299123
- this.hasCommented = true;
299235
+ this.checkRunId = res.data.id;
299236
+ })();
299237
+ try {
299238
+ await this.creatingPromise;
299239
+ }
299240
+ finally {
299241
+ this.creatingPromise = undefined;
299124
299242
  }
299125
299243
  }
299126
299244
  async __updateCheckRun(allContent) {
299127
299245
  if (this.closed || this.closing)
299128
299246
  return;
299129
- await this.__ensureCreated();
299130
299247
  const { text, summary } = this.buildOutputTextAndSummary(allContent);
299131
299248
  await this.octokit.rest.checks.update({
299132
299249
  owner: this.owner,
@@ -299139,6 +299256,14 @@ class GithubCheckRun {
299139
299256
  text,
299140
299257
  },
299141
299258
  });
299259
+ if (this.includeCheckRunComment && this.pullNumber !== undefined) {
299260
+ try {
299261
+ await this.__ensureAndUpdateStickyComment(this.__buildCheckRunUrl());
299262
+ }
299263
+ catch (e) {
299264
+ github_src_logger.warn('Error updating check run comment:', e);
299265
+ }
299266
+ }
299142
299267
  }
299143
299268
  __buildCheckRunUrl() {
299144
299269
  if (this.checkRunId) {
@@ -299168,6 +299293,20 @@ class GithubCheckRun {
299168
299293
  }
299169
299294
  return { text, summary };
299170
299295
  }
299296
+ // Ensure a sticky comment exists and rewrite it entirely with the latest content.
299297
+ async __ensureAndUpdateStickyComment(link) {
299298
+ if (!this.includeCheckRunComment || this.pullNumber === undefined)
299299
+ return;
299300
+ const base = this.checkRunComment ?? '';
299301
+ const linkLine = base ? `${base}[here](${link})` : `[here](${link})`;
299302
+ await upsertStickyComment(this.octokit, {
299303
+ owner: this.owner,
299304
+ repo: this.repo,
299305
+ pullNumber: this.pullNumber,
299306
+ kind: `check-run:${this.name}`,
299307
+ body: linkLine,
299308
+ });
299309
+ }
299171
299310
  }
299172
299311
  // -------------------- Helpers --------------------
299173
299312
  function truncateRight(s, max) {
@@ -299185,11 +299324,12 @@ async function createCheckRunForOrg(org, owner, repo, name, opts) {
299185
299324
  const pr = opts?.pullNumber;
299186
299325
  const hasValidPrNumber = typeof pr === 'number' && Number.isInteger(pr) && pr > 0;
299187
299326
  if (!headSHA && hasValidPrNumber) {
299188
- headSHA = await getPrMergeCommitSHA(opts.pullNumber, repo, owner);
299327
+ headSHA = await getPrMergeCommitSHA(pr, repo, owner);
299189
299328
  }
299190
299329
  if (!headSHA) {
299191
299330
  throw new Error('createCheckRunForOrg: either opts.headSHA or opts.pullNumber must be provided');
299192
299331
  }
299332
+ github_src_logger.debug(`Creating check run ${name} in ${owner}/${repo} at ${headSHA}`);
299193
299333
  return new GithubCheckRun(octokit, {
299194
299334
  owner,
299195
299335
  repo,
@@ -299204,6 +299344,7 @@ async function createCheckRunForOrg(org, owner, repo, name, opts) {
299204
299344
  });
299205
299345
  }
299206
299346
  async function createCheckRun(owner, repo, name, opts) {
299347
+ github_src_logger.debug(`Creating check run ${name} in ${owner}/${repo}`);
299207
299348
  return createCheckRunForOrg(owner, owner, repo, name, opts);
299208
299349
  }
299209
299350
  const CheckRun = GithubCheckRun;
@@ -310215,9 +310356,6 @@ class RepoGithubDecanter extends GithubDecanter {
310215
310356
  }
310216
310357
  }
310217
310358
  __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
310359
  const directMaintainers = this.data.teamsAndMembers.directMembers
310222
310360
  .filter((member) => member.role === 'maintain')
310223
310361
  .map((member) => {
@@ -310243,7 +310381,6 @@ class RepoGithubDecanter extends GithubDecanter {
310243
310381
  path: '/maintainedBy',
310244
310382
  });
310245
310383
  }
310246
- importer_src_logger.debug("Decanting admins...");
310247
310384
  const directAdmins = this.data.teamsAndMembers.directMembers
310248
310385
  .filter((member) => member.role === 'admin')
310249
310386
  .map((member) => {
@@ -310279,7 +310416,6 @@ class RepoGithubDecanter extends GithubDecanter {
310279
310416
  path: '/providers/github/overrides',
310280
310417
  });
310281
310418
  }
310282
- importer_src_logger.debug("Decanting writers...");
310283
310419
  const directWriters = this.data.teamsAndMembers.directMembers
310284
310420
  .filter((member) => member.role === 'push')
310285
310421
  .map((member) => {
@@ -310295,8 +310431,6 @@ class RepoGithubDecanter extends GithubDecanter {
310295
310431
  .map((team) => {
310296
310432
  return `group:${team.name}`;
310297
310433
  });
310298
- console.log("--- 🚀 Team writers:");
310299
- console.dir(teamWriters, { depth: null });
310300
310434
  const writers = directWriters.concat(outsideWriters).concat(teamWriters);
310301
310435
  if (writers && writers.length > 0) {
310302
310436
  overrides['additionalWriters'] = writers;
@@ -310306,7 +310440,6 @@ class RepoGithubDecanter extends GithubDecanter {
310306
310440
  path: '/providers/github/overrides',
310307
310441
  });
310308
310442
  }
310309
- importer_src_logger.debug("Decanting readers...");
310310
310443
  const directReaders = this.data.teamsAndMembers.directMembers
310311
310444
  .filter((member) => member.role === 'pull')
310312
310445
  .map((member) => {
@@ -310335,13 +310468,11 @@ class RepoGithubDecanter extends GithubDecanter {
310335
310468
  async __gatherRepoTeamsAndMembers() {
310336
310469
  this.data['teamsAndMembers'] = {};
310337
310470
  const directMembers = (await github_0.repo.getCollaborators(this.data.repoDetails.owner.login, this.data.repoDetails.name, 'direct')).map((member) => {
310338
- return { name: member.login, slug: member.slug, role: member.role_name };
310471
+ return { name: member.login, role: member.role_name };
310339
310472
  });
310340
310473
  const outsideMembers = (await github_0.repo.getCollaborators(this.data.repoDetails.owner.login, this.data.repoDetails.name, 'outside')).map((member) => {
310341
310474
  return { name: member.login, role: member.role_name };
310342
310475
  });
310343
- console.debug("--- 🚀 Gathered repo's teams and members:");
310344
- console.dir(this.githubTeams, { depth: null });
310345
310476
  const teams = Object.keys(this.githubTeams).map((teamName) => {
310346
310477
  return {
310347
310478
  name: teamName,
@@ -310506,8 +310637,6 @@ class RepoCollectionGithubDecanter extends GithubDecanter {
310506
310637
  const filteredRepos = await this.filter(RepoCollectionGithubDecanter.collectionKind, filters, repoList.map((repo) => repo.name));
310507
310638
  for (const repoName of filteredRepos) {
310508
310639
  const repoInfo = await this.github.repo.getRepoInfo(this.org, repoName);
310509
- console.log(`--- 🚀 Processing repo: ${repoName}`);
310510
- console.dir(directAccessRepos, { depth: null });
310511
310640
  repos.push(new RepoGithubDecanter({ repoDetails: repoInfo }, this.org, directAccessRepos?.[repoName]));
310512
310641
  }
310513
310642
  this.data['collection'] = repos;
@@ -311531,7 +311660,7 @@ async function writePlanInGithubPR(prUrl, planText) {
311531
311660
  ${planText}
311532
311661
  \`\`\`
311533
311662
  `;
311534
- await github_0.pulls.commentInPR(message, +pr_number, repo, owner);
311663
+ await github_0.pulls.commentInPR(message, +pr_number, repo, owner, 'logs');
311535
311664
  }
311536
311665
  catch (err) {
311537
311666
  operator_src_logger.error(`writePlanInGithubPR: Cannot write plan in PR: ${err}`);
@@ -311629,7 +311758,6 @@ async function updateDryRun(manifest, namespace) {
311629
311758
 
311630
311759
 
311631
311760
 
311632
-
311633
311761
  /**
311634
311762
  * Execute the callbacks for each item in the store
311635
311763
  * @param {string} plural - Kind to observe
@@ -311686,7 +311814,9 @@ async function observe(plural, namespace, onAdd, onChange, onDelete, _onRename)
311686
311814
  operator_src_logger.error(`An error occurred in the reflector for '${plural}' in namespace '${namespace}': '${err}'.`);
311687
311815
  setTimeout(async () => {
311688
311816
  try {
311817
+ operator_src_logger.warn(`Trying to recover from the error: "${err}" for '${plural}' in '${namespace}'`);
311689
311818
  await informer.start();
311819
+ operator_src_logger.warn(`Recovered from the error: "${err}" for '${plural}' in '${namespace}'`);
311690
311820
  }
311691
311821
  catch (err) {
311692
311822
  operator_src_logger.error(`Failed to start the reflector informer for '${plural}' in namespace '${namespace}': '${err}'.`);
@@ -311696,9 +311826,8 @@ async function observe(plural, namespace, onAdd, onChange, onDelete, _onRename)
311696
311826
  await informer.start();
311697
311827
  }
311698
311828
  catch (err) {
311699
- console.error(`Observing: ${plural}: ${err}`);
311700
- catalog_common.io.writeFunctionLog('observer', `Error Observing: ${plural}: ${err}`);
311701
- throw `Observing: ${plural}: ${err}`;
311829
+ operator_src_logger.error(`Observing: ${plural}: ${err}`);
311830
+ throw new Error(`Observing: ${plural}: ${err}`);
311702
311831
  }
311703
311832
  }
311704
311833
 
@@ -314653,7 +314782,7 @@ async function tryPublishDestroy(item, destroyOutput) {
314653
314782
  let currentCommentNo = 1;
314654
314783
  for (const commentContent of dividedOutput) {
314655
314784
  const comment = `<h1>
314656
- <img width="25" src="https://static-00.iconduck.com/assets.00/file-type-terraform-icon-1821x2048-mbxeegff.png"> Terraform destroy
314785
+ <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Destroy Finished
314657
314786
  </h1>
314658
314787
  <p><b>TFWorkspace: </b>${item.metadata.name}</p>
314659
314788
 
@@ -314665,7 +314794,7 @@ ${commentContent}
314665
314794
  \`\`\`
314666
314795
  </details>`;
314667
314796
  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}'.`);
314668
- await github_0.pulls.commentInPR(comment, lastPr.number, repo, org);
314797
+ await github_0.pulls.commentInPR(comment, lastPr.number, repo, org, 'logs');
314669
314798
  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}'.`);
314670
314799
  currentCommentNo += 1;
314671
314800
  }
@@ -314680,7 +314809,7 @@ async function publishApply(item, applyOutput, kind) {
314680
314809
  let currentCommentNo = 1;
314681
314810
  for (const commentContent of dividedOutput) {
314682
314811
  const comment = `<h1>
314683
- <img width="25" src="https://static-00.iconduck.com/assets.00/file-type-terraform-icon-1821x2048-mbxeegff.png"> Terraform apply
314812
+ <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Apply Finished
314684
314813
  </h1>
314685
314814
  <p><b>${kind}: </b>${item.metadata.name}</p>
314686
314815
 
@@ -314691,7 +314820,7 @@ async function publishApply(item, applyOutput, kind) {
314691
314820
  ${commentContent}
314692
314821
  \`\`\`
314693
314822
  </details>`;
314694
- await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org);
314823
+ await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org, 'logs');
314695
314824
  currentCommentNo += 1;
314696
314825
  }
314697
314826
  }
@@ -314740,7 +314869,7 @@ async function publishError(item, reason, message) {
314740
314869
  #### â„šī¸ Details:
314741
314870
  ${message}
314742
314871
  `;
314743
- await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org);
314872
+ await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org, 'logs');
314744
314873
  }
314745
314874
  async function publishPlan(item, planOutput, prNumber, repo, org) {
314746
314875
  try {
@@ -314748,7 +314877,7 @@ async function publishPlan(item, planOutput, prNumber, repo, org) {
314748
314877
  let currentCommentNo = 1;
314749
314878
  for (const commentContent of dividedOutput) {
314750
314879
  const comment = `<h1>
314751
- <img width="25" src="https://static-00.iconduck.com/assets.00/file-type-terraform-icon-1821x2048-mbxeegff.png"> Terraform plan
314880
+ <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Plan Finished
314752
314881
  </h1>
314753
314882
  <p><b>TFWorkspace: </b>${item.metadata.name}</p>
314754
314883
 
@@ -314759,7 +314888,7 @@ async function publishPlan(item, planOutput, prNumber, repo, org) {
314759
314888
  ${commentContent}
314760
314889
  \`\`\`
314761
314890
  </details>`;
314762
- await github_0.pulls.commentInPR(comment, prNumber, repo, org);
314891
+ await github_0.pulls.commentInPR(comment, prNumber, repo, org, 'logs');
314763
314892
  currentCommentNo += 1;
314764
314893
  }
314765
314894
  }
@@ -314798,7 +314927,7 @@ async function GHCheckRun(cmd, item) {
314798
314927
  };
314799
314928
  }
314800
314929
  function helperCreateCheckRunName(cmd, item) {
314801
- return `Github Provisioner / ${item.kind} - ${cmd}`;
314930
+ return `${item.kind} - ${cmd}`;
314802
314931
  }
314803
314932
  function gh_checkrun_extractPrInfo(item) {
314804
314933
  const prInfo = item.metadata.annotations['firestartr.dev/last-state-pr'];
@@ -314951,7 +315080,7 @@ async function* markedToDeletion(item, op, handler) {
314951
315080
  },
314952
315081
  logStreamCallbacksTF: {
314953
315082
  prepare: async () => {
314954
- checkRunCtl = await GHCheckRun('terraform destroy', item);
315083
+ checkRunCtl = await GHCheckRun('destroy', item);
314955
315084
  return checkRunCtl;
314956
315085
  },
314957
315086
  },
@@ -315075,7 +315204,7 @@ async function* doApply(item, op, handler) {
315075
315204
  },
315076
315205
  logStreamCallbacksTF: {
315077
315206
  prepare: async () => {
315078
- checkRunCtl = await GHCheckRun('terraform apply', item);
315207
+ checkRunCtl = await GHCheckRun('apply', item);
315079
315208
  return checkRunCtl;
315080
315209
  },
315081
315210
  },
@@ -317511,7 +317640,7 @@ async function processOperationPlan_publishPlan(item, planOutput) {
317511
317640
  let currentCommentNo = 1;
317512
317641
  for (const commentContent of dividedOutput) {
317513
317642
  const comment = `<h1>
317514
- <img width="25" src="https://static-00.iconduck.com/assets.00/file-type-terraform-icon-1821x2048-mbxeegff.png"> Terraform plan
317643
+ <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Plan Finished
317515
317644
  </h1>
317516
317645
  <p><b>TFWorkspace: </b>${item.metadata.name}</p>
317517
317646
 
@@ -317522,7 +317651,7 @@ async function processOperationPlan_publishPlan(item, planOutput) {
317522
317651
  ${commentContent}
317523
317652
  \`\`\`
317524
317653
  </details>`;
317525
- await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org);
317654
+ await github_0.pulls.commentInPR(comment, parseInt(prNumber), repo, org, 'logs');
317526
317655
  currentCommentNo += 1;
317527
317656
  }
317528
317657
  }
@@ -1,8 +1,14 @@
1
1
  import { Octokit } from '@octokit/rest';
2
+ import type { Api } from '@octokit/plugin-rest-endpoint-methods/dist-types/types';
3
+ import type { PaginateInterface } from '@octokit/plugin-paginate-rest/dist-types/types';
4
+ import type { paginateGraphQLInterface } from "@octokit/plugin-paginate-graphql/dist-types/index.js";
2
5
  export declare const generateGithubAppToken: (config: any) => Promise<string>;
3
6
  export declare function getGithubAppToken(org: string, genGithubAppToken?: any): Promise<string>;
4
- export declare function getOctokitForOrg(org: string, paginated?: boolean, genGithubAppToken?: any): Promise<Octokit>;
5
- export declare function getOctokitFromPat(envVar: string): Promise<Octokit>;
7
+ type OctoType = Octokit & Api & {
8
+ paginate: PaginateInterface;
9
+ } & paginateGraphQLInterface;
10
+ export declare function getOctokitForOrg(org: string, paginated?: boolean, genGithubAppToken?: any): Promise<OctoType>;
11
+ export declare function getOctokitFromPat(envVar: string): Promise<OctoType>;
6
12
  declare const _default: {
7
13
  getOctokitForOrg: typeof getOctokitForOrg;
8
14
  };
@@ -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-32",
3
+ "version": "1.50.1-snapshot-36",
4
4
  "private": false,
5
5
  "description": "Commandline tool",
6
6
  "main": "build/main.js",