Skip to content

Commit 005281a

Browse files
committed
update/recreate comments instead of creating new
1 parent d9cf744 commit 005281a

File tree

6 files changed

+138
-20
lines changed

6 files changed

+138
-20
lines changed

.buildkite/package-lock.json

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.buildkite/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
"globby": "^11.1.0",
1616
"js-yaml": "^4.1.0",
1717
"minimatch": "^5.0.1",
18+
"minimist": "^1.2.8",
1819
"tslib": "*"
1920
},
2021
"devDependencies": {
2122
"@types/chai": "^4.3.3",
2223
"@types/js-yaml": "^4.0.5",
2324
"@types/minimatch": "^3.0.5",
25+
"@types/minimist": "^1.2.5",
2426
"@types/mocha": "^10.0.1",
2527
"@types/node": "^15.12.2",
2628
"chai": "^4.3.10",

.buildkite/pipeline-utils/github/github.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
import { Octokit, RestEndpointMethodTypes } from '@octokit/rest';
1111

12+
export const KIBANA_COMMENT_SIGIL = 'kbn-message-context';
13+
1214
const github = new Octokit({
1315
auth: process.env.GITHUB_TOKEN,
1416
});
@@ -113,6 +115,56 @@ export function addComment(
113115
});
114116
}
115117

118+
export async function upsertComment(
119+
messageOpts: {
120+
commentBody: string;
121+
commentContext: string;
122+
clearPrevious: boolean;
123+
},
124+
owner = process.env.GITHUB_PR_BASE_OWNER,
125+
repo = process.env.GITHUB_PR_BASE_REPO,
126+
prNumber: undefined | string | number = process.env.GITHUB_PR_NUMBER
127+
) {
128+
const { commentBody, commentContext, clearPrevious } = messageOpts;
129+
if (!owner || !repo || !prNumber) {
130+
throw Error(
131+
"Couldn't retrieve Github PR info from environment variables in order to add a comment"
132+
);
133+
}
134+
if (!commentContext) {
135+
throw Error('Comment context is required when updating a comment');
136+
}
137+
138+
const commentMarker = `<!-- ${KIBANA_COMMENT_SIGIL}:${commentContext} -->`;
139+
const body = `${commentMarker}${commentBody}`;
140+
141+
const existingComment = (
142+
await github.paginate(github.issues.listComments, {
143+
owner,
144+
repo,
145+
issue_number: typeof prNumber === 'number' ? prNumber : parseInt(prNumber, 10),
146+
})
147+
).find((comment) => comment.body?.includes(commentMarker));
148+
149+
if (!existingComment) {
150+
return addComment(body, owner, repo, prNumber);
151+
} else if (clearPrevious) {
152+
await github.issues.deleteComment({
153+
owner,
154+
repo,
155+
comment_id: existingComment.id,
156+
});
157+
return addComment(body, owner, repo, prNumber);
158+
} else {
159+
return github.issues.updateComment({
160+
owner,
161+
repo,
162+
comment_id: existingComment.id,
163+
body,
164+
});
165+
}
166+
}
167+
116168
export function getGithubClient() {
117169
return github;
118170
}

.buildkite/pipelines/build_pr_and_deploy_cloud.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ steps:
2222
limit: 1
2323

2424
- command: |
25-
ts-node .buildkite/scripts/lifecycle/comment_on_pr.ts "PR Cloud deployment started at: $BUILDKITE_BUILD_URL"
25+
ts-node .buildkite/scripts/lifecycle/comment_on_pr.ts \
26+
--message "PR Cloud deployment started at: $BUILDKITE_BUILD_URL" \
27+
--context "cloud-deploy-job" \
28+
--clear-previous
2629
label: Comment with job URL
2730
agents:
2831
provider: gcp
@@ -66,7 +69,10 @@ steps:
6669
- wait: ~
6770

6871
- command: |
69-
ts-node .buildkite/scripts/lifecycle/comment_on_pr.ts "Cloud deployment initiated, see credentials at: $BUILDKITE_BUILD_URL"
72+
ts-node .buildkite/scripts/lifecycle/comment_on_pr.ts \
73+
--message "Cloud deployment initiated, see credentials at: $BUILDKITE_BUILD_URL" \
74+
--context "cloud-deploy-job" \
75+
--clear-previous
7076
label: Comment with job URL
7177
agents:
7278
provider: gcp

