Split out GitHub release events into created and drafted (#582)

* Support published events

* Changelog

* Improve comments

* Add frontend support

* Change func names
This commit is contained in:
Will Hunt 2022-12-08 02:48:56 +00:00 committed by GitHub
parent 7d74f1b1a8
commit b6ae8f9106
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 8 deletions

1
changelog.d/582.bugfix Normal file
View File

@ -0,0 +1 @@
Ensure bridge treats published and drafted GitHub releases as different events.

View File

@ -65,6 +65,7 @@ Note: Some of these event types are enabled by default (marked with a `*`)
- pull_request.reviewed * - pull_request.reviewed *
- release * - release *
- release.created * - release.created *
- release.drafted
- workflow.run - workflow.run
- workflow.run.success - workflow.run.success
- workflow.run.failure - workflow.run.failure

View File

@ -328,10 +328,16 @@ export class Bridge {
(c, data) => c.onWorkflowCompleted(data), (c, data) => c.onWorkflowCompleted(data),
); );
this.bindHandlerToQueue<GitHubWebhookTypes.ReleasePublishedEvent, GitHubRepoConnection>(
"github.release.published",
(data) => connManager.getConnectionsForGithubRepo(data.repository.owner.login, data.repository.name),
(c, data) => c.onReleaseCreated(data),
);
this.bindHandlerToQueue<GitHubWebhookTypes.ReleaseCreatedEvent, GitHubRepoConnection>( this.bindHandlerToQueue<GitHubWebhookTypes.ReleaseCreatedEvent, GitHubRepoConnection>(
"github.release.created", "github.release.created",
(data) => connManager.getConnectionsForGithubRepo(data.repository.owner.login, data.repository.name), (data) => connManager.getConnectionsForGithubRepo(data.repository.owner.login, data.repository.name),
(c, data) => c.onReleaseCreated(data), (c, data) => c.onReleaseDrafted(data),
); );
this.bindHandlerToQueue<IGitLabWebhookMREvent, GitLabRepoConnection>( this.bindHandlerToQueue<IGitLabWebhookMREvent, GitLabRepoConnection>(

View File

@ -6,8 +6,8 @@ import { FormatUtil } from "../FormatUtil";
import { Connection, IConnection, IConnectionState, InstantiateConnectionOpts, ProvisionConnectionOpts } from "./IConnection"; import { Connection, IConnection, IConnectionState, InstantiateConnectionOpts, ProvisionConnectionOpts } from "./IConnection";
import { GetConnectionsResponseItem } from "../provisioning/api"; import { GetConnectionsResponseItem } from "../provisioning/api";
import { IssuesOpenedEvent, IssuesReopenedEvent, IssuesEditedEvent, PullRequestOpenedEvent, IssuesClosedEvent, PullRequestClosedEvent, import { IssuesOpenedEvent, IssuesReopenedEvent, IssuesEditedEvent, PullRequestOpenedEvent, IssuesClosedEvent, PullRequestClosedEvent,
PullRequestReadyForReviewEvent, PullRequestReviewSubmittedEvent, ReleaseCreatedEvent, IssuesLabeledEvent, IssuesUnlabeledEvent, PullRequestReadyForReviewEvent, PullRequestReviewSubmittedEvent, ReleasePublishedEvent, ReleaseCreatedEvent,
WorkflowRunCompletedEvent, IssuesLabeledEvent, IssuesUnlabeledEvent, WorkflowRunCompletedEvent,
} from "@octokit/webhooks-types"; } from "@octokit/webhooks-types";
import { MatrixMessageContent, MatrixEvent, MatrixReactionContent } from "../MatrixEvent"; import { MatrixMessageContent, MatrixEvent, MatrixReactionContent } from "../MatrixEvent";
import { MessageSenderClient } from "../MatrixSender"; import { MessageSenderClient } from "../MatrixSender";
@ -94,6 +94,7 @@ type AllowedEventsNames =
"pull_request.reviewed" | "pull_request.reviewed" |
"pull_request" | "pull_request" |
"release.created" | "release.created" |
"release.drafted" |
"release" | "release" |
"workflow" | "workflow" |
"workflow.run" | "workflow.run" |
@ -118,6 +119,7 @@ const AllowedEvents: AllowedEventsNames[] = [
"pull_request.reviewed" , "pull_request.reviewed" ,
"pull_request" , "pull_request" ,
"release.created" , "release.created" ,
"release.drafted" ,
"release", "release",
"workflow", "workflow",
"workflow.run", "workflow.run",
@ -137,7 +139,7 @@ const AllowedEvents: AllowedEventsNames[] = [
const AllowHookByDefault: AllowedEventsNames[] = [ const AllowHookByDefault: AllowedEventsNames[] = [
"issue", "issue",
"pull_request", "pull_request",
"release", "release.created"
]; ];
const ConnectionStateSchema = { const ConnectionStateSchema = {
@ -1069,7 +1071,11 @@ export class GitHubRepoConnection extends CommandConnection<GitHubRepoConnection
}); });
} }
public async onReleaseCreated(event: ReleaseCreatedEvent) { public async onReleaseCreated(event: ReleasePublishedEvent) {
// This checks `release.created` despite the function being called onReleasePublished
// because historically release.created used to refer to all releases (rather than just published ones).
// This is now considered an *unsafe* default, so hookshot now treats release.created
// as published.
if (this.hookFilter.shouldSkip('release', 'release.created')) { if (this.hookFilter.shouldSkip('release', 'release.created')) {
return; return;
} }
@ -1081,9 +1087,36 @@ export class GitHubRepoConnection extends CommandConnection<GitHubRepoConnection
throw Error('No repository content!'); throw Error('No repository content!');
} }
const orgRepoName = event.repository.full_name; const orgRepoName = event.repository.full_name;
const content = `**${event.sender.login}** 🪄 released [${event.release.name}](${event.release.html_url}) for ${orgRepoName} let content = `**${event.sender.login}** 🪄 released [${event.release.name ?? event.release.tag_name}](${event.release.html_url}) for ${orgRepoName}`;
if (event.release.body) {
content += `\n\n${event.release.body}`
}
await this.as.botIntent.sendEvent(this.roomId, {
msgtype: "m.notice",
body: content,
formatted_body: md.render(content),
format: "org.matrix.custom.html",
});
}
${event.release.body}`; public async onReleaseDrafted(event: ReleaseCreatedEvent) {
// This function handles release.created events but published releases are handled by the above function,
// therefore this only handles drafted releases.
if (this.hookFilter.shouldSkip('release', 'release.drafted') || !event.release.draft) {
return;
}
log.info(`onReleaseDrafted ${this.roomId} ${this.org}/${this.repo} #${event.release.tag_name}`);
if (!event.release) {
throw Error('No release content!');
}
if (!event.repository) {
throw Error('No repository content!');
}
const orgRepoName = event.repository.full_name;
let content = `**${event.sender.login}** 🪄 drafted release [${event.release.name ?? event.release.tag_name}](${event.release.html_url}) for ${orgRepoName}`;
if (event.release.body) {
content += `\n\n${event.release.body}`
}
await this.as.botIntent.sendEvent(this.roomId, { await this.as.botIntent.sendEvent(this.roomId, {
msgtype: "m.notice", msgtype: "m.notice",
body: content, body: content,

View File

@ -245,7 +245,11 @@ const ConnectionConfiguration: FunctionComponent<ConnectionConfigurationProps<ne
<EventCheckbox enabledHooks={enabledHooks} ignoredHooks={ignoredHooks} parentEvent="workflow.run" eventName="workflow.run.action_required" onChange={toggleEnabledHook}>Action Required</EventCheckbox> <EventCheckbox enabledHooks={enabledHooks} ignoredHooks={ignoredHooks} parentEvent="workflow.run" eventName="workflow.run.action_required" onChange={toggleEnabledHook}>Action Required</EventCheckbox>
<EventCheckbox enabledHooks={enabledHooks} ignoredHooks={ignoredHooks} parentEvent="workflow.run" eventName="workflow.run.stale" onChange={toggleEnabledHook}>Stale</EventCheckbox> <EventCheckbox enabledHooks={enabledHooks} ignoredHooks={ignoredHooks} parentEvent="workflow.run" eventName="workflow.run.stale" onChange={toggleEnabledHook}>Stale</EventCheckbox>
</ul> </ul>
<EventCheckbox ignoredHooks={ignoredHooks} eventName="release" onChange={toggleIgnoredHook}>Releases</EventCheckbox> <EventCheckbox enabledHooks={enabledHooks} ignoredHooks={ignoredHooks} eventName="release" onChange={toggleIgnoredHook}>Releases</EventCheckbox>
<ul>
<EventCheckbox enabledHooks={enabledHooks} ignoredHooks={ignoredHooks} parentEvent="release" eventName="release.created" onChange={toggleIgnoredHook}>Published</EventCheckbox>
<EventCheckbox enabledHooks={enabledHooks} ignoredHooks={ignoredHooks} parentEvent="release" eventName="release.drafted" onChange={toggleEnabledHook}>Drafted</EventCheckbox>
</ul>
</ul> </ul>
</InputField> </InputField>
<ButtonSet> <ButtonSet>