Skip to content

Commit 7229177

Browse files
committed
Merge remote-tracking branch 'origin/main' into MONGOSH-1928-dry-run-homebrew-release-fail
2 parents f35a972 + 2377d4a commit 7229177

21 files changed

+1028
-1192
lines changed

.evergreen.yml

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3780,6 +3780,23 @@ functions:
37803780
# - signature_tag (either 'signed' or 'unsigned')
37813781
###
37823782
add_crypt_shared_and_sbom:
3783+
- command: ec2.assume_role
3784+
display_name: Assume IAM role with permissions to pull Kondukto API token
3785+
params:
3786+
role_arn: ${kondukto_role_arn}
3787+
- command: shell.exec
3788+
display_name: Pull Kondukto API token from AWS Secrets Manager and write it to file
3789+
params:
3790+
silent: true
3791+
shell: bash
3792+
working_dir: src
3793+
include_expansions_in_env: [AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN]
3794+
script: |
3795+
set -e
3796+
# use AWS CLI to get the Kondukto API token from AWS Secrets Manager
3797+
kondukto_token=$(aws secretsmanager get-secret-value --secret-id "kondukto-token" --region "us-east-1" --query 'SecretString' --output text)
3798+
# set the KONDUKTO_TOKEN environment variable
3799+
echo "KONDUKTO_TOKEN=$kondukto_token" > /tmp/kondukto_credentials.env
37833800
- command: subprocess.exec
37843801
params:
37853802
working_dir: src
@@ -3790,10 +3807,8 @@ functions:
37903807
PACKAGE_VARIANT: ${package_variant}
37913808
ARTIFACTORY_USERNAME: ${artifactory_username}
37923809
ARTIFACTORY_PASSWORD: ${artifactory_password}
3793-
# for Silk SBOM integration
3794-
SILK_ASSET_GROUP: mongosh-${executable_os_id}
3795-
SILK_CLIENT_ID: ${silk_client_id}
3796-
SILK_CLIENT_SECRET: ${silk_client_secret}
3810+
# for Kondukto SBOM integration
3811+
KONDUKTO_BRANCH: ${branch_name}_${executable_os_id}
37973812
create_static_analysis_report:
37983813
- command: s3.get
37993814
params:

.evergreen/evergreen.yml.in

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,23 @@ functions:
489489
# - signature_tag (either 'signed' or 'unsigned')
490490
###
491491
add_crypt_shared_and_sbom:
492+
- command: ec2.assume_role
493+
display_name: Assume IAM role with permissions to pull Kondukto API token
494+
params:
495+
role_arn: ${kondukto_role_arn}
496+
- command: shell.exec
497+
display_name: Pull Kondukto API token from AWS Secrets Manager and write it to file
498+
params:
499+
silent: true
500+
shell: bash
501+
working_dir: src
502+
include_expansions_in_env: [AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN]
503+
script: |
504+
set -e
505+
# use AWS CLI to get the Kondukto API token from AWS Secrets Manager
506+
kondukto_token=$(aws secretsmanager get-secret-value --secret-id "kondukto-token" --region "us-east-1" --query 'SecretString' --output text)
507+
# set the KONDUKTO_TOKEN environment variable
508+
echo "KONDUKTO_TOKEN=$kondukto_token" > /tmp/kondukto_credentials.env
492509
- command: subprocess.exec
493510
params:
494511
working_dir: src
@@ -499,10 +516,8 @@ functions:
499516
PACKAGE_VARIANT: ${package_variant}
500517
ARTIFACTORY_USERNAME: ${artifactory_username}
501518
ARTIFACTORY_PASSWORD: ${artifactory_password}
502-
# for Silk SBOM integration
503-
SILK_ASSET_GROUP: mongosh-${executable_os_id}
504-
SILK_CLIENT_ID: ${silk_client_id}
505-
SILK_CLIENT_SECRET: ${silk_client_secret}
519+
# for Kondukto SBOM integration
520+
KONDUKTO_BRANCH: ${branch_name}_${executable_os_id}
506521
create_static_analysis_report:
507522
<%
508523
let firstPartyDepsFilenames = [];

THIRD_PARTY_NOTICES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
The following third-party software is used by and included in **mongosh**.
2-
This document was automatically generated on Tue Feb 25 2025.
2+
This document was automatically generated on Wed Feb 26 2025.
33

44
## List of dependencies
55

packages/build/src/homebrew/publish-to-homebrew.spec.ts

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
import chai, { expect } from 'chai';
22
import sinon from 'sinon';
33
import type { GithubRepo } from '@mongodb-js/devtools-github-repo';
4-
import { publishToHomebrew } from './publish-to-homebrew';
4+
import type { HomebrewPublisherConfig } from './publish-to-homebrew';
5+
import { HomebrewPublisher } from './publish-to-homebrew';
56

67
chai.use(require('sinon-chai'));
78

