Skip to content

Commit

Permalink
feat: initial work for legacy deleteAfterMerge option
Browse files Browse the repository at this point in the history
  • Loading branch information
christophehurpeau committed Aug 12, 2022
1 parent c0b1c7b commit 77001be
Show file tree
Hide file tree
Showing 20 changed files with 173 additions and 25 deletions.
1 change: 1 addition & 0 deletions src/__fixtures__/pull_request_30.opened.json
Expand Up @@ -433,6 +433,7 @@
"open_issues": 4,
"watchers": 0,
"default_branch": "master",
"delete_branch_on_merge": true,
"is_template": false,
"topics": [],
"visibility": "public"
Expand Down
8 changes: 4 additions & 4 deletions src/context/accountContext.ts
@@ -1,11 +1,11 @@
import { Lock } from 'lock';
import type { EventsWithOrganisation } from 'events/account-handlers/utils/createHandlerOrgChange';
import type { Config } from '../accountConfigs';
import type { EventsWithOrganisation } from '../events/account-handlers/utils/createHandlerOrgChange';
import type {
PullRequestWithDecentData,
PullRequestWithDecentDataFromWebhook,
} from 'events/pr-handlers/utils/PullRequestData';
import type { ProbotEvent } from 'events/probot-types';
import type { Config } from '../accountConfigs';
} from '../events/pr-handlers/utils/PullRequestData';
import type { ProbotEvent } from '../events/probot-types';
import type {
Org,
User,
Expand Down
2 changes: 1 addition & 1 deletion src/context/getOrCreateAccount.ts
@@ -1,8 +1,8 @@
import type { EmitterWebhookEventName } from '@octokit/webhooks';
import type { ProbotEvent } from 'events/probot-types';
import { syncOrg } from '../events/account-handlers/actions/syncOrg';
import { syncTeamsAndTeamMembers } from '../events/account-handlers/actions/syncTeams';
import { syncUser } from '../events/account-handlers/actions/syncUser';
import type { ProbotEvent } from '../events/probot-types';
import type { Org, User } from '../mongo';
import type { AppContext } from './AppContext';

Expand Down
2 changes: 1 addition & 1 deletion src/context/initRepoLabels.ts
@@ -1,7 +1,7 @@
import type { RestEndpointMethodTypes } from '@octokit/rest';
import type { EmitterWebhookEventName } from '@octokit/webhooks';
import type { ProbotEvent } from 'events/probot-types';
import type { Config } from '../accountConfigs';
import type { ProbotEvent } from '../events/probot-types';

export interface LabelResponse {
id: number;
Expand Down
31 changes: 26 additions & 5 deletions src/context/repoContext.ts
@@ -1,18 +1,19 @@
/* eslint-disable max-lines */
import type { EmitterWebhookEventName } from '@octokit/webhooks';
import { Lock } from 'lock';
import type { ProbotEvent } from 'events/probot-types';
import type { Config } from '../accountConfigs';
import { accountConfigs, defaultConfig } from '../accountConfigs';
import type { GroupLabels } from '../accountConfigs/types';
import { autoMergeIfPossible } from '../events/pr-handlers/actions/autoMergeIfPossible';
import { parseRepositoryOptions } from '../events/pr-handlers/actions/utils/body/repositoryOptions';
import type {
PullRequestDataMinimumData,
PullRequestLabels,
} from '../events/pr-handlers/utils/PullRequestData';
import { getReviewflowPrContext } from '../events/pr-handlers/utils/createPullRequestContext';
import { fetchPr } from '../events/pr-handlers/utils/fetchPr';
import type { RepositoryMergeQueue } from '../mongo';
import type { ProbotEvent } from '../events/probot-types';
import type { RepositoryMergeQueue, Repository } from '../mongo';
import { ExcludesFalsy } from '../utils/Excludes';
import type { AppContext } from './AppContext';
import type { AccountContext } from './accountContext';
Expand Down Expand Up @@ -83,6 +84,7 @@ interface RepoContextWithoutTeamContext<GroupNames extends string> {
repoFullName: string;
repoEmbed: { id: number; name: string };
repoEmoji: string | undefined;
defaultBranch: string;
labels: LabelsRecord;
protectedLabelIds: readonly LabelResponse['id'][];
shouldIgnore: boolean;
Expand Down Expand Up @@ -179,7 +181,6 @@ async function initRepoContext<
owner: org,
description,
} = context.payload.repository;
const repoEmoji = getEmojiFromRepoDescription(description);

const accountContext = await obtainAccountContext<T>(
appContext,
Expand All @@ -191,6 +192,24 @@ async function initRepoContext<

const shouldIgnore = shouldIgnoreRepo(name, config);

const findOrCreateRepository = async (): Promise<Repository> => {
const res = await appContext.mongoStores.repositories.findByKey(id, {
'account.id': accountContext.accountEmbed.id,
});

if (res) {
return res;
}

const repoEmoji = getEmojiFromRepoDescription(description);
return appContext.mongoStores.repositories.insertOne({
_id: id,
account: accountContext.accountEmbed,
emoji: repoEmoji,
fullName,
options: parseRepositoryOptions(context.payload.repository),
});
};
const findOrCreateRepositoryMergeQueue =
async (): Promise<RepositoryMergeQueue> => {
const res = await appContext.mongoStores.repositoryMergeQueue.findOne({
Expand All @@ -209,8 +228,9 @@ async function initRepoContext<
});
};

const [repoLabels, repositoryMergeQueue] = await Promise.all([
const [repoLabels, repository, repositoryMergeQueue] = await Promise.all([
shouldIgnore ? {} : initRepoLabels(context, config),
findOrCreateRepository(),
findOrCreateRepositoryMergeQueue(),
]);

Expand Down Expand Up @@ -483,7 +503,8 @@ async function initRepoContext<
labels: repoLabels,
repoFullName: fullName,
repoEmbed: { id, name },
repoEmoji,
repoEmoji: repository.emoji,
defaultBranch: context.payload.repository.default_branch,
protectedLabelIds,
shouldIgnore,
hasNeedsReview,
Expand Down
2 changes: 2 additions & 0 deletions src/events/pr-handlers/actions/commentBodyEdited.ts
Expand Up @@ -9,6 +9,7 @@ import { updateBranch } from './updateBranch';
import { updatePrCommentBodyIfNeeded } from './updatePrCommentBody';
import { updateStatusCheckFromLabels } from './updateStatusCheckFromLabels';
import { calcDefaultOptions } from './utils/body/prOptions';
import { parseRepositoryOptions } from './utils/body/repositoryOptions';
import { updateCommentOptions } from './utils/body/updateBody';
import { syncLabels, removeLabel } from './utils/syncLabel';

Expand All @@ -24,6 +25,7 @@ export const commentBodyEdited = async <Name extends EventsWithRepository>(
const updateBranchLabel = repoContext.labels['merge/update-branch'];

const { commentBody, options, actions } = updateCommentOptions(
parseRepositoryOptions(context.payload.repository),
context.payload.repository.html_url,
repoContext.config.labels.list,
reviewflowPrContext.commentBody,
Expand Down
2 changes: 2 additions & 0 deletions src/events/pr-handlers/actions/editOpenedPR.ts
Expand Up @@ -11,6 +11,7 @@ import { readCommitsAndUpdateInfos } from './readCommitsAndUpdateInfos';
import { updatePrIfNeeded } from './updatePr';
import { updatePrCommentBodyIfNeeded } from './updatePrCommentBody';
import { calcDefaultOptions } from './utils/body/prOptions';
import { parseRepositoryOptions } from './utils/body/repositoryOptions';
import {
updateCommentBodyInfos,
defaultCommentBody,
Expand Down Expand Up @@ -248,6 +249,7 @@ export const editOpenedPR = async <Name extends EventsWithRepository>({

const newCommentBody = shouldCreateCommentBody
? createCommentBody(
parseRepositoryOptions(context.payload.repository),
context.payload.repository.html_url,
repoContext.config.labels.list,
calcDefaultOptions(repoContext, pullRequest),
Expand Down
2 changes: 2 additions & 0 deletions src/events/pr-handlers/actions/updatePrCommentBody.ts
Expand Up @@ -2,6 +2,7 @@ import type { EventsWithRepository, RepoContext } from 'context/repoContext';
import type { ProbotEvent } from 'events/probot-types';
import type { ReviewflowPrContext } from '../utils/createPullRequestContext';
import type { Options } from './utils/body/prOptions';
import { parseRepositoryOptions } from './utils/body/repositoryOptions';
import { updateCommentOptions } from './utils/body/updateBody';

const updatePrCommentBody = async <Name extends EventsWithRepository>(
Expand Down Expand Up @@ -39,6 +40,7 @@ export const updatePrCommentBodyOptions = async <
updateOptions: Partial<Options>,
): Promise<void> => {
const { commentBody: newBody } = updateCommentOptions(
parseRepositoryOptions(context.payload.repository),
context.payload.repository.html_url,
repoContext.config.labels.list,
reviewflowPrContext.commentBody,
Expand Down
Expand Up @@ -3,7 +3,6 @@ export default `
- [ ] <!-- reviewflow-featureBranch -->This PR is a feature branch
- [ ] <!-- reviewflow-autoMergeWithSkipCi -->Add \`[skip ci]\` on merge commit
- [ ] <!-- reviewflow-autoMerge -->Auto merge when this PR is ready and has no failed statuses. (Also has a queue per repo to prevent multiple useless "Update branch" triggers)
- [x] <!-- reviewflow-deleteAfterMerge -->Automatic branch delete after this PR is merged
### Actions:
- [ ] <!-- reviewflow-updateChecks -->:bug: Force updating reviewflow checks for this PR. Use this to try to fix reviewflow checks that are still missing/pending, which might happen if webhook failed or something bad happened when reviewflow tried to send the status check to github.
- [ ] <!-- reviewflow-updateBranch -->[:arrows_counterclockwise: update branch](https://github.com/christophehurpeau/reviewflow/labels/%3Aarrows_counterclockwise%3A%20update%20branch): Merge base branch in this PR's branch. Only works if merging is possible without conflicts.
Expand Down
Expand Up @@ -6,7 +6,6 @@ Some informations here, like links.
- [ ] <!-- reviewflow-featureBranch -->This PR is a feature branch
- [ ] <!-- reviewflow-autoMergeWithSkipCi -->Add \`[skip ci]\` on merge commit
- [ ] <!-- reviewflow-autoMerge -->Auto merge when this PR is ready and has no failed statuses. (Also has a queue per repo to prevent multiple useless "Update branch" triggers)
- [x] <!-- reviewflow-deleteAfterMerge -->Automatic branch delete after this PR is merged
### Actions:
- [ ] <!-- reviewflow-updateChecks -->:bug: Force updating reviewflow checks for this PR. Use this to try to fix reviewflow checks that are still missing/pending, which might happen if webhook failed or something bad happened when reviewflow tried to send the status check to github.
- [ ] <!-- reviewflow-updateBranch -->[:arrows_counterclockwise: update branch](https://github.com/christophehurpeau/reviewflow/labels/%3Aarrows_counterclockwise%3A%20update%20branch): Merge base branch in this PR's branch. Only works if merging is possible without conflicts.
Expand Down
Expand Up @@ -3,7 +3,6 @@ export default `
- [ ] <!-- reviewflow-featureBranch -->This PR is a feature branch
- [ ] <!-- reviewflow-autoMergeWithSkipCi -->Add \`[skip ci]\` on merge commit
- [ ] <!-- reviewflow-autoMerge -->Auto merge when this PR is ready and has no failed statuses. (Also has a queue per repo to prevent multiple useless "Update branch" triggers)
- [x] <!-- reviewflow-deleteAfterMerge -->Automatic branch delete after this PR is merged
### Actions:
- [ ] <!-- reviewflow-updateChecks -->:bug: Force updating reviewflow checks for this PR. Use this to try to fix reviewflow checks that are still missing/pending, which might happen if webhook failed or something bad happened when reviewflow tried to send the status check to github.
- [ ] <!-- reviewflow-updateBranch -->[:arrows_counterclockwise: update branch](https://github.com/christophehurpeau/reviewflow/labels/%3Aarrows_counterclockwise%3A%20update%20branch): Merge base branch in this PR's branch. Only works if merging is possible without conflicts.
Expand Down
Expand Up @@ -2,7 +2,6 @@ export default `
### Options:
- [ ] <!-- reviewflow-autoMerge -->[:vertical_traffic_light: automerge](https://github.com/christophehurpeau/reviewflow/labels/%3Avertical_traffic_light%3A%20automerge): Automatically merge when this PR is ready and has no failed statuses. When the repository requires _branches to be up to date before merging_, it merges default branch, with a queue per repo to prevent multiple merges when several PRs are ready. A fail job prevents the merge.
- [ ] <!-- reviewflow-autoMergeWithSkipCi -->[:vertical_traffic_light: skip-ci](https://github.com/christophehurpeau/reviewflow/labels/%3Avertical_traffic_light%3A%20skip-ci): Add \`[skip ci]\` on merge commit when merge is done with autoMerge.
- [x] <!-- reviewflow-deleteAfterMerge -->:recycle: Automatically delete the branch after this PR is merged.
### Actions:
- [ ] <!-- reviewflow-updateChecks -->:bug: Force updating reviewflow checks for this PR. Use this to try to fix reviewflow checks that are still missing/pending, which might happen if webhook failed or something bad happened when reviewflow tried to send the status check to github.
- [ ] <!-- reviewflow-updateBranch -->[:arrows_counterclockwise: update branch](https://github.com/christophehurpeau/reviewflow/labels/%3Aarrows_counterclockwise%3A%20update%20branch): Merge base branch in this PR's branch. Only works if merging is possible without conflicts.
Expand Down
10 changes: 10 additions & 0 deletions src/events/pr-handlers/actions/utils/body/prOptions.ts
@@ -1,6 +1,7 @@
import type { RepoContext } from 'context/repoContext';
import type { PullRequestWithDecentData } from 'events/pr-handlers/utils/PullRequestData';
import hasLabelInPR from '../hasLabelInPR';
import type { RepositoryOptions } from './repositoryOptions';

export type OptionsKeys =
| 'autoMerge'
Expand All @@ -27,6 +28,10 @@ interface OptionDisplay {
labelKey?: string;
icon?: string;
description: string;
legacy?: {
repositoryOptionKey: keyof RepositoryOptions;
legacyMessage?: string;
};
}

export const optionsDescriptions: OptionDisplay[] = [
Expand All @@ -46,6 +51,11 @@ export const optionsDescriptions: OptionDisplay[] = [
key: 'deleteAfterMerge',
icon: ':recycle:',
description: 'Automatically delete the branch after this PR is merged.',
legacy: {
repositoryOptionKey: 'deleteBranchOnMerge',
legacyMessage:
'[Delete branch with Github Setting](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-the-automatic-deletion-of-branches)',
},
},
];

Expand Down
23 changes: 23 additions & 0 deletions src/events/pr-handlers/actions/utils/body/repositoryOptions.ts
@@ -0,0 +1,23 @@
import type { ProbotEvent } from '../../../../probot-types';

export interface RepositoryOptions {
defaultBranch: string;
deleteBranchOnMerge?: boolean;
allowAutoMerge?: boolean;
allowRebaseMerge?: boolean;
allowSquashMerge?: boolean;
allowMergeCommit?: boolean;
}

export function parseRepositoryOptions<Name extends 'repository.edited'>(
repository: ProbotEvent<Name>['payload']['repository'],
): RepositoryOptions {
return {
defaultBranch: repository.default_branch,
deleteBranchOnMerge: repository.delete_branch_on_merge,
allowAutoMerge: repository.allow_auto_merge,
allowRebaseMerge: repository.allow_rebase_merge,
allowSquashMerge: repository.allow_squash_merge,
allowMergeCommit: repository.allow_merge_commit,
};
}
34 changes: 33 additions & 1 deletion src/events/pr-handlers/actions/utils/body/updateBody.test.ts
Expand Up @@ -5,16 +5,26 @@ import initialAfterEditSimpleWithInfosV1 from './mocks/commentBody-v1-initialAft
import initialAfterEditSimpleV2 from './mocks/commentBody-v2-initialAfterEdit-simple';
import initialAfterEditSimpleWithInfosV2 from './mocks/commentBody-v2-initialAfterEdit-simpleWithInfos';
import type { Options } from './prOptions';
import type { RepositoryOptions } from './repositoryOptions';
import {
updateCommentOptions,
updateCommentBodyCommitsNotes,
updateCommentBodyInfos,
} from './updateBody';

const repositoryOptions: RepositoryOptions = {
defaultBranch: 'main',
deleteBranchOnMerge: false,
allowAutoMerge: false,
allowRebaseMerge: false,
allowSquashMerge: true,
allowMergeCommit: true,
};

const defaultConfig: Options = {
autoMerge: false,
autoMergeWithSkipCi: false,
deleteAfterMerge: true,
deleteAfterMerge: false,
};

const repoLinkMock = 'https://github.com/christophehurpeau/reviewflow';
Expand Down Expand Up @@ -61,6 +71,7 @@ const initialAfterEditSimpleWithInfosLatest = initialAfterEditSimpleWithInfosV2;
it('should update initial description', () => {
expect(
updateCommentOptions(
repositoryOptions,
repoLinkMock,
labels,
initialSimple,
Expand All @@ -72,6 +83,7 @@ const initialAfterEditSimpleWithInfosLatest = initialAfterEditSimpleWithInfosV2;
it('should keep infos on update', () => {
expect(
updateCommentOptions(
repositoryOptions,
repoLinkMock,
labels,
initialAfterEditSimpleWithInfos,
Expand All @@ -83,6 +95,7 @@ const initialAfterEditSimpleWithInfosLatest = initialAfterEditSimpleWithInfosV2;
it('should update options', () => {
expect(
updateCommentOptions(
repositoryOptions,
repoLinkMock,
labels,
initialAfterEditSimpleWithInfos,
Expand Down Expand Up @@ -183,3 +196,22 @@ const initialAfterEditSimpleWithInfosLatest = initialAfterEditSimpleWithInfosV2;
});
},
);

describe('Repository Options', () => {
it('should sjhow automerge if in default options', () => {
expect(
updateCommentOptions(
{ ...repositoryOptions, deleteBranchOnMerge: false },
repoLinkMock,
labels,
initialSimpleV1,
{ ...defaultConfig, deleteAfterMerge: true },
).commentBody,
).toEqual(
initialAfterEditSimpleLatest.replace(
'### Actions',
'- [x] <!-- reviewflow-deleteAfterMerge -->:recycle: Automatically delete the branch after this PR is merged. (:warning: Legacy Option: [Delete branch with Github Setting](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-the-automatic-deletion-of-branches))\n### Actions',
),
);
});
});

0 comments on commit 77001be

Please sign in to comment.