mirror of
https://github.com/matrix-org/matrix-hookshot.git
synced 2025-03-10 21:19:13 +00:00
Add support for GitHub workflow run completion events (#520)
* Add support for workflow run completions * Create 520.feature
This commit is contained in:
parent
db3caeae03
commit
b8cc1f962f
1
changelog.d/520.feature
Normal file
1
changelog.d/520.feature
Normal file
@ -0,0 +1 @@
|
||||
Add support for notifying when a GitHub workflow completes.
|
@ -322,6 +322,12 @@ export class Bridge {
|
||||
(c, data) => c.onPRReviewed(data),
|
||||
);
|
||||
|
||||
this.bindHandlerToQueue<GitHubWebhookTypes.WorkflowRunCompletedEvent, GitHubRepoConnection>(
|
||||
"github.workflow_run.completed",
|
||||
(data) => connManager.getConnectionsForGithubRepo(data.repository.owner.login, data.repository.name),
|
||||
(c, data) => c.onWorkflowCompleted(data),
|
||||
);
|
||||
|
||||
this.bindHandlerToQueue<GitHubWebhookTypes.ReleaseCreatedEvent, GitHubRepoConnection>(
|
||||
"github.release.created",
|
||||
(data) => connManager.getConnectionsForGithubRepo(data.repository.owner.login, data.repository.name),
|
||||
|
@ -5,7 +5,10 @@ import { CommentProcessor } from "../CommentProcessor";
|
||||
import { FormatUtil } from "../FormatUtil";
|
||||
import { Connection, IConnection, IConnectionState, InstantiateConnectionOpts, ProvisionConnectionOpts } from "./IConnection";
|
||||
import { GetConnectionsResponseItem } from "../provisioning/api";
|
||||
import { IssuesOpenedEvent, IssuesReopenedEvent, IssuesEditedEvent, PullRequestOpenedEvent, IssuesClosedEvent, PullRequestClosedEvent, PullRequestReadyForReviewEvent, PullRequestReviewSubmittedEvent, ReleaseCreatedEvent, IssuesLabeledEvent, IssuesUnlabeledEvent } from "@octokit/webhooks-types";
|
||||
import { IssuesOpenedEvent, IssuesReopenedEvent, IssuesEditedEvent, PullRequestOpenedEvent, IssuesClosedEvent, PullRequestClosedEvent,
|
||||
PullRequestReadyForReviewEvent, PullRequestReviewSubmittedEvent, ReleaseCreatedEvent, IssuesLabeledEvent, IssuesUnlabeledEvent,
|
||||
WorkflowRunCompletedEvent,
|
||||
} from "@octokit/webhooks-types";
|
||||
import { MatrixMessageContent, MatrixEvent, MatrixReactionContent } from "../MatrixEvent";
|
||||
import { MessageSenderClient } from "../MatrixSender";
|
||||
import { CommandError, NotLoggedInError } from "../errors";
|
||||
@ -50,6 +53,9 @@ export interface GitHubRepoConnectionOptions extends IConnectionState {
|
||||
newIssue?: {
|
||||
labels: string[];
|
||||
};
|
||||
workflowRun?: {
|
||||
matchingBranch?: string;
|
||||
}
|
||||
}
|
||||
export interface GitHubRepoConnectionState extends GitHubRepoConnectionOptions {
|
||||
org: string;
|
||||
@ -84,7 +90,16 @@ type AllowedEventsNames =
|
||||
"pull_request.reviewed" |
|
||||
"pull_request" |
|
||||
"release.created" |
|
||||
"release";
|
||||
"release" |
|
||||
"workflow" |
|
||||
"workflow.run" |
|
||||
"workflow.run.success" |
|
||||
"workflow.run.failure" |
|
||||
"workflow.run.neutral" |
|
||||
"workflow.run.cancelled" |
|
||||
"workflow.run.timed_out" |
|
||||
"workflow.run.action_required" |
|
||||
"workflow.run.stale";
|
||||
|
||||
const AllowedEvents: AllowedEventsNames[] = [
|
||||
"issue.changed" ,
|
||||
@ -100,6 +115,15 @@ const AllowedEvents: AllowedEventsNames[] = [
|
||||
"pull_request" ,
|
||||
"release.created" ,
|
||||
"release",
|
||||
"workflow",
|
||||
"workflow.run",
|
||||
"workflow.run.success",
|
||||
"workflow.run.failure",
|
||||
"workflow.run.neutral",
|
||||
"workflow.run.cancelled",
|
||||
"workflow.run.timed_out",
|
||||
"workflow.run.action_required",
|
||||
"workflow.run.stale",
|
||||
];
|
||||
|
||||
const ConnectionStateSchema = {
|
||||
@ -173,6 +197,16 @@ const ConnectionStateSchema = {
|
||||
}, {
|
||||
type: "boolean",
|
||||
}],
|
||||
},
|
||||
workflowRun: {
|
||||
type: "object",
|
||||
nullable: true,
|
||||
properties: {
|
||||
matchingBranch: {
|
||||
nullable: true,
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
required: [
|
||||
@ -215,6 +249,16 @@ const EMOJI_TO_REVIEW_STATE = {
|
||||
'🔴🚫⛔️': 'REQUEST_CHANGES',
|
||||
};
|
||||
|
||||
const WORKFLOW_CONCLUSION_TO_NOTICE: Record<WorkflowRunCompletedEvent["workflow_run"]["conclusion"], string> = {
|
||||
success: "completed sucessfully 🎉",
|
||||
failure: "failed 😟",
|
||||
neutral: "completed neutrally 😐",
|
||||
cancelled: "was cancelled 🙅",
|
||||
timed_out: "timed out ⏰",
|
||||
action_required: "requires further action 🖱️",
|
||||
stale: "completed, but is stale 🍞"
|
||||
}
|
||||
|
||||
const LABELED_DEBOUNCE_MS = 5000;
|
||||
const CREATED_GRACE_PERIOD_MS = 6000;
|
||||
const DEFAULT_HOTLINK_PREFIX = "#";
|
||||
@ -981,6 +1025,30 @@ ${event.release.body}`;
|
||||
format: "org.matrix.custom.html",
|
||||
});
|
||||
}
|
||||
|
||||
public async onWorkflowCompleted(event: WorkflowRunCompletedEvent) {
|
||||
const workflowRun = event.workflow_run;
|
||||
const workflowRunType = `workflow.run.${workflowRun.conclusion}`;
|
||||
// Type safety checked above.
|
||||
if (
|
||||
this.shouldSkipHook('workflow', 'workflow.run', workflowRunType as AllowedEventsNames)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.state.workflowRun?.matchingBranch && !workflowRun.head_branch.match(this.state.workflowRun?.matchingBranch)) {
|
||||
return;
|
||||
}
|
||||
log.info(`onWorkflowCompleted ${this.roomId} ${this.org}/${this.repo} '${workflowRun.id}'`);
|
||||
const orgRepoName = event.repository.full_name;
|
||||
const content = `Workflow **${event.workflow.name}** [${WORKFLOW_CONCLUSION_TO_NOTICE[workflowRun.conclusion]}](${workflowRun.html_url}) for ${orgRepoName} on branch \`${workflowRun.head_branch}\``;
|
||||
await this.as.botIntent.sendEvent(this.roomId, {
|
||||
msgtype: "m.notice",
|
||||
body: content,
|
||||
formatted_body: md.render(content),
|
||||
format: "org.matrix.custom.html",
|
||||
});
|
||||
}
|
||||
|
||||
public async onEvent(evt: MatrixEvent<unknown>) {
|
||||
const octokit = await this.tokenStore.getOctokitForUser(evt.sender);
|
||||
if (!octokit) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user