8-
describe('Homebrew publish-to-homebrew', function () {
9+
describe('HomebrewPublisher', function () {
910
let homebrewCore: GithubRepo;
1011
let homebrewCoreFork: GithubRepo;
1112
let createPullRequest: sinon.SinonStub;
1213
let httpsSha256: sinon.SinonStub;
1314
let generateFormula: sinon.SinonStub;
1415
let updateHomebrewFork: sinon.SinonStub;
1516

16-
beforeEach(function () {
17+
let testPublisher: HomebrewPublisher;
18+
19+
const setupHomebrewPublisher = (
20+
config: Omit<HomebrewPublisherConfig, 'homebrewCore' | 'homebrewCoreFork'>
21+
) => {
1722
createPullRequest = sinon.stub();
18-
httpsSha256 = sinon.stub();
19-
generateFormula = sinon.stub();
20-
updateHomebrewFork = sinon.stub();
2123

2224
homebrewCore = {
2325
repo: {
@@ -32,9 +34,33 @@ describe('Homebrew publish-to-homebrew', function () {
3234
repo: 'homebrew-core',
3335
},
3436
} as unknown as GithubRepo;
37+
38+
testPublisher = new HomebrewPublisher({
39+
...config,
40+
homebrewCore,
41+
homebrewCoreFork,
42+
});
43+
44+
httpsSha256 = sinon.stub(testPublisher, 'httpsSha256');
45+
generateFormula = sinon.stub(testPublisher, 'generateFormula');
46+
updateHomebrewFork = sinon.stub(testPublisher, 'updateHomebrewFork');
47+
};
48+
49+
beforeEach(function () {
50+
setupHomebrewPublisher({
51+
packageVersion: '1.0.0',
52+
githubReleaseLink: 'githubRelease',
53+
isDryRun: false,
54+
});
3555
});
3656

3757
it('creates and merges a PR on update and cleans up', async function () {
58+
setupHomebrewPublisher({
59+
packageVersion: '1.0.0',
60+
githubReleaseLink: 'githubRelease',
61+
isDryRun: false,
62+
});
63+
3864
httpsSha256
3965
.rejects()
4066
.withArgs(
@@ -69,16 +95,7 @@ describe('Homebrew publish-to-homebrew', function () {
6995
)
7096
.resolves({ prNumber: 42, url: 'url' });
7197

72-
await publishToHomebrew(
73-
homebrewCore,
74-
homebrewCoreFork,
75-
'1.0.0',
76-
'githubRelease',
77-
false,
78-
httpsSha256,
79-
generateFormula,
80-
updateHomebrewFork
81-
);
98+
await testPublisher.publish();
8299

83100
expect(httpsSha256).to.have.been.called;
84101
expect(generateFormula).to.have.been.called;
@@ -87,6 +104,12 @@ describe('Homebrew publish-to-homebrew', function () {
87104
});
88105

89106
it('does not try to push/merge when there is no formula update', async function () {
107+
setupHomebrewPublisher({
108+
packageVersion: '1.0.0',
109+
githubReleaseLink: 'githubRelease',
110+
isDryRun: false,
111+
});
112+
90113
httpsSha256
91114
.rejects()
92115
.withArgs(
@@ -111,16 +134,7 @@ describe('Homebrew publish-to-homebrew', function () {
111134
})
112135
.resolves(undefined);
113136

114-
await publishToHomebrew(
115-
homebrewCore,
116-
homebrewCoreFork,
117-
'1.0.0',
118-
'githubRelease',
119-
false,
120-
httpsSha256,
121-
generateFormula,
122-
updateHomebrewFork
123-
);
137+
await testPublisher.publish();
124138

125139
expect(httpsSha256).to.have.been.called;
126140
expect(generateFormula).to.have.been.called;
@@ -163,16 +177,7 @@ describe('Homebrew publish-to-homebrew', function () {
163177
)
164178
.resolves({ prNumber: 42, url: 'url' });
165179

166-
await publishToHomebrew(
167-
homebrewCore,
168-
homebrewCoreFork,
169-
'1.0.0',
170-
'githubRelease',
171-
false,
172-
httpsSha256,
173-
generateFormula,
174-
updateHomebrewFork
175-
);
180+
await testPublisher.publish();
176181

177182
expect(httpsSha256).to.have.been.called;
178183
expect(generateFormula).to.have.been.called;
Lines changed: 81 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,88 @@
11
import type { GithubRepo } from '@mongodb-js/devtools-github-repo';
2-
import { generateUpdatedFormula } from './generate-formula';
3-
import { updateHomebrewFork } from './update-homebrew-fork';
4-
import { httpsSha256 } from './utils';
5-
6-
export async function publishToHomebrew(
7-
homebrewCore: GithubRepo,
8-
homebrewCoreFork: GithubRepo,
9-
packageVersion: string,
10-
githubReleaseLink: string,
11-
isDryRun: boolean,
12-
httpsSha256Fn = httpsSha256,
13-
generateFormulaFn = generateUpdatedFormula,
14-
updateHomebrewForkFn = updateHomebrewFork
15-
): Promise<void> {
16-
const cliReplPackageUrl = `https://registry.npmjs.org/@mongosh/cli-repl/-/cli-repl-${packageVersion}.tgz`;
17-
const packageSha = isDryRun
18-
? `dryRun-fakesha256-${Date.now()}`
19-
: await httpsSha256Fn(cliReplPackageUrl);
20-
21-
const homebrewFormula = await generateFormulaFn(
22-
{ version: packageVersion, sha: packageSha },
23-
homebrewCore,
24-
isDryRun
25-
);
26-
if (!homebrewFormula) {
27-
console.warn('There are no changes to the homebrew formula');
28-
return;
29-
}
2+
import { generateUpdatedFormula as generateUpdatedFormulaFn } from './generate-formula';
3+
import { updateHomebrewFork as updateHomebrewForkFn } from './update-homebrew-fork';
4+
import { httpsSha256 as httpsSha256Fn } from './utils';
5+
6+
export type HomebrewPublisherConfig = {
7+
homebrewCore: GithubRepo;
8+
homebrewCoreFork: GithubRepo;
9+
packageVersion: string;
10+
githubReleaseLink: string;
11+
isDryRun?: boolean;
12+
};
3013

31-
const forkBranch = await updateHomebrewForkFn({
32-
packageVersion,
33-
packageSha,
34-
homebrewFormula,
35-
homebrewCore,
36-
homebrewCoreFork,
37-
isDryRun,
38-
});
39-
if (!forkBranch) {
40-
console.warn('There are no changes to the homebrew formula');
41-
return;
14+
export class HomebrewPublisher {
15+
readonly httpsSha256: typeof httpsSha256Fn;
16+
readonly generateFormula: typeof generateUpdatedFormulaFn;
17+
readonly updateHomebrewFork: typeof updateHomebrewForkFn;
18+
19+
constructor(
20+
public config: HomebrewPublisherConfig,
21+
{
22+
httpsSha256 = httpsSha256Fn,
23+
generateFormula = generateUpdatedFormulaFn,
24+
updateHomebrewFork = updateHomebrewForkFn,
25+
} = {}
26+
) {
27+
this.httpsSha256 = httpsSha256;
28+
this.generateFormula = generateFormula;
29+
this.updateHomebrewFork = updateHomebrewFork;
4230
}
4331

44-
const description = `This PR was created automatically and bumps \`mongosh\` to the latest published version \`${packageVersion}\`.\n\nFor additional details see ${githubReleaseLink}.`;
32+
async publish(): Promise<void> {
33+
const {
34+
isDryRun,
35+
homebrewCore,
36+
packageVersion,
37+
homebrewCoreFork,
38+
githubReleaseLink,
39+
} = this.config;
40+
41+
const cliReplPackageUrl = `https://registry.npmjs.org/@mongosh/cli-repl/-/cli-repl-${packageVersion}.tgz`;
42+
const packageSha = isDryRun
43+
? `dryRun-fakesha256-${Date.now()}`
44+
: await this.httpsSha256(cliReplPackageUrl);
45+
46+
const homebrewFormula = await this.generateFormula(
47+
{ version: packageVersion, sha: packageSha },
48+
homebrewCore,
49+
isDryRun || false
50+
);
51+
if (!homebrewFormula) {
52+
console.warn('There are no changes to the homebrew formula');
53+
return;
54+
}
55+
56+
const forkBranch = await this.updateHomebrewFork({
57+
packageVersion,
58+
packageSha,
59+
homebrewFormula,
60+
homebrewCore,
61+
homebrewCoreFork,
62+
isDryRun: isDryRun || false,
63+
});
64+
if (!forkBranch) {
65+
console.warn('There are no changes to the homebrew formula');
66+
return;
67+
}
68+
69+
const description = `This PR was created automatically and bumps \`mongosh\` to the latest published version \`${packageVersion}\`.\n\nFor additional details see ${githubReleaseLink}.`;
4570

46-
if (isDryRun) {
47-
await homebrewCoreFork.deleteBranch(forkBranch);
48-
console.warn('Deleted branch instead of creating homebrew PR');
49-
return;
71+
if (isDryRun) {
72+
await homebrewCoreFork.deleteBranch(forkBranch);
73+
console.warn('Deleted branch instead of creating homebrew PR');
74+
return;
75+
}
76+
const pr = await homebrewCore.createPullRequest(
77+
`mongosh ${packageVersion}`,
78+
description,
79+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
80+
`${homebrewCoreFork.repo.owner}:${forkBranch}`,
81+
'master'
82+
);
83+
console.info(
84+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
85+
`Created PR #${pr.prNumber} in ${homebrewCore.repo.owner}/${homebrewCore.repo.repo}: ${pr.url}`
86+
);
5087
}
51-
const pr = await homebrewCore.createPullRequest(
52-
`mongosh ${packageVersion}`,
53-
description,
54-
`${homebrewCoreFork.repo.owner}:${forkBranch}`,
55-
'master'
56-
);
57-
console.info(
58-
`Created PR #${pr.prNumber} in ${homebrewCore.repo.owner}/${homebrewCore.repo.repo}: ${pr.url}`
59-
);
6088
}

0 commit comments

Comments
 (0)