Closed zmiklank closed 1 week ago
Here is an example of implementation I use in our GA. It's based on probot/metadata
javascript library, which works only for GitHub Apps (Bots).
Example of implementation from redhat-plumbers-in-action/devel-freezer
:
source: https://github.com/redhat-plumbers-in-action/devel-freezer/blob/main/src/metadata.ts#L84-L142
/**
* Based on probot-metadata - https://github.com/probot/metadata
*/
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class MetadataController {
static readonly regex = /\n\n<!-- devel-freezer = (.*) -->/;
static async getMetadata(issueNumber: number, key: string, context: Context) {
const body =
(
await context.octokit.issues.get(
context.issue({ issue_number: issueNumber })
)
).data.body || '';
const match = body.match(MetadataController.regex);
if (match) {
const data = JSON.parse(match[1]);
return key ? data && data[key] : data;
}
}
static async setMetadata(
key: string,
value: string,
context: Context,
issueNumber?: number
) {
let body =
(
await context.octokit.issues.get(
context.issue(issueNumber ? { issue_number: issueNumber } : {})
)
).data.body || '';
let data = {};
body = body.replace(MetadataController.regex, (_, json) => {
data = JSON.parse(json);
return '';
});
if (!data) data = {};
if (typeof key === 'object') {
Object.assign(data, key);
} else {
(data as { [key: string]: string })[key] = value;
}
return context.octokit.issues.update(
context.issue({
body: `${body}\n\n<!-- devel-freezer = ${JSON.stringify(data)} -->`,
...(issueNumber ? { issue_number: issueNumber } : {}),
})
);
}
}
source: https://github.com/redhat-plumbers-in-action/devel-freezer/blob/main/src/pull-request.ts#L57-L110
private async publishComment(
content: string,
context: {
[K in keyof typeof events]: Context<(typeof events)[K][number]>;
}[keyof typeof events]
) {
if (this.metadata.commentID) {
this.updateComment(content, context);
return;
}
const commentPayload = (await this.createComment(content, context))?.data;
if (!commentPayload) {
warning(`Failed to create comment.`);
return;
}
return commentPayload.id;
}
private createComment(
body: string,
context: {
[K in keyof typeof events]: Context<(typeof events)[K][number]>;
}[keyof typeof events]
) {
if (!body || body === '') return;
return context.octokit.issues.createComment(
// !FIXME: This is wrong, don't use `as`
(context as Context<(typeof events.pull_request)[number]>).issue({
issue_number: this.id,
body,
})
);
}
private async updateComment(
body: string,
context: {
[K in keyof typeof events]: Context<(typeof events)[K][number]>;
}[keyof typeof events]
) {
if (!this.metadata.commentID) return;
return context.octokit.issues.updateComment(
// !FIXME: This is wrong, don't use `as`
(context as Context<(typeof events.pull_request)[number]>).issue({
comment_id: +this.metadata.commentID,
body,
})
);
}
We can use, e.g., https://github.com/marocchino/sticky-pull-request-comment
Only nice to have.