.buildkite/pipelines/serverless_deployment/build_pr_and_deploy_project.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ steps:
2222
limit: 1
2323

2424
- command: |
25-
ts-node .buildkite/scripts/lifecycle/comment_on_pr.ts "PR Project deployment started at: $BUILDKITE_BUILD_URL"
25+
ts-node .buildkite/scripts/lifecycle/comment_on_pr.ts \
26+
--message "PR Project deployment started at: $BUILDKITE_BUILD_URL" \
27+
--context "project-deploy-job" \
28+
--clear-previous
2629
label: Comment with job URL
2730
agents:
2831
provider: gcp
@@ -62,7 +65,10 @@ steps:
6265
- wait: ~
6366

6467
- command: |
65-
ts-node .buildkite/scripts/lifecycle/comment_on_pr.ts "Project deployed, see credentials at: $BUILDKITE_BUILD_URL"
68+
ts-node .buildkite/scripts/lifecycle/comment_on_pr.ts \
69+
--message "Project deployed, see credentials at: $BUILDKITE_BUILD_URL" \
70+
--context "project-deploy-job" \
71+
--clear-previous
6672
label: Comment with job URL
6773
agents:
6874
provider: gcp

.buildkite/scripts/lifecycle/comment_on_pr.ts

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
* License v3.0 only", or the "Server Side Public License, v 1".
88
*/
99

10-
import { addComment } from '#pipeline-utils';
10+
import parseArgs from 'minimist';
11+
import { upsertComment, addComment } from '#pipeline-utils';
1112

1213
const ALLOWED_ENV_VARS = [
1314
'BUILDKITE_BRANCH',
@@ -31,20 +32,16 @@ const ALLOWED_ENV_VARS = [
3132
'GITHUB_PR_TRIGGER_USER',
3233
'GITHUB_PR_USER',
3334
];
34-
const DEFAULT_MESSAGE_TEMPLATE =
35-
'🚀 Buildkite job started for PR #${GITHUB_PR_NUMBER}: ${BUILDKITE_BUILD_URL}';
36-
37-
export function commentOnPR() {
38-
const messageTemplate =
39-
process.argv.slice(2)?.join(' ') ||
40-
process.env.JOB_START_COMMENT_TEMPLATE ||
41-
DEFAULT_MESSAGE_TEMPLATE;
42-
if (messageTemplate === DEFAULT_MESSAGE_TEMPLATE) {
43-
console.log('No message template provided, using default message');
44-
} else {
45-
console.log(`Using message template: ${messageTemplate}`);
46-
}
4735

36+
export function commentOnPR({
37+
messageTemplate,
38+
context,
39+
clearPrevious,
40+
}: {
41+
messageTemplate: string;
42+
context?: string;
43+
clearPrevious: boolean;
44+
}) {
4845
const message = messageTemplate.replace(/\${([^}]+)}/g, (_, envVar) => {
4946
if (ALLOWED_ENV_VARS.includes(envVar)) {
5047
return process.env[envVar] || '';
@@ -53,11 +50,39 @@ export function commentOnPR() {
5350
}
5451
});
5552

56-
return addComment(message);
53+
if (context) {
54+
return upsertComment({ commentBody: message, commentContext: context, clearPrevious });
55+
} else {
56+
return addComment(message);
57+
}
5758
}
5859

5960
if (require.main === module) {
60-
commentOnPR().catch((error) => {
61+
const args = parseArgs<{
62+
context?: string;
63+
message: string;
64+
'clear-previous'?: boolean | string;
65+
}>(process.argv.slice(2), {
66+
string: ['message', 'context'],
67+
boolean: ['clear-previous'],
68+
});
69+
70+
if (!args.message) {
71+
throw new Error(
72+
`No message template provided for ${process.argv[1]}, use --message to provide one.`
73+
);
74+
} else {
75+
console.log(`Using message template: ${args.message}`);
76+
}
77+
78+
commentOnPR({
79+
messageTemplate: args.message,
80+
context: args.context,
81+
clearPrevious:
82+
typeof args['clear-previous'] === 'string'
83+
? !!args['clear-previous'].match(/(1|true)/i)
84+
: !!args['clear-previous'],
85+
}).catch((error) => {
6186
console.error(error);
6287
process.exit(1);
6388
});

0 commit comments

Comments
 (0)