Skip to content

Commit

Permalink
feat: publish multiple modules in the same pr
Browse files Browse the repository at this point in the history
  • Loading branch information
kormide committed Sep 21, 2024
1 parent 82a77ee commit cb018b8
Show file tree
Hide file tree
Showing 9 changed files with 400 additions and 124 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Prepare your ruleset for bzlmod by following the [Bzlmod User Guide](https://baz

## Publishing multiple modules in the same repo

You can publish BCR entries for multiple modules that exist in your git repository by configuring [`moduleRoots`](./templates/README.md#optional-configyml).
Multple modules that are versioned together in the same git repository can be published by configuring [`moduleRoots`](./templates/README.md#optional-configyml).

## Including patches

Expand Down
135 changes: 133 additions & 2 deletions e2e/__snapshots__/e2e.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,28 @@ modules/no-prefix/metadata.json
"
`;

exports[`e2e tests [snapshot] error message for incorrect strip prefix 1`] = `
"Failed to publish entry for testorg/versioned@v1.0.0 to the Bazel Central Registry.
exports[`e2e tests [snapshot] error email for incorrect strip prefix 1`] = `
"TO: releaser@test.org, foo@test.org
SUBJECT: Publish to BCR
Failed to publish entry for testorg/versioned@v1.0.0 to the Bazel Central Registry.
Could not find MODULE.bazel in release archive at ./versioned-1.0.0/MODULE.bazel.
Is the strip prefix in source.template.json correct? (currently it's 'versioned-1.0.0')
"
`;

exports[`e2e tests [snapshot] error email for incorrect strip prefix in multi module repo 1`] = `
"TO: releaser@test.org, foo@test.org, moo@test.org
SUBJECT: Publish to BCR
Failed to publish entry for testorg/multi-module@v1.0.0 to the Bazel Central Registry.
Failed to download release archive from http://localhost:8001/testorg/multi-module/releases/download/v1.0.0.tar.gz. Received status 503
"
`;

Expand Down Expand Up @@ -122,6 +138,121 @@ modules/empty-prefix/metadata.json
"
`;

exports[`e2e tests [snapshot] multiple modules 1`] = `
"----------------------------------------------------
modules/module/1.0.0/MODULE.bazel
----------------------------------------------------
module(
name = \\"module\\",
version = \\"1.0.0\\",
)
----------------------------------------------------
modules/module/1.0.0/presubmit.yml
----------------------------------------------------
bcr_test_module:
module_path: \\"e2e/bzlmod\\"
matrix:
platform: [\\"debian10\\", \\"macos\\", \\"ubuntu2004\\", \\"windows\\"]
bazel: [6.x, 7.x]
tasks:
run_tests:
name: \\"Run test module\\"
platform: \${{ platform }}
bazel: \${{ bazel }}
test_targets:
- \\"//...\\"
----------------------------------------------------
modules/module/1.0.0/source.json
----------------------------------------------------
{
\\"integrity\\": \\"sha256-yjUiRsFFe2FdefykIyd4CMmF/v12UDm4L/IrqiVkOHU=\\",
\\"strip_prefix\\": \\"multi-module-1.0.0\\",
\\"url\\": \\"https://github.com/testorg/multi-module/releases/download/v1.0.0.tar.gz\\"
}
----------------------------------------------------
modules/module/metadata.json
----------------------------------------------------
{
\\"homepage\\": \\"https://github.com/testorg/multi-module\\",
\\"maintainers\\": [
{
\\"name\\": \\"Foo McBar\\",
\\"email\\": \\"foo@test.org\\",
\\"github\\": \\"foobar\\"
}
],
\\"repository\\": [
\\"github:testorg/multi-module\\"
],
\\"versions\\": [
\\"1.0.0\\"
],
\\"yanked_versions\\": {}
}
----------------------------------------------------
modules/submodule/1.0.0/MODULE.bazel
----------------------------------------------------
module(
name = \\"submodule\\",
version = \\"1.0.0\\",
)
----------------------------------------------------
modules/submodule/1.0.0/presubmit.yml
----------------------------------------------------
bcr_test_module:
module_path: \\"e2e/bzlmod\\"
matrix:
platform: [\\"debian10\\", \\"macos\\", \\"ubuntu2004\\", \\"windows\\"]
bazel: [6.x, 7.x]
tasks:
run_tests:
name: \\"Run test module\\"
platform: \${{ platform }}
bazel: \${{ bazel }}
test_targets:
- \\"//...\\"
----------------------------------------------------
modules/submodule/1.0.0/source.json
----------------------------------------------------
{
\\"integrity\\": \\"sha256-yjUiRsFFe2FdefykIyd4CMmF/v12UDm4L/IrqiVkOHU=\\",
\\"strip_prefix\\": \\"multi-module-1.0.0/submodule\\",
\\"url\\": \\"https://github.com/testorg/multi-module/releases/download/v1.0.0.tar.gz\\"
}
----------------------------------------------------
modules/submodule/metadata.json
----------------------------------------------------
{
\\"homepage\\": \\"https://github.com/testorg/multi-module\\",
\\"maintainers\\": [
{
\\"name\\": \\"Foo McBar\\",
\\"email\\": \\"foo@test.org\\",
\\"github\\": \\"foobar\\"
},
{
\\"name\\": \\"Moo Cow\\",
\\"email\\": \\"moo@test.org\\",
\\"github\\": \\"moocow\\"
}
],
\\"repository\\": [
\\"github:testorg/multi-module\\"
],
\\"versions\\": [
\\"1.0.0\\"
],
\\"yanked_versions\\": {}
}
"
`;

exports[`e2e tests [snapshot] ruleset with tarball release archive 1`] = `
"----------------------------------------------------
modules/tarball/1.0.0/MODULE.bazel
Expand Down
122 changes: 100 additions & 22 deletions e2e/e2e.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ReturnTypeOf } from "@octokit/core/dist-types/types";
import { User } from "@octokit/webhooks-types";
import { ImapFlow } from "imapflow";
import { ParsedMail } from "mailparser";
import { CompletedRequest } from "mockttp";
import { randomBytes } from "node:crypto";
import fs from "node:fs";
Expand Down Expand Up @@ -375,6 +376,46 @@ describe("e2e tests", () => {
expect(snapshot).toMatchSnapshot();
});

test("[snapshot] multiple modules", async () => {
const repo = Fixture.MultiModule;
const tag = "v1.0.0";
await setupLocalRemoteRulesetRepo(repo, tag, releaser);

fakeGitHub.mockUser(releaser);
fakeGitHub.mockRepository(testOrg, repo);
fakeGitHub.mockRepository(
testOrg,
"bazel-central-registry",
"bazelbuild",
"bazel-central-registry"
);
const installationId = fakeGitHub.mockAppInstallation(testOrg, repo);
fakeGitHub.mockAppInstallation(testOrg, "bazel-central-registry");

const releaseArchive = await makeReleaseTarball(repo, "multi-module-1.0.0");

await fakeGitHub.mockReleaseArchive(
`/${testOrg}/${repo}/releases/download/${tag}.tar.gz`,
releaseArchive
);

const response = await publishReleaseEvent(
cloudFunctions.getBaseUrl(),
secrets.webhookSecret,
installationId,
{
owner: testOrg,
repo,
tag,
releaser,
}
);
expect(response.status).toEqual(200);

const snapshot = await rollupEntryFiles();
expect(snapshot).toMatchSnapshot();
});

test("happy path", async () => {
const repo = Fixture.Versioned;
const tag = "v1.0.0";
Expand Down Expand Up @@ -491,8 +532,8 @@ describe("e2e tests", () => {
const messages = await fetchEmails(emailClient);
expect(messages.length).toEqual(0);

// Two pull requests were created with the corrects params
expect(fakeGitHub.pullRequestHandler).toHaveBeenCalledTimes(2);
// One pull requests was created with the corrects params
expect(fakeGitHub.pullRequestHandler).toHaveBeenCalledTimes(1);
let request = fakeGitHub.pullRequestHandler.mock
.calls[0][0] as CompletedRequest;
expect(request.path).toEqual(
Expand All @@ -505,23 +546,7 @@ describe("e2e tests", () => {
head: expect.stringMatching(
new RegExp(`${testOrg}\\:${testOrg}\\/${repo}@${tag}-.+`)
),
title: "module@1.0.0",
})
);

request = fakeGitHub.pullRequestHandler.mock
.calls[1][0] as CompletedRequest;
expect(request.path).toEqual(
expect.stringMatching(/bazelbuild\/bazel-central-registry/)
);
body = (await request.body.getJson()) as any;
expect(body).toEqual(
expect.objectContaining({
base: "main",
head: expect.stringMatching(
new RegExp(`${testOrg}\\:${testOrg}\\/${repo}@${tag}-.+`)
),
title: "submodule@1.0.0",
title: "module@1.0.0, submodule@1.0.0",
})
);
});
Expand Down Expand Up @@ -667,7 +692,7 @@ describe("e2e tests", () => {
// Function exited normally
expect(response.status).toEqual(200);

// No error emails were sent
// Email was sent
const messages = await fetchEmails(emailClient);
expect(messages.length).toEqual(1);

Expand Down Expand Up @@ -729,7 +754,7 @@ describe("e2e tests", () => {
expect(logs.latest?.author_name).toEqual("publish-to-bcr-bot");
});

test("[snapshot] error message for incorrect strip prefix", async () => {
test("[snapshot] error email for incorrect strip prefix", async () => {
const repo = Fixture.Versioned;
const tag = "v1.0.0";
await setupLocalRemoteRulesetRepo(repo, tag, releaser);
Expand Down Expand Up @@ -768,7 +793,51 @@ describe("e2e tests", () => {

const messages = await fetchEmails(emailClient);
expect(messages.length).toEqual(1);
expect(messages[0].text).toMatchSnapshot();

expect(emailSnapshot(messages[0])).toMatchSnapshot();
});

test("[snapshot] error email for incorrect strip prefix in multi module repo", async () => {
const repo = Fixture.MultiModule;
const tag = "v1.0.0";
await setupLocalRemoteRulesetRepo(repo, tag, releaser);

fakeGitHub.mockUser(releaser);
fakeGitHub.mockRepository(testOrg, repo);
fakeGitHub.mockRepository(
testOrg,
"bazel-central-registry",
"bazelbuild",
"bazel-central-registry"
);
const rulesetInstallationId = fakeGitHub.mockAppInstallation(testOrg, repo);
fakeGitHub.mockAppInstallation(testOrg, "bazel-central-registry");

// Strip prefix in release archive doesn't match source.template.json
const releaseArchive = await makeReleaseTarball(repo, "invalid-prefix");
await fakeGitHub.mockReleaseArchive(
`/${testOrg}/${repo}/archive/refs/tags/${tag}.tar.gz`,
releaseArchive
);

const response = await publishReleaseEvent(
cloudFunctions.getBaseUrl(),
secrets.webhookSecret,
rulesetInstallationId,
{
owner: testOrg,
repo,
tag,
releaser,
}
);

expect(response.status).toEqual(200);

const messages = await fetchEmails(emailClient);
expect(messages.length).toEqual(1);

expect(emailSnapshot(messages[0])).toMatchSnapshot();
});
});

Expand Down Expand Up @@ -820,6 +889,15 @@ ${fileContent}
return content;
}

function emailSnapshot(email: ParsedMail): string {
return `\
TO: ${(Array.isArray(email.to) ? email.to : [email.to]).map((to) => to?.text)}
SUBJECT: ${email.subject}
${email.text}
`;
}

export function mockSecrets(
fakeSecrets: FakeSecrets,
emailAccount: TestAccount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
"name": "Foo McBar",
"email": "foo@test.org",
"github": "foobar"
},
{
"name": "Moo Cow",
"email": "moo@test.org",
"github": "moocow"
}
],
"repository": ["github:testorg/multi-module"],
Expand Down
2 changes: 1 addition & 1 deletion src/application/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ 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 ${JSON.stringify(recipients)}`);
console.log(`Sending error email to ${recipients.join(", ")}`);
console.log(`Subject: ${subject}`);
console.log(`Content:`);
console.log(content);
Expand Down
Loading

0 comments on commit cb018b8

Please sign in to comment.