Skip to content

Commit

Permalink
feat: allow configuring release-search-depth and `commit-search-dep…
Browse files Browse the repository at this point in the history
…th` (#1396)

Fixes #1394
  • Loading branch information
chingor13 committed Apr 15, 2022
1 parent f5aff97 commit 102d650
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 8 deletions.
15 changes: 15 additions & 0 deletions docs/manifest-releaser.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,21 @@ documented in comments)
// absence defaults to "chore: release ${branch}"
"group-pull-request-title-pattern": "chore: release ${branch}",

// When searching for the latest release SHAs, only consider the last N releases.
// This option prevents paginating through all releases in history when we
// expect to find the release within the last N releases. For repositories with
// a large number of individual packages, you may want to consider raising this
// value, but it will increase the number of API calls used.
"release-search-depth": 400,

// When fetching the list of commits to consider, only consider the last N commits.
// This option limits paginating through every commit in history when we may not
// find the release SHA of the last release (there may not be one). We expect to
// only need to consider the last 500 commits on a branch. For repositories with
// a large number of individual packages, you may want to consider raising this
// value, but it will increase the number of API calls used.
"commit-search-depth": 500,

// per package configuration: at least one entry required.
// the key is the relative path from the repo root to the folder that contains
// all the files for that package.
Expand Down
20 changes: 18 additions & 2 deletions src/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ export interface ManifestOptions {
prerelease?: boolean;
draftPullRequest?: boolean;
groupPullRequestTitlePattern?: string;
releaseSearchDepth?: number;
commitSearchDepth?: number;
}

