Skip to content

Commit

Permalink
feat: notify maintainers of releases and issues
Browse files Browse the repository at this point in the history
  • Loading branch information
kormide committed Oct 30, 2023
1 parent e30cbc0 commit a09cb13
Show file tree
Hide file tree
Showing 24 changed files with 907 additions and 167 deletions.
2 changes: 1 addition & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export default {
// setupFiles: [],

// A list of paths to modules that run some code to configure or set up the testing framework before each test
// setupFilesAfterEnv: [],
setupFilesAfterEnv: ["./jest.setup.ts"],

// The number of seconds after which a test is considered as slow and reported as such in the results.
// slowTestThreshold: 5,
Expand Down
64 changes: 64 additions & 0 deletions jest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
declare global {
namespace jest {
interface Matchers<R> {
toThrowErrorContaining<T extends Error>(
errorType: new (...args: any[]) => T,
message: string
): R;
}
}
}

expect.extend({
toThrowErrorContaining<T extends Error>(
func: Function,
errorType: new (...args: any[]) => T,
message: string
) {
try {
func();
} catch (e) {
if (!(e instanceof errorType)) {
return {
pass: false,
message: () => `\
Expected error to throw:
${errorType}
But instead it threw:
${e.constructor}
`,
};
}

if (!e.message.includes(message)) {
return {
pass: false,
message: () => `\
Expected error message to contain:
${message}
But instead it was:
${e.message}
`,
};
}

return {
pass: true,
message: () => "",
};
}

return {
pass: false,
message: () => "Expected function to throw but it did not",
};
},
});

export default undefined;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
"yaml": "^2.1.1"
},
"devDependencies": {
"@jest/globals": "^28.1.3",
"@types/diff": "^5.0.2",
"@types/jest": "^29.5.6",
"@types/node": "^18.6.2",
"@types/nodemailer": "^6.4.5",
"@types/source-map-support": "^0.5.4",
Expand Down
48 changes: 35 additions & 13 deletions src/application/notifications.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { UserFacingError } from "../domain/error.js";
import { Maintainer } from "../domain/metadata-file.js";
import { User } from "../domain/user.js";
import { Authentication, EmailClient } from "../infrastructure/email.js";
import { SecretsClient } from "../infrastructure/secrets.js";
Expand Down Expand Up @@ -38,27 +39,41 @@ export class NotificationsService {
}

public async notifyError(
recipient: User,
releaseAuthor: User,
maintainers: ReadonlyArray<Maintainer>,
repoCanonicalName: string,
tag: string,
errors: Error[]
): Promise<void> {
await this.setAuth();

await this.sendErrorEmailToUser(recipient, repoCanonicalName, tag, errors);
// Send an error email to the release author as well
// as any maintainers that have their email listed.
const recipientEmails = new Set<string>();
recipientEmails.add(releaseAuthor.email);
maintainers
.filter((m) => !!m.email)
.forEach((m) => recipientEmails.add(m.email));

await this.sendErrorEmail(
Array.from(recipientEmails),
repoCanonicalName,
tag,
errors
);

if (this.debugEmail) {
await this.sendErrorEmailToDevs(
recipient,
releaseAuthor,
repoCanonicalName,
tag,
errors
);
}
}

private async sendErrorEmailToUser(
recipient: User,
private async sendErrorEmail(
recipients: string[],
repoCanonicalName: string,
tag: string,
errors: Error[]
Expand All @@ -83,21 +98,20 @@ Failed to publish entry for ${repoCanonicalName}@${tag} to the Bazel Central Reg
"An unknown error occurred. Please report an issue here: https://github.com/bazel-contrib/publish-to-bcr/issues.";
}

console.log(`Sending error email to ${recipient.email}`);
console.log(`Sending error email to ${JSON.stringify(recipients)}`);
console.log(`Subject: ${subject}`);
console.log(`Content:`);
console.log(content);

await this.emailClient.sendEmail(
recipient.email,
this.sender,
subject,
content
await Promise.all(
recipients.map((email) =>
this.emailClient.sendEmail(email, this.sender, subject, content)
)
);
}

private async sendErrorEmailToDevs(
user: User,
releaseAuthor: User,
repoCanonicalName: string,
tag: string,
errors: Error[]
Expand All @@ -113,7 +127,7 @@ Failed to publish entry for ${repoCanonicalName}@${tag} to the Bazel Central Reg
}

let content = `\
User ${user.username} <${user.email}> encountered ${unknownErrors.length} unknown error(s) trying publish entry for ${repoCanonicalName}@${tag} to the Bazel Central Registry.
User ${releaseAuthor.username} <${releaseAuthor.email}> encountered ${unknownErrors.length} unknown error(s) trying publish entry for ${repoCanonicalName}@${tag} to the Bazel Central Registry.
`;
for (let error of unknownErrors) {
Expand All @@ -128,3 +142,11 @@ User ${user.username} <${user.email}> encountered ${unknownErrors.length} unknow
);
}
}

function uniqueUsers(...users: User[]): User[] {
const usersByEmail = users.reduce<{ [email: string]: User }>(
(acc, curr) => ({ ...acc, [curr.email]: curr }),
{}
);
return Object.values(usersByEmail);
}
Loading

0 comments on commit a09cb13

Please sign in to comment.