Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore reporting "Do Not Merge" PRs in Discord #293

Merged
merged 9 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .sourcekit-lsp/config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"backgroundIndexing": true,
"backgroundPreparationMode": "build",
"backgroundPreparationMode": "enabled",
"maxCoresPercentageToUseForBackgroundIndexing": 0.7,
"experimentalFeatures": ["on-type-formatting"]
}
7 changes: 7 additions & 0 deletions Lambdas/GHHooks/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ enum Constants {
static let guildID: GuildSnowflake = "431917998102675485"
static let botDevUserID: UserSnowflake = "290483761559240704"

static let trustedGitHubUserIds: [Int64] = [
69_189_821, // Paul
9_938_337, // Tim
1_130_717, // Gwynne
54_685_446, // Mahdi
]

enum GitHub {
/// The user id of Penny.
static let userID = 139_480_971
Expand Down
9 changes: 7 additions & 2 deletions Lambdas/GHHooks/EventHandler/Handlers/PRCoinGiver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ struct PRCoinGiver {
repoFullName: repo.fullName,
branch: branch
)
for pr in try await getPRsRelatedToCommit() {
guard pr.mergedAt != nil else { continue }
for pr in prs {
if pr.mergedAt == nil {
logger.debug("PR is not merged yet", metadata: ["pr": "\(pr)"])
continue
}
let user = try pr.user.requireValue()
var usersToReceiveCoins = codeOwners.contains(user: user) ? [] : [user.id]

Expand Down Expand Up @@ -88,6 +91,8 @@ struct PRCoinGiver {
}

func giveCoin(userId: Int64, pr: SimplePullRequest) async throws {
logger.trace("Giving a coin", metadata: ["userId": .stringConvertible(userId)])

guard
let member = try await context.requester.getDiscordMember(
githubID: "\(userId)"
Expand Down
2 changes: 2 additions & 0 deletions Lambdas/GHHooks/EventHandler/Handlers/PRHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,12 @@ struct PRHandler {
}

func onEdited() async throws {
if self.pr.isIgnorableDoNotMergePR { return }
try await self.editPRReport()
}

func onOpened() async throws {
if self.pr.isIgnorableDoNotMergePR { return }
try await self.makeReporter().reportCreation()
}

Expand Down
20 changes: 10 additions & 10 deletions Lambdas/GHHooks/EventHandler/Handlers/ReleaseMaker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,9 @@ struct ReleaseMaker {
}

func isNewContributor(codeOwners: CodeOwners, existingContributors: Set<Int64>) -> Bool {
pr.authorAssociation != .owner && !pr.user.isBot && !codeOwners.contains(user: pr.user)
pr.authorAssociation != .owner
&& !pr.user.isBot
&& !codeOwners.contains(user: pr.user)
&& !existingContributors.contains(pr.user.id)
}

Expand All @@ -305,9 +307,9 @@ struct ReleaseMaker {
)
)

guard case let .ok(ok) = response,
case let .json(json) = ok.body
else {
do {
return try response.ok.body.json
} catch {
logger.warning(
"Could not find reviews",
metadata: [
Expand All @@ -316,8 +318,6 @@ struct ReleaseMaker {
)
return []
}

return json
}

func getExistingContributorIDs() async throws -> Set<Int64> {
Expand Down Expand Up @@ -357,9 +357,9 @@ struct ReleaseMaker {
)
)

if case let .ok(ok) = response,
case let .json(json) = ok.body
{
do {
let ok = try response.ok
let json = try ok.body.json
/// Example of a `link` header: `<https://api.github.com/repositories/49910095/contributors?page=6>; rel="prev", <https://api.github.com/repositories/49910095/contributors?page=8>; rel="next", <https://api.github.com/repositories/49910095/contributors?page=8>; rel="last", <https://api.github.com/repositories/49910095/contributors?page=1>; rel="first"`
/// If the header contains `rel="next"` then we'll have a next page to fetch.
let hasNext =
Expand All @@ -378,7 +378,7 @@ struct ReleaseMaker {
]
)
return (ids, hasNext)
} else {
} catch {
logger.error(
"Error when fetching contributors but will continue",
metadata: [
Expand Down
39 changes: 0 additions & 39 deletions Lambdas/GHHooks/Extensions/+PR.Label.swift

This file was deleted.

92 changes: 92 additions & 0 deletions Lambdas/GHHooks/Extensions/+PR.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import GitHubAPI

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif

extension PullRequest {

enum KnownLabel: String {
case semVerMajor = "semver-major"
case semVerMinor = "semver-minor"
case semVerPatch = "semver-patch"
case semVerNoOp = "semver-noop"
case release = "release"
case noReleaseNeeded = "no-release-needed"
case translationUpdate = "translation-update"
case noTranslationNeeded = "no-translation-needed"

func toBump() -> SemVerBump? {
switch self {
case .semVerMajor: return .major
case .semVerMinor: return .minor
case .semVerPatch: return .patch
case .release: return .releaseStage
case .semVerNoOp, .noReleaseNeeded, .translationUpdate, .noTranslationNeeded: return nil
}
}
}

var knownLabels: [KnownLabel] {
self.labels.compactMap {
KnownLabel(rawValue: $0.name)
}
}

var isIgnorableDoNotMergePR: Bool {
isIgnorableDoNotMergePullRequest(
title: self.title,
userId: self.user.id,
authorAssociation: self.authorAssociation
)
}
}

extension SimplePullRequest {
var knownLabels: [PullRequest.KnownLabel] {
self.labels.compactMap {
PullRequest.KnownLabel(rawValue: $0.name)
}
}

var isIgnorableDoNotMergePR: Bool {
isIgnorableDoNotMergePullRequest(
title: self.title,
userId: self.user?.id,
authorAssociation: self.authorAssociation
)
}
}

private func isIgnorableDoNotMergePullRequest(
title: String,
userId: Int64?,
authorAssociation: AuthorAssociation
) -> Bool {
let isTrustedUser = userId.map { Constants.trustedGitHubUserIds.contains($0) } ?? false
guard isTrustedUser || authorAssociation.isContributorOrHigher else {
return false
}
return title.hasDoNotMergePrefix
}

extension AuthorAssociation {
fileprivate var isContributorOrHigher: Bool {
switch self {
case .collaborator, .contributor, .owner: return true
case .member, .firstTimer, .firstTimeContributor, .mannequin, .none: return false
}
}
}

extension String {
fileprivate var hasDoNotMergePrefix: Bool {
let folded = self.lowercased()
.filter { !$0.isPunctuation }
.folding(options: .caseInsensitive, locale: nil)
.folding(options: .diacriticInsensitive, locale: nil)
return folded.hasPrefix("dnm") || folded.hasPrefix("do not merge")
}
}
1 change: 1 addition & 0 deletions Lambdas/GitHubAPI/Aliases.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package typealias Repository = Components.Schemas.Repository
package typealias User = Components.Schemas.SimpleUser
package typealias PullRequest = Components.Schemas.PullRequest
package typealias SimplePullRequest = Components.Schemas.PullRequestSimple
package typealias AuthorAssociation = Components.Schemas.AuthorAssociation
package typealias Issue = Components.Schemas.Issue
package typealias Label = Components.Schemas.Label
package typealias Release = Components.Schemas.Release
Expand Down
Loading