interface ReleaserPackageConfig extends ReleaserConfigJson {
Expand Down Expand Up @@ -173,6 +175,8 @@ export interface ManifestConfig extends ReleaserConfigJson {
plugins?: PluginType[];
'separate-pull-requests'?: boolean;
'group-pull-request-title-pattern'?: string;
'release-search-depth'?: number;
'commit-search-depth'?: number;
}
// path => version
export type ReleasedVersions = Record<string, Version>;
Expand All @@ -187,6 +191,8 @@ export const DEFAULT_LABELS = ['autorelease: pending'];
export const DEFAULT_RELEASE_LABELS = ['autorelease: tagged'];
export const DEFAULT_SNAPSHOT_LABELS = ['autorelease: snapshot'];
export const SNOOZE_LABEL = 'autorelease: snooze';
const DEFAULT_RELEASE_SEARCH_DEPTH = 400;
const DEFAULT_COMMIT_SEARCH_DEPTH = 500;

export const MANIFEST_PULL_REQUEST_TITLE_PATTERN = 'chore: release ${branch}';

Expand Down Expand Up @@ -220,6 +226,8 @@ export class Manifest {
private prerelease?: boolean;
private draftPullRequest?: boolean;
private groupPullRequestTitlePattern?: string;
readonly releaseSearchDepth: number;
readonly commitSearchDepth: number;

/**
* Create a Manifest from explicit config in code. This assumes that the
Expand Down Expand Up @@ -277,6 +285,10 @@ export class Manifest {
this.draftPullRequest = manifestOptions?.draftPullRequest;
this.groupPullRequestTitlePattern =
manifestOptions?.groupPullRequestTitlePattern;
this.releaseSearchDepth =
manifestOptions?.releaseSearchDepth || DEFAULT_RELEASE_SEARCH_DEPTH;
this.commitSearchDepth =
manifestOptions?.commitSearchDepth || DEFAULT_COMMIT_SEARCH_DEPTH;
}

/**
Expand Down Expand Up @@ -403,8 +415,9 @@ export class Manifest {

// Releases by path
const releasesByPath: Record<string, Release> = {};
logger.debug(`release search depth: ${this.releaseSearchDepth}`);
for await (const release of this.github.releaseIterator({
maxResults: 400,
maxResults: this.releaseSearchDepth,
})) {
const tagName = TagName.parse(release.tagName);
if (!tagName) {
Expand Down Expand Up @@ -481,8 +494,9 @@ export class Manifest {
// seen all release commits
logger.info('Collecting commits since all latest releases');
const commits: Commit[] = [];
logger.debug(`commit search depth: ${this.commitSearchDepth}`);
const commitGenerator = this.github.mergeCommitIterator(this.targetBranch, {
maxResults: 500,
maxResults: this.commitSearchDepth,
backfillFiles: true,
});
const releaseShas = new Set(Object.values(releaseShasByPath));
Expand Down Expand Up @@ -1138,6 +1152,8 @@ async function parseConfig(
configReleaseLabel === undefined ? undefined : [configReleaseLabel],
snapshotLabels:
configSnapshotLabel === undefined ? undefined : [configSnapshotLabel],
releaseSearchDepth: config['release-search-depth'],
commitSearchDepth: config['commit-search-depth'],
};
return {config: repositoryConfig, options: manifestOptions};
}
Expand Down
9 changes: 9 additions & 0 deletions test/fixtures/manifest/config/search-depth.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"release-search-depth": 10,
"commit-search-depth": 50,
"packages": {
".": {
"release-type": "simple"
}
}
}
12 changes: 6 additions & 6 deletions test/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,37 +330,37 @@ export function mockCommits(
sandbox: sinon.SinonSandbox,
github: GitHub,
commits: Commit[]
) {
): sinon.SinonStub {
async function* fakeGenerator() {
for (const commit of commits) {
yield commit;
}
}
sandbox.stub(github, 'mergeCommitIterator').returns(fakeGenerator());
return sandbox.stub(github, 'mergeCommitIterator').returns(fakeGenerator());
}

export function mockReleases(
sandbox: sinon.SinonSandbox,
github: GitHub,
releases: GitHubRelease[]
) {
): sinon.SinonStub {
async function* fakeGenerator() {
for (const release of releases) {
yield release;
}
}
sandbox.stub(github, 'releaseIterator').returns(fakeGenerator());
return sandbox.stub(github, 'releaseIterator').returns(fakeGenerator());
}

export function mockTags(
sandbox: sinon.SinonSandbox,
github: GitHub,
tags: GitHubTag[]
) {
): sinon.SinonStub {
async function* fakeGenerator() {
for (const tag of tags) {
yield tag;
}
}
sandbox.stub(github, 'tagIterator').returns(fakeGenerator());
return sandbox.stub(github, 'tagIterator').returns(fakeGenerator());
}
170 changes: 170 additions & 0 deletions test/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,33 @@ describe('Manifest', () => {
},
]);
});
it('should configure search depth from manifest', async () => {
const getFileContentsStub = sandbox.stub(
github,
'getFileContentsOnBranch'
);
getFileContentsStub
.withArgs('release-please-config.json', 'main')
.resolves(
buildGitHubFileContent(
fixturesPath,
'manifest/config/search-depth.json'
)
)
.withArgs('.release-please-manifest.json', 'main')
.resolves(
buildGitHubFileContent(
fixturesPath,
'manifest/versions/versions.json'
)
);
const manifest = await Manifest.fromManifest(
github,
github.repository.defaultBranch
);
expect(manifest.releaseSearchDepth).to.eql(10);
expect(manifest.commitSearchDepth).to.eql(50);
});
});

describe('fromConfig', () => {
Expand Down Expand Up @@ -2554,6 +2581,149 @@ describe('Manifest', () => {
expect(pullRequests[0].labels).to.eql(['autorelease: pending']);
snapshot(dateSafe(pullRequests[0].body.toString()));
});

it('should allow customizing release-search-depth', async () => {
const releaseStub = mockReleases(sandbox, github, []);
mockTags(sandbox, github, [
{
name: 'pkg1-v1.0.0',
sha: 'abc123',
},
]);
mockCommits(sandbox, github, [
{
sha: 'def456',
message: 'fix: some bugfix',
files: [],
},
{
sha: 'abc123',
message: 'chore: release 1.0.0',
files: [],
pullRequest: {
headBranchName: 'release-please/branches/main/components/pkg1',
baseBranchName: 'main',
number: 123,
title: 'chore: release 1.0.0',
body: '',
labels: [],
files: [],
sha: 'abc123',
},
},
]);
const getFileContentsStub = sandbox.stub(
github,
'getFileContentsOnBranch'
);
getFileContentsStub
.withArgs('package.json', 'main')
.resolves(
buildGitHubFileContent(
fixturesPath,
'manifest/repo/node/pkg1/package.json'
)
);
const manifest = new Manifest(
github,
'main',
{
'.': {
releaseType: 'node',
},
},
{
'.': Version.parse('1.0.0'),
},
{
releaseSearchDepth: 1,
}
);
expect(manifest.releaseSearchDepth).to.eql(1);
const pullRequests = await manifest.buildPullRequests();
expect(pullRequests).lengthOf(1);
const pullRequest = pullRequests[0];
expect(pullRequest.version?.toString()).to.eql('1.0.1');
expect(pullRequest.headRefName).to.eql(
'release-please--branches--main--components--pkg1'
);
sinon.assert.calledOnceWithMatch(
releaseStub,
sinon.match.has('maxResults', 1)
);
});

it('should allow customizing commit-search-depth', async () => {
mockReleases(sandbox, github, []);
mockTags(sandbox, github, [
{
name: 'pkg1-v1.0.0',
sha: 'abc123',
},
]);
const commitsStub = mockCommits(sandbox, github, [
{
sha: 'def456',
message: 'fix: some bugfix',
files: [],
},
{
sha: 'abc123',
message: 'chore: release 1.0.0',
files: [],
pullRequest: {
headBranchName: 'release-please/branches/main/components/pkg1',
baseBranchName: 'main',
number: 123,
title: 'chore: release 1.0.0',
body: '',
labels: [],
files: [],
sha: 'abc123',
},
},
]);
const getFileContentsStub = sandbox.stub(
github,
'getFileContentsOnBranch'
);
getFileContentsStub
.withArgs('package.json', 'main')
.resolves(
buildGitHubFileContent(
fixturesPath,
'manifest/repo/node/pkg1/package.json'
)
);
const manifest = new Manifest(
github,
'main',
{
'.': {
releaseType: 'node',
},
},
{
'.': Version.parse('1.0.0'),
},
{
commitSearchDepth: 1,
}
);
expect(manifest.commitSearchDepth).to.eql(1);
const pullRequests = await manifest.buildPullRequests();
expect(pullRequests).lengthOf(1);
const pullRequest = pullRequests[0];
expect(pullRequest.version?.toString()).to.eql('1.0.1');
expect(pullRequest.headRefName).to.eql(
'release-please--branches--main--components--pkg1'
);
sinon.assert.calledOnceWithMatch(
commitsStub,
'main',
sinon.match.has('maxResults', 1)
);
});
});

describe('createPullRequests', () => {
Expand Down

0 comments on commit 102d650

Please sign in to comment.