Skip to content

Commit 8ce53ee

Browse files
meorphismeorphis
andauthored
[APP-2111] fork base and add release commit atomically (#215)
* Revert "do not leave comment if custom version has not been set (#212)" This reverts commit e163d6f. * fork base and add release commit atomically * fix --------- Co-authored-by: meorphis <[email protected]>
1 parent 5a068dc commit 8ce53ee

File tree

5 files changed

+209
-56
lines changed

5 files changed

+209
-56
lines changed

src/github.ts

Lines changed: 130 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
import {commitAndPush} from 'code-suggester/build/src/github/commit-and-push';
15+
import {
16+
createTree,
17+
generateTreeObjects,
18+
} from 'code-suggester/build/src/github/commit-and-push';
1619
import {addLabels} from 'code-suggester/build/src/github/labels';
1720
import {setupLogger} from 'code-suggester/build/src/logger';
1821

@@ -1275,27 +1278,7 @@ export class GitHub {
12751278
updates: Update[],
12761279
options?: CreatePullRequestOptions
12771280
): Promise<PullRequest> => {
1278-
const changes = await this.buildChangeSet(updates, refBranch);
1279-
1280-
// create release branch
1281-
const pullRequestBranchSha = await this.forkBranch(
1282-
pullRequest.headBranchName,
1283-
refBranch
1284-
);
1285-
1286-
// commit and push changeset
1287-
await commitAndPush(
1288-
this.octokit,
1289-
pullRequestBranchSha,
1290-
changes,
1291-
{
1292-
branch: pullRequest.headBranchName,
1293-
repo: this.repository.repo,
1294-
owner: this.repository.owner,
1295-
},
1296-
message,
1297-
true
1298-
);
1281+
await this.upsertReleaseBranch(pullRequest, refBranch, message, updates);
12991282

13001283
// create pull request, unless one already exists
13011284
let pullRequestNumber: number;
@@ -1334,6 +1317,131 @@ export class GitHub {
13341317
}
13351318
);
13361319

1320+
upsertReleaseBranch = wrapAsync(
1321+
async (
1322+
pullRequest: PullRequest,
1323+
refBranch: string,
1324+
message: string,
1325+
updates: Update[]
1326+
): Promise<void> => {
1327+
this.logger.debug(
1328+
{
1329+
pullRequest: pullRequest.headBranchName,
1330+
refBranch: refBranch,
1331+
message: message,
1332+
updates: updates.length,
1333+
},
1334+
'upserting release branch'
1335+
);
1336+
1337+
const changes = await this.buildChangeSet(updates, refBranch);
1338+
1339+
const refSHA = await this.getBranchSha(refBranch);
1340+
1341+
this.logger.debug(
1342+
{
1343+
refBranch: refBranch,
1344+
refSHA: refSHA,
1345+
changes: changes.size,
1346+
},
1347+
'found ref branch SHA'
1348+
);
1349+
1350+
if (!refSHA) {
1351+
throw new Error(
1352+
`could not find branch ${refBranch} in repository ${this.repository.owner}/${this.repository.repo}`
1353+
);
1354+
}
1355+
1356+
const tree = generateTreeObjects(changes);
1357+
1358+
const treeSha = await createTree(
1359+
this.octokit,
1360+
this.repository,
1361+
refSHA,
1362+
tree
1363+
);
1364+
1365+
this.logger.debug(
1366+
{
1367+
treeSha: treeSha,
1368+
},
1369+
'created tree'
1370+
);
1371+
1372+
const {data: newCommit} = await this.octokit.git.createCommit({
1373+
...this.repository,
1374+
message,
1375+
tree: treeSha,
1376+
parents: [refSHA],
1377+
});
1378+
1379+
this.logger.debug(
1380+
{
1381+
newCommit: newCommit.sha,
1382+
},
1383+
'created commit'
1384+
);
1385+
1386+
const ref = `heads/${pullRequest.headBranchName}`;
1387+
try {
1388+
// try to update existing branch
1389+
await this.octokit.git.updateRef({
1390+
...this.repository,
1391+
ref,
1392+
sha: newCommit.sha,
1393+
force: true,
1394+
});
1395+
1396+
this.logger.debug(
1397+
{
1398+
ref: ref,
1399+
newCommit: newCommit.sha,
1400+
},
1401+
'updated existing branch'
1402+
);
1403+
} catch (error) {
1404+
if (this.isRefDoesNotExistError(error)) {
1405+
this.logger.debug(
1406+
{
1407+
ref: ref,
1408+
},
1409+
'branch does not exist, creating it'
1410+
);
1411+
1412+
// branch doesn't exist, create it
1413+
await this.octokit.git.createRef({
1414+
...this.repository,
1415+
ref: `refs/${ref}`,
1416+
sha: newCommit.sha,
1417+
});
1418+
1419+
this.logger.debug(
1420+
{
1421+
ref: ref,
1422+
newCommit: newCommit.sha,
1423+
},
1424+
'created new branch'
1425+
);
1426+
} else {
1427+
throw error;
1428+
}
1429+
}
1430+
}
1431+
);
1432+
1433+
isRefDoesNotExistError = (error: unknown): boolean => {
1434+
return (
1435+
(error &&
1436+
typeof error === 'object' &&
1437+
'status' in error &&
1438+
error.status === 422 &&
1439+
'message' in error &&
1440+
typeof error.message === 'string' &&
1441+
error.message.includes('does not exist')) === true
1442+
);
1443+
};
1444+
13371445
/**
13381446
* Fetch a pull request given the pull number
13391447
* @param {number} number The pull request number

src/strategies/base.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
MANIFEST_PULL_REQUEST_TITLE_PATTERN,
2323
ExtraFile,
2424
DEFAULT_CUSTOM_VERSION_LABEL,
25+
DEFAULT_RELEASE_PLEASE_MANIFEST,
2526
} from '../manifest';
2627
import {DefaultVersioningStrategy} from '../versioning-strategies/default';
2728
import {DefaultChangelogNotes} from '../changelog-notes/default';
@@ -274,12 +275,14 @@ export abstract class BaseStrategy implements Strategy {
274275
labels = [],
275276
latestRelease,
276277
draft,
278+
manifestPath,
277279
}: {
278280
commits: Commit[];
279281
latestRelease?: Release;
280282
draft?: boolean;
281283
labels?: string[];
282284
existingPullRequest?: PullRequest;
285+
manifestPath?: string;
283286
}): Promise<ReleasePullRequest | undefined> {
284287
this.logger.info(`Considering: ${commits.length} raw commits`);
285288

@@ -388,7 +391,13 @@ To set a custom version be sure to use the [semantic versioning format](https://
388391
} else {
389392
// look at the manifest from release branch and compare against version from PR title
390393
try {
391-
if (newVersion.toString() !== existingPRTitleVersion.toString()) {
394+
const manifest =
395+
(await this.github.getFileJson<Record<string, string>>(
396+
manifestPath || DEFAULT_RELEASE_PLEASE_MANIFEST,
397+
existingPullRequest.headBranchName
398+
)) || {};
399+
const componentVersion = manifest[component || '.'];
400+
if (componentVersion !== existingPRTitleVersion?.toString()) {
392401
// version from title has been edited, add custom version label, a comment, and use the title version
393402
this.github.addIssueLabels(
394403
[DEFAULT_CUSTOM_VERSION_LABEL],

src/strategies/java.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,14 @@ export class Java extends BaseStrategy {
7979
labels = [],
8080
latestRelease,
8181
draft,
82+
manifestPath,
8283
}: {
8384
commits: ConventionalCommit[];
8485
latestRelease?: Release;
8586
draft?: boolean;
8687
labels?: string[];
8788
existingPullRequest?: PullRequest;
89+
manifestPath?: string;
8890
}): Promise<ReleasePullRequest | undefined> {
8991
if (await this.needsSnapshot(commits, latestRelease)) {
9092
this.logger.info('Repository needs a snapshot bump.');
@@ -100,6 +102,7 @@ export class Java extends BaseStrategy {
100102
latestRelease,
101103
draft,
102104
labels,
105+
manifestPath,
103106
});
104107
}
105108

test/github.ts

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import {
3535
import {fail} from 'assert';
3636
import {PullRequestBody} from '../src/util/pull-request-body';
3737
import {PullRequestTitle} from '../src/util/pull-request-title';
38-
import * as codeSuggesterCommitAndPush from 'code-suggester/build/src/github/commit-and-push';
3938
import {HttpsProxyAgent} from 'https-proxy-agent';
4039
import {HttpProxyAgent} from 'http-proxy-agent';
4140
import {Commit} from '../src/commit';
@@ -1112,26 +1111,10 @@ describe('GitHub', () => {
11121111

11131112
describe('updatePullRequest', () => {
11141113
it('handles a ref branch different from the base branch', async () => {
1115-
const forkBranchStub = sandbox
1116-
.stub(github, <any>'forkBranch') // eslint-disable-line @typescript-eslint/no-explicit-any
1117-
.withArgs('release-please--branches--main--changes--next', 'next')
1114+
const upsertReleaseBranch = sandbox
1115+
.stub(github, <any>'upsertReleaseBranch') // eslint-disable-line @typescript-eslint/no-explicit-any
11181116
.resolves('the-pull-request-branch-sha');
11191117

1120-
const commitAndPushStub = sandbox
1121-
.stub(codeSuggesterCommitAndPush, 'commitAndPush')
1122-
.withArgs(
1123-
sinon.match.any,
1124-
'the-pull-request-branch-sha',
1125-
sinon.match.any,
1126-
sinon.match.has(
1127-
'branch',
1128-
'release-please--branches--main--changes--next'
1129-
),
1130-
sinon.match.string,
1131-
true
1132-
)
1133-
.resolves();
1134-
11351118
const getPullRequestStub = sandbox
11361119
.stub(github, 'getPullRequest')
11371120
.withArgs(123)
@@ -1171,19 +1154,16 @@ describe('GitHub', () => {
11711154
};
11721155

11731156
await github.updatePullRequest(123, pullRequest, 'main', 'next');
1174-
sinon.assert.calledOnce(forkBranchStub);
1175-
sinon.assert.calledOnce(commitAndPushStub);
1157+
sinon.assert.calledOnce(upsertReleaseBranch);
11761158
sinon.assert.calledOnce(getPullRequestStub);
11771159
req.done();
11781160
});
11791161

11801162
it('handles a PR body that is too big', async () => {
1181-
const commitAndPushStub = sandbox
1182-
.stub(codeSuggesterCommitAndPush, 'commitAndPush')
1183-
.resolves();
1184-
const forkBranchStub = sandbox
1185-
.stub(github, <any>'forkBranch') // eslint-disable-line @typescript-eslint/no-explicit-any
1163+
const upsertReleaseBranch = sandbox
1164+
.stub(github, <any>'upsertReleaseBranch') // eslint-disable-line @typescript-eslint/no-explicit-any
11861165
.resolves('the-pull-request-branch-sha');
1166+
11871167
req = req.patch('/repos/fake/fake/pulls/123').reply(200, {
11881168
number: 123,
11891169
title: 'updated-title',
@@ -1225,8 +1205,7 @@ describe('GitHub', () => {
12251205
pullRequestOverflowHandler,
12261206
});
12271207
sinon.assert.calledOnce(handleOverflowStub);
1228-
sinon.assert.calledOnce(commitAndPushStub);
1229-
sinon.assert.calledOnce(forkBranchStub);
1208+
sinon.assert.calledOnce(upsertReleaseBranch);
12301209
sinon.assert.calledOnce(getPullRequestStub);
12311210
req.done();
12321211
});

0 commit comments

Comments
 (0)