From dc2eac9b34f8f417788976edd7d8986151f4060a Mon Sep 17 00:00:00 2001 From: Javier Bullrich Date: Wed, 6 Mar 2024 17:26:49 +0100 Subject: [PATCH] Allow unstable branches to be merged (#25) Added the ability to merge [unstable branches](https://docs.github.com/en/graphql/reference/enums#mergestatestatus). This is enabled by default, as GitHub's Auto Merge feature always merges unstable branches. Fixes #24 --- README.md | 5 +++++ action.yml | 5 ++++- package.json | 2 +- src/github/merger.ts | 23 +++++++++++++++++++---- src/index.ts | 15 ++++++++++++++- 5 files changed, 43 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 699a61d..09f1cfa 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ jobs: with: GITHUB_TOKEN: '${{ github.token }}' MERGE_METHOD: "SQUASH" + ALLOW_UNSTABLE: true ``` #### Inputs @@ -48,6 +49,10 @@ You can find all the inputs in [the action file](./action.yml), but let's walk t - `ALLOWLIST`: List of user accounts which are allowed to use the bot aside from the author and org members. - **Optional** - Must be a comma separated value: `user-1,user-2,user-3`. +- `ALLOW_UNSTABLE`: If unstable, ready to merge, PRs can be merged + - An [unstable PR](https://docs.github.com/en/graphql/reference/enums#mergestatestatus) is a PR that can be merged, but a *non required status check* is failing. + - This is only relevant once the PR can be merged. GitHub's auto-merge always merges unstable PRs + - **Optional**: Defaults to `true` ## Usage diff --git a/action.yml b/action.yml index 5b11377..dc042b6 100644 --- a/action.yml +++ b/action.yml @@ -18,10 +18,13 @@ inputs: ALLOWLIST: required: false description: List of users which are allowed to use the bot. Separated by commas (abc,def,ghi) + ALLOW_UNSTABLE: + required: false + description: If unstable, ready to merge, PRs can be merged. Defaults to true outputs: repo: description: 'The name of the repo in owner/repo pattern' runs: using: 'docker' - image: 'docker://ghcr.io/paritytech/auto-merge-bot/action:1.0.0' + image: 'docker://ghcr.io/paritytech/auto-merge-bot/action:1.0.1' diff --git a/package.json b/package.json index 801fdb9..7a1bd79 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "auto-merge-bot", - "version": "1.0.0", + "version": "1.0.1", "description": "Bot which enables or disable auto-merge", "main": "src/index.ts", "scripts": { diff --git a/src/github/merger.ts b/src/github/merger.ts index 2f03b98..86d1a07 100644 --- a/src/github/merger.ts +++ b/src/github/merger.ts @@ -35,8 +35,26 @@ export class Merger { private readonly gql: typeof graphql, private readonly logger: ActionLogger, private readonly mergeMethod: PullRequestMergeMethod, + private readonly allowUnstable: boolean = false, ) {} + errorPermitsToMerge(error: Error): boolean { + // If it's clean it can be merged + if (error.message.includes("Pull request is in clean status")) { + return true; + } + + // If it is unstable and allowed, it can also be merged + if (error.message.includes("Pull request is in unstable status")) { + this.logger.warn( + "PR is unstable! Some non required status checks are failing.", + ); + return this.allowUnstable; + } + + return false; + } + async enableAutoMerge(): Promise { try { await this.gql<{ @@ -48,10 +66,7 @@ export class Merger { this.logger.info("Succesfully enabled auto-merge"); } catch (error) { this.logger.warn(error as Error); - if ( - error instanceof Error && - error.message.includes("Pull request is in clean status") - ) { + if (error instanceof Error && this.errorPermitsToMerge(error)) { this.logger.warn( "Pull Request is ready to merge. Running merge command instead", ); diff --git a/src/index.ts b/src/index.ts index 7710034..39de748 100644 --- a/src/index.ts +++ b/src/index.ts @@ -52,6 +52,11 @@ const getMergeMethod = (): PullRequestMergeMethod => { return method; }; +/** If it should allow PRs that have failed NON REQUIRED status check to be merged */ +const getAllowUnstable = (): boolean => { + return getInput("ALLOW_UNSTABLE", { required: false }) !== "false"; +}; + const silentMode = getInput("SILENT", { required: false }) === "true"; logger.info( @@ -80,7 +85,15 @@ if (context.payload.comment) { const gql = getOctokit(token).graphql.defaults({ headers: { authorization: `token ${token}` }, }) as graphql; - const merger = new Merger(issue.node_id, gql, logger, getMergeMethod()); + const mergeMethod = getMergeMethod(); + const unstableAllowed = getAllowUnstable(); + const merger = new Merger( + issue.node_id, + gql, + logger, + mergeMethod, + unstableAllowed, + ); const bot = new Bot( comment, issue,