Skip to content

Commit a68a9c6

Browse files
authored
refactor: fix a layer violation causing a circular dependency (#192)
1 parent ca569c6 commit a68a9c6

File tree

14 files changed

+242
-137
lines changed

14 files changed

+242
-137
lines changed

e2e/e2e.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,7 @@ describe("e2e tests", () => {
729729
});
730730

731731
fakeGitHub.mockUser({
732-
login: GitHubClient.GITHUB_ACTIONS_BOT.username,
732+
login: GitHubClient.GITHUB_ACTIONS_BOT.login,
733733
id: GitHubClient.GITHUB_ACTIONS_BOT.id,
734734
});
735735
fakeGitHub.mockUser({ login: "publish-to-bcr-bot[bot]", id: 123 });

src/application/notifications.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { Inject, Injectable } from "@nestjs/common";
1+
import { Injectable } from "@nestjs/common";
22
import { UserFacingError } from "../domain/error.js";
33
import { Maintainer } from "../domain/metadata-file.js";
44
import { Repository } from "../domain/repository.js";
5-
import { User } from "../domain/user.js";
5+
import { User, UserService } from "../domain/user.js";
66
import { Authentication, EmailClient } from "../infrastructure/email.js";
7-
import { GitHubClient } from "../infrastructure/github.js";
87
import { SecretsClient } from "../infrastructure/secrets.js";
98

109
@Injectable()
@@ -16,7 +15,7 @@ export class NotificationsService {
1615
constructor(
1716
private readonly emailClient: EmailClient,
1817
private readonly secretsClient: SecretsClient,
19-
@Inject("rulesetRepoGitHubClient") private githubClient: GitHubClient
18+
private readonly userService: UserService
2019
) {
2120
if (process.env.NOTIFICATIONS_EMAIL === undefined) {
2221
throw new Error("Missing NOTIFICATIONS_EMAIL environment variable.");
@@ -70,7 +69,7 @@ export class NotificationsService {
7069
const fetchedEmails = (
7170
await Promise.all(
7271
maintainersWithOnlyGithubHandle.map((m) =>
73-
this.githubClient.getRepoUser(m.github, rulesetRepo)
72+
this.userService.getUser(m.github)
7473
)
7574
)
7675
)

src/application/release-event-handler.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
RulesetRepoError,
1212
RulesetRepository,
1313
} from "../domain/ruleset-repository.js";
14-
import { User } from "../domain/user.js";
14+
import { User, UserService } from "../domain/user.js";
1515
import { GitHubClient } from "../infrastructure/github.js";
1616
import { NotificationsService } from "./notifications.js";
1717

@@ -24,9 +24,8 @@ interface PublishAttempt {
2424
@Injectable()
2525
export class ReleaseEventHandler {
2626
constructor(
27-
@Inject("rulesetRepoGitHubClient")
28-
private rulesetRepoGitHubClient: GitHubClient,
2927
@Inject("appOctokit") private appOctokit: Octokit,
28+
private readonly userService: UserService,
3029
private readonly findRegistryForkService: FindRegistryForkService,
3130
private readonly createEntryService: CreateEntryService,
3231
private readonly publishEntryService: PublishEntryService,
@@ -40,10 +39,7 @@ export class ReleaseEventHandler {
4039
process.env.BAZEL_CENTRAL_REGISTRY
4140
);
4241

43-
let releaser = await this.rulesetRepoGitHubClient.getRepoUser(
44-
event.payload.sender.login,
45-
repository
46-
);
42+
let releaser = await this.userService.getUser(event.payload.sender.login);
4743
const releaseUrl = event.payload.release.html_url;
4844

4945
const tag = event.payload.release.tag_name;
@@ -117,7 +113,8 @@ export class ReleaseEventHandler {
117113
for (let bcrFork of candidateBcrForks) {
118114
const bcrForkGitHubClient = await GitHubClient.forRepoInstallation(
119115
this.appOctokit,
120-
bcrFork
116+
bcrFork.owner,
117+
bcrFork.name
121118
);
122119

123120
const attempt = await this.attemptPublish(
@@ -275,9 +272,8 @@ export class ReleaseEventHandler {
275272
);
276273

277274
// Fetch the releaser to get their name
278-
const fixedReleaser = await this.rulesetRepoGitHubClient.getRepoUser(
279-
rulesetRepo.config.fixedReleaser.login,
280-
rulesetRepo
275+
const fixedReleaser = await this.userService.getUser(
276+
rulesetRepo.config.fixedReleaser.login
281277
);
282278

283279
return {

src/application/webhook/app.module.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { Module } from "@nestjs/common";
22
import { CreateEntryService } from "../../domain/create-entry.js";
33
import { FindRegistryForkService } from "../../domain/find-registry-fork.js";
44
import { PublishEntryService } from "../../domain/publish-entry.js";
5+
import { RepositoryService } from "../../domain/repository.js";
6+
import { UserService } from "../../domain/user.js";
57
import { EmailClient } from "../../infrastructure/email.js";
68
import { GitClient } from "../../infrastructure/git.js";
79
import { SecretsClient } from "../../infrastructure/secrets.js";
@@ -24,6 +26,8 @@ import {
2426
CreateEntryService,
2527
FindRegistryForkService,
2628
PublishEntryService,
29+
RepositoryService,
30+
UserService,
2731
APP_OCTOKIT_PROVIDER,
2832
BCR_APP_OCTOKIT_PROVIDER,
2933
RULESET_REPO_GITHUB_CLIENT_PROVIDER,

src/application/webhook/providers.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ export const RULESET_REPO_GITHUB_CLIENT_PROVIDER: Provider = {
4747

4848
const githubClient = await GitHubClient.forRepoInstallation(
4949
appOctokit,
50-
rulesetRepo,
50+
rulesetRepo.owner,
51+
rulesetRepo.name,
5152
installationId
5253
);
5354
return githubClient;
@@ -67,7 +68,8 @@ export const BCR_GITHUB_CLIENT_PROVIDER: Provider = {
6768

6869
const githubClient = await GitHubClient.forRepoInstallation(
6970
bcrAppOctokit,
70-
bcr
71+
bcr.owner,
72+
bcr.name
7173
);
7274
return githubClient;
7375
},

src/domain/create-entry.spec.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import fs, { PathLike } from "node:fs";
66
import os from "node:os";
77
import path from "node:path";
88
import { GitClient } from "../infrastructure/git";
9-
import { GitHubApp, GitHubClient } from "../infrastructure/github";
9+
import {
10+
GitHubApp,
11+
GitHubClient,
12+
User as GitHubUser,
13+
} from "../infrastructure/github";
1014
import {
1115
fakeMetadataFile,
1216
fakeModuleFile,
@@ -26,7 +30,7 @@ import { ModuleFile } from "./module-file";
2630
import { ReleaseArchive } from "./release-archive";
2731
import { Repository } from "./repository";
2832
import { RulesetRepository } from "./ruleset-repository";
29-
import { User } from "./user";
33+
import { User, UserService } from "./user";
3034

3135
let createEntryService: CreateEntryService;
3236
let mockGitClient: Mocked<GitClient>;
@@ -942,16 +946,18 @@ describe("commitEntryToNewBranch", () => {
942946
const tag = "v1.2.3";
943947
const rulesetRepo = await RulesetRepository.create("repo", "owner", tag);
944948
const bcrRepo = CANONICAL_BCR;
945-
const releaser = GitHubClient.GITHUB_ACTIONS_BOT;
946-
const botUser: User = {
949+
const releaser = UserService.fromGitHubUser(
950+
GitHubClient.GITHUB_ACTIONS_BOT
951+
);
952+
const botUser: Partial<GitHubUser> = {
947953
name: "publish-to-bcr",
948-
username: "publish-to-bcr[bot]",
954+
login: "publish-to-bcr[bot]",
949955
email: `12345+"publish-to-bcr[bot]@users.noreply.github.com`,
950956
};
951957
const botApp = { slug: "publish-to-bcr" } as GitHubApp;
952958

953959
mockBcrGitHubClient.getApp.mockResolvedValue(botApp);
954-
mockBcrGitHubClient.getBotAppUser.mockResolvedValue(botUser);
960+
mockBcrGitHubClient.getBotAppUser.mockResolvedValue(botUser as GitHubUser);
955961

956962
await createEntryService.commitEntryToNewBranch(
957963
rulesetRepo,
@@ -1105,7 +1111,7 @@ describe("pushEntryToFork", () => {
11051111
);
11061112
expect(
11071113
mockBcrForkGitHubClient.getAuthenticatedRemoteUrl
1108-
).toHaveBeenCalledWith(bcrForkRepo);
1114+
).toHaveBeenCalledWith(bcrForkRepo.owner, bcrForkRepo.name);
11091115
});
11101116

11111117
test("adds a remote with the authenticated url for the fork to the local bcr repo", async () => {

src/domain/create-entry.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { ReleaseArchive } from "./release-archive.js";
1717
import { Repository } from "./repository.js";
1818
import { RulesetRepository } from "./ruleset-repository.js";
1919
import { SourceTemplate } from "./source-template.js";
20-
import { User } from "./user.js";
20+
import { User, UserService } from "./user.js";
2121

2222
export class VersionAlreadyPublishedError extends UserFacingError {
2323
public constructor(version: string) {
@@ -44,7 +44,10 @@ export class CreateEntryService {
4444
tag: string,
4545
moduleRoot: string
4646
): Promise<{ moduleName: string }> {
47-
await Promise.all([rulesetRepo.shallowCloneAndCheckout(tag), bcrRepo.shallowCloneAndCheckout("main")]);
47+
await Promise.all([
48+
rulesetRepo.shallowCloneAndCheckout(tag),
49+
bcrRepo.shallowCloneAndCheckout("main"),
50+
]);
4851

4952
const version = RulesetRepository.getVersionFromTag(tag);
5053

@@ -123,7 +126,7 @@ export class CreateEntryService {
123126
const branchName = `${repoAndVersion}-${randomBytes(4).toString("hex")}`;
124127

125128
let commitAuthor: Partial<User> = releaser;
126-
if (releaser.username === GitHubClient.GITHUB_ACTIONS_BOT.username) {
129+
if (UserService.isGitHubActionsBot(releaser)) {
127130
const botApp = await this.bcrGitHubClient.getApp();
128131
const botAppUser = await this.bcrGitHubClient.getBotAppUser(botApp);
129132

@@ -157,7 +160,8 @@ export class CreateEntryService {
157160
githubClient: GitHubClient
158161
): Promise<void> {
159162
const authenticatedRemoteUrl = await githubClient.getAuthenticatedRemoteUrl(
160-
bcrForkRepo
163+
bcrForkRepo.owner,
164+
bcrForkRepo.name
161165
);
162166

163167
if (!(await this.gitClient.hasRemote(bcr.diskPath, "authed-fork"))) {

0 commit comments

Comments
 (0)