title: GitHub 自动合并 PR 笔记

translate_title: github-automatically-merges-pull-requests-notes

date: 2021-01-18 00:00:00

updated: 2021-01-18 00:00:00

tags: [工具,GitHub]

categories: 工具

keywords: [工具,GitHub]

description: GitHub 自动合并 PR 笔记

cover: https://cdn.jsdelivr.net/gh/ccknbc-backup/photos/blog/2021-01-17~17-57-41.webp

photos: https://cdn.jsdelivr.net/gh/ccknbc-backup/photos/blog/2021-01-17~17-57-41.webp

comments: true

id: 21


本文首发在语雀

自动同步更新至CC的部落格


automerge-action


GitHub action to automatically merge pull requests when they are ready.


image


When added, this action will run the following tasks on pull requests with the

automerge label:



Labels, merge and update strategies are configurable, see Configuration.


A pull request is considered ready when:


  1. the required number of review approvals has been given (if enabled in the
    branch protection rules) and
  2. the required checks have passed (if enabled in the branch protection rules)
    and
  3. the pull request is up to date (if enabled in the branch protection rules)


After the pull request has been merged successfully, the branch will not be

deleted. To delete branches after they are merged,

see automatic deletion of branches.


Usage


Create a new .github/workflows/automerge.yml file:


name: automerge
on:
  pull_request:
    types:
      - labeled
      - unlabeled
      - synchronize
      - opened
      - edited
      - ready_for_review
      - reopened
      - unlocked
  pull_request_review:
    types:
      - submitted
  check_suite:
    types:
      - completed
  status: {}
jobs:
  automerge:
    runs-on: ubuntu-latest
    steps:
      - name: automerge
        uses: "pascalgn/automerge-action@v0.13.0"
        env:
          GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"


For the latest version, see the list of releases.


Configuration


The following merge options are supported:



The following update options are supported:



Also, the following general options are supported:



You can configure the environment variables in the workflow file like this:


        env:
          GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
          MERGE_LABELS: "automerge,!work in progress"
          MERGE_REMOVE_LABELS: "automerge"
          MERGE_METHOD: "squash"
          MERGE_COMMIT_MESSAGE: "pull-request-description"
          MERGE_FORKS: "false"
          MERGE_RETRIES: "6"
          MERGE_RETRY_SLEEP: "10000"
          UPDATE_LABELS: ""
          UPDATE_METHOD: "rebase"


Supported Events


Automerge can be configured to run for these events:



For more information on when these occur, see the Github documentation on events that trigger workflows and their payloads.


Limitations



Debugging


To run the action with full debug logging, update your workflow file as follows:


      - name: automerge
        uses: pascalgn/automerge-action@...
        with:
          args: "--trace"


If you need to further debug the action, you can run it locally.


You will need a personal access token.


Then clone this repository, create a file .env in the repository, such as:


GITHUB_TOKEN="123abc..."
URL="https://github.com/pascalgn/repository-name/pull/123"


Install dependencies with yarn, and finally run yarn it (or npm run it).


License


MIT


bulldozer


image image


bulldozer is a GitHub App that

automatically merges pull requests (PRs) when (and only when) all required

status checks are successful and required reviews are provided.


Additionally, bulldozer can:



Bulldozer might be useful if you:



Contents



Behavior


bulldozer will only merge pull requests that GitHub allows non-admin

collaborators to merge. This means that all branch protection settings,

including required status checks and required reviews, are respected. It also

means that you must enable branch protection to prevent bulldozer from

immediately merging every pull request.


Only pull requests matching the trigger conditions (or not matching

ignore conditions) are considered for merging. bulldozer is event-driven,

which means it will usually merge a pull request within a few seconds of the

pull request satisfying all preconditions.


Configuration


The behavior of the bot is configured by a .bulldozer.yml file at the root of

the repository. The file name and location are configurable when running your

own instance of the server.


The .bulldozer.yml file is read from the most recent commit on the target

branch of each pull request. If bulldozer cannot find a configuration file,

it will take no action. This means it is safe to enable the bulldozer on all

repositories in an organization.


bulldozer.yml Specification


The .bulldozer.yml file supports the following keys.


# "version" is the configuration version, currently "1".
version: 1

# "merge" defines how and when pull requests are merged. If the section is
# missing, bulldozer will consider all pull requests and use default settings.
merge:
  # "trigger" defines the set of pull requests considered by bulldozer. If
  # the section is missing, bulldozer considers all pull requests not excluded
  # by the ignore conditions.
  trigger:
    # Pull requests with any of these labels (case-insensitive) are added to
    # the trigger.
    labels: ["merge when ready"]

    # Pull requests where the body or any comment contains any of these
    # substrings are added to the trigger.
    comment_substrings: ["==MERGE_WHEN_READY=="]

    # Pull requests where any comment matches one of these exact strings are
    # added to the trigger.
    comments: ["Please merge this pull request!"]

    # Pull requests where the body contains any of these substrings are added
    # to the trigger.
    pr_body_substrings: ["==MERGE_WHEN_READY=="]

    # Pull requests targeting any of these branches are added to the trigger.
    branches: ["develop"]

    # Pull requests targeting branches matching any of these regular expressions are added to the trigger.
    branch_patterns: ["feature/.*"]

  # "ignore" defines the set of pull request ignored by bulldozer. If the
  # section is missing, bulldozer considers all pull requests. It takes the
  # same keys as the "trigger" section.
  ignore:
    labels: ["do not merge"]
    comment_substrings: ["==DO_NOT_MERGE=="]

  # "method" defines the merge method. The available options are "merge",
  # "rebase", "squash", and "ff-only".
  method: squash

  # Allows the merge method that is used when auto-merging a PR to be different based on the
  # target branch. The keys of the hash are the target branch name, and the values are the merge method that
  # will be used for PRs targeting that branch. The valid values are the same as for the "method" key.
  # Note: If the target branch does not match any of the specified keys, the "method" key is used instead.
  branch_method:
    develop: squash
    master: merge

  # "options" defines additional options for the individual merge methods.
  options:
    # "squash" options are only used when the merge method is "squash"
    squash:
      # "title" defines how the title of the commit message is created when
      # generating a squash commit. The options are "pull_request_title",
      # "first_commit_title", and "github_default_title". The default is
      # "pull_request_title".
      title: "pull_request_title"

      # "body" defines how the body of the commit message is created when
      # generating a squash commit. The options are "pull_request_body",
      # "summarize_commits", and "empty_body". The default is "empty_body".
      body: "empty_body"

      # If "body" is "pull_request_body", then the commit message will be the
      # part of the pull request body surrounded by "message_delimiter"
      # strings. This is disabled (empty string) by default.
      message_delimiter: ==COMMIT_MSG==

  # "required_statuses" is a list of additional status contexts that must pass
  # before bulldozer can merge a pull request. This is useful if you want to
  # require extra testing for automated merges, but not for manual merges.
  required_statuses:
    - "ci/circleci: ete-tests"

  # If true, bulldozer will delete branches after their pull requests merge.
  delete_after_merge: true

# "update" defines how and when to update pull request branches. Unlike with
# merges, if this section is missing, bulldozer will not update any pull requests.
update:
  # "trigger" defines the set of pull requests that should be updated by
  # bulldozer. It accepts the same keys as the trigger in the "merge" block.
  trigger:
    labels: ["WIP", "Update Me"]

  # "ignore" defines the set of pull requests that should not be updated by
  # bulldozer. It accepts the same keys as the ignore in the "merge" block.
  ignore:
    labels: ["Do Not Update"]


FAQ


Can I specify both ignore and trigger?


Yes. If both ignore and trigger are specified, bulldozer will attempt to match

on both. In cases where both match, ignore will take precedence.


Can I specify the body of the commit when using the squash strategy?


Yes. When the merge strategy is squash, you can set additional options under the

options.squash property, including how to render the commit body.


merge:
  method: squash
  options:
    squash:
      body: summarize_commits # or `pull_request_body`, `empty_body`


You can also define part of pull request body to pick as a commit message when

body is pull_request_body.


merge:
  method: squash
  options:
    squash:
      body: pull_request_body
      message_delimiter: ==COMMIT_MSG==


Anything that's contained between two ==COMMIT_MSG== strings will become the

commit message instead of whole pull request body.


What if I don't want to put config files into each repo?


You can add default repository configuration in your bulldozer config file.


It will be used only when your repo config file does not exist.


options:
  default_repository_config:
    ignore:
      labels: ["do not merge"] # or any other available config.


Bulldozer isn't merging my commit when it should, what could be happening?


Bulldozer will attempt to merge a branch whenever it passes the trigger/ignore

criteria. GitHub may prevent it from merging a branch in certain conditions, some of

which are to be expected, and others that may be caused by mis-configuring Bulldozer.



Bulldozer isn't updating my branch when it should, what could be happening?


When using the branch update functionality, Bulldozer only acts when the target

branch is updated after updates are enabled for the pull request. For

example:


  1. User A opens a pull request targetting develop
  2. User B pushes a commit to develop
  3. User A adds the update me label to the first pull request
  4. User C pushes a commit to develop
  5. Bulldozer updates the pull request with the commits from Users B and C


Note that the update does not happen when the update me label is added,

even though there is a new commit on develop that is not part of the pull

request.


Can Bulldozer work with push restrictions on branches?


As mentioned above, as of Github ~2.19.x, GitHub Apps can be added to the list of users associated

with push restrictions. If you don't want to do this, or if you're running

an older version of Github that doesn't support this behaviour, you may work

around this:


  1. Use another app like policy-bot to
    implement approval restrictions as required status checks instead of using
    push restrictions. This effectively limits who can push to a branch by
    requiring changes to go through the pull request process and be approved.
  2. Configure Bulldozer to use a personal access token for a regular user to
    perform merges in this case. The token must have the repo scope and the
    user must be allowed to push to the branch. In the server configuration
    file, set:
options:
  push_restriction_user_token: <token-value>
  1. The token is only used if the target branch has push restrictions enabled.
    All other merges are performed as the normal GitHub App user.


Deployment


bulldozer is easy to deploy in your own environment as it has no dependencies

other than GitHub. It is also safe to run multiple instances of the server,

making it a good fit for container schedulers like Nomad or Kubernetes.


We provide both a Docker container and a binary distribution of the server:



A sample configuration file is provided at config/bulldozer.example.yml.

Certain values may also be set by environment variables; these are noted in the

comments in the sample configuration file.


GitHub App Configuration


To configure Bulldozer as a GitHub App, these general options are required:



The app requires these permissions:

PermissionAccessReason
Repository administrationRead-onlyDetermine required status checks
ChecksRead-onlyRead checks for ref
Repository contentsRead & writeRead configuration, perform merges
IssuesRead & writeRead comments, close linked issues
Repository metadataRead-onlyBasic repository data
Pull requestsRead & writeMerge and close pull requests
Commit statusRead-onlyEvaluate pull request status


The app should be subscribed to these events:



Operations


bulldozer uses go-baseapp and

go-githubapp, both of which emit

standard metrics and structured log keys. Please see those projects for

details.


Example Files


Example .bulldozer.yml files can be found in config/examples


Migrating: Version 0.4.X to 1.X


The server configuration for bulldozer allows you to specify configuration_v0_path, which is a list of paths

to check for 0.4.X style bulldozer configuration. When a 1.X style configuration file does not appear

at the configured path, bulldozer will attempt to read from the paths configured by configuration_v0_path,

converting the legacy configuration into an equivalent v1 configuration internally.


The upgrade process is therefore to deploy the latest version of bulldozer with both configuration_path and

configuration_v0_path configured, and to enable the bulldozer GitHub App on all organizations where it was

previously installed.


Development


To develop bulldozer, you will need a Go installation.


Run style checks and tests


./godelw verify


Running the server locally


# copy and edit the server config
cp config/bulldozer.example.yml config/bulldozer.yml

./godelw run bulldozer server



Running the server via Docker


# copy and edit the server config
cp config/bulldozer.example.yml config/bulldozer.yml

# build the docker image
./godelw docker build --verbose

docker run --rm -v "$(pwd)/config:/secrets/" -p 8080:8080 palantirtechnologies/bulldozer:latest



Contributing


Contributions and issues are welcome. For new features or large contributions,

we prefer discussing the proposed change on a GitHub issue prior to a PR.


License


This application is made available under the Apache 2.0 License.


probot-auto-merge


image

image


A GitHub App built with Probot that automatically merges PRs



Usage


  1. Configure the GitHub App
  2. Create .github/auto-merge.yml in your repository.
  3. Customize configuration to your needs. See below.


Configuration


Configuration of probot-auto-merge is done through .github/auto-merge.yml in

your repository. An example of this file can be found here.

You can also see the configuration for this repository here.


The configuration has values that serve as conditions on whether or not a pull request

should be automatically merged and also configuration about the merge itself. Values

that serve as conditions are annotated as such below.


All conditions must be met before a PR will be automatically merged. You can get more

flexibility by defining multiple rules. Rules can have multiple conditions and if any

of the conditions inside a rule are met, the PR is also merged. See rules.


If the target branch is a protected branch, you must add probot-auto-merge bot to

the list of People, teams or apps with push access in your branch protection rules.


Note that the default configuration options are to do nothing. This is to prevent

implicit and possibly unintended behavior.


The configuration fields are as follows:


minApprovals (required, condition)


The minimum number of reviews from each association that approve the pull request before

doing an automatic merge. For more information about associations see:

https://developer.github.com/v4/enum/commentauthorassociation/


Possible associations: OWNER, MEMBER, COLLABORATOR, CONTRIBUTOR, FIRST_TIMER, FIRST_TIME_CONTRIBUTOR, NONE


In the example below when a pull request gets 2 approvals from owners, members or collaborators,

the automatic merge will continue.


minApprovals:
  COLLABORATOR: 2


In the example below when a pull request gets 1 approval from an owner OR 2 approvals from members, the automatic merge will continue.


minApprovals:
  OWNER: 1
  MEMBER: 2


requiredReviewers (condition, default: none)


Whenever required reviewers are configured, pull requests will only be automatically

merged whenever all of these reviewers have approved the pull request.


In the example below, pull requests need to have been approved by the user 'rogerluan'

before they will be automatically merged.


requiredReviewers:
- rogerluan


maxRequestedChanges (condition, default: none)


Similar to minApprovals, maxRequestedChanges determines the maximum number of

requested changes before a pull request will be blocked from being automatically

merged.


It yet again allows you to configure this per association.


Note that maxRequestedChanges takes precedence over minApprovals.


In the example below, automatic merges will be blocked when one of the owners, members

or collaborators has requested changes.


maxRequestedChanges:
  COLLABORATOR: 0


In the example below, automatic merges will be blocked when the owner has

requested changes or two members, collaborators or other users have requested

changes.


maxRequestedChanges:
  OWNER: 0
  NONE: 1


The default for this value is:


maxRequestedChanges:
  NONE: 0


blockingBaseBranches (condition, default: none)


Whenever blocking base branches are configured, pull requests will only be automatically

merged whenever their base branch (into which the PR would be merged) is not matching

the patterns listed.


In the example below, pull requests that have the base branch develop or one that starts

with feature- will not be merged automatically.


blockingBaseBranches:
- develop
- regex: ^feature-


Note: remove the whole section when you're not using blocking base branches.


requiredBaseBranches (condition, default: none)


Whenever required base branches are configured, pull requests will only be automatically

merged whenever their base branch (into which the PR would be merged) is matching

any of the patterns listed.


In the example below, pull requests need to have the base branch master or one that

starts with v{number} before they will be automatically merged.


requiredBaseBranches:
- master
- regex: ^v\d


blockingLabels (condition, default: none)


Blocking labels are the labels that can be attached to a pull request to make

sure the pull request is not being merged automatically.


In the example below, pull requests that have the blocked label will not be

merged automatically.


blockingLabels:
- blocked


The above example denotes literal label names. Regular expressions can be used to

partially match labels. This can be specified by the regex: property in the

configuration. The following example will block merging when a label is added that

starts with the text blocked:


blockingLabels:
- regex: ^blocked


Note: remove the whole section when you're not using blocking labels.


requiredLabels (condition, default: none)


Whenever required labels are configured, pull requests will only be automatically

merged whenever all of these labels are attached to a pull request.


In the example below, pull requests need to have the label merge before they

will be automatically merged.


requiredLabels:
- merge


The above example denotes literal label names. Regular expressions can be used to

partially match labels. This requires regex: property in the configuration. The

following example will requires at least one label that starts with merge:


requiredLabels:
- regex: ^merge


Note: remove the whole section when you're not using required labels.


blockingTitleRegex (condition, default: none)


Whenever a blocking title regular expression is configured, pull requests that have a title

matching the configured expression will not be automatically merged.


This is useful whenever pull requests with WIP in their title need to be skipped.


In the example below, pull requests with the word wip in the title will not be

automatically merged. This also includes [wip], WIP or [WIP], but not swiping:


blockingTitleRegex: '\bWIP\b'


requiredTitleRegex (condition, default: none)


Whenever a required title regular expression is configured, only pull requests that have a title

matching the configured expression will automatically be merged.


This is useful for forks, that can only create pull request text, no labels.


In the example below, pull requests with the title containing MERGE will be

automatically merged. This also includes This also includes [merge], MERGE or [MERGE], but not submerge:


requiredTitleRegex: '\bMERGE\b'


blockingBodyRegex (condition, default: none)


Whenever a blocking body regular expression is configured, pull requests that have a body

matching the configured expression will not be automatically merged.


This is useful whenever pull requests with a certain string in their body need to be skipped.


In the example below, pull requests with the body containing do-not-merge will not be

automatically merged. This also includes labels: do-not-merge, LABELS: DO-NOT-MERGE or some more text, but do-not-merge,

but not do-not-merge-just-kidding:


blockingBodyRegex: '(^|\\s)do-not-merge($|\\s)'


requiredBodyRegex (condition, default: none)


Whenever a required body regular expression is configured, only pull requests that have a body

matching the configured expression will automatically be merged.


This is useful for forks, that can only create pull request text, no labels.


In the example below, pull requests with the body containing ok-to-merge will be

automatically merged. This also includes labels: ok-to-merge, LABELS: OK-TO-MERGE or some more text, but ok-to-merge, but not not-ok-to-merge:


requiredBodyRegex: '(^|\\s)ok-to-merge($|\\s)'


reportStatus (default: false)


The status of the auto-merge process will be shown in each PR as a check. This can be especially useful to find out why a PR is not being merged automatically.


To enable status reporting, add the following to your configuration:


reportStatus: true


updateBranch (default: false)


Whether an out-of-date pull request is automatically updated.

It does so by merging its base on top of the head of the pull request.

This is similar to the behavior of the 'Update branch' button.


updateBranch is useful for repositories where protected branches are used

and the option Require branches to be up to date before merging is enabled.


Note that this only works when the branch of the pull request resides in the same

repository as the pull request itself.


In the example below automatic updating of branches is enabled:


updateBranch: true


deleteBranchAfterMerge (default: false)


Whether the pull request branch is automatically deleted.

This is the equivalent of clicking the 'Delete branch' button shown on merged

pull requests.


Note that this only works when the branch of the pull request resides in the same

repository as the pull request itself.


In the example below automatic deletion of pull request branches is enabled:


deleteBranchAfterMerge: true


mergeMethod (default: merge)


In what way a pull request is merged. This can be:



For more information see https://help.github.com/articles/about-pull-request-merges/


mergeMethod: merge


mergeCommitMessage (default: none)


Optionally specify the merge commit message format. The following template tags

are supported:



When this option is not set, the merge commit message is controlled by

GitHub and uses a combination of the title of the pull request when it was

opened (note that later changes to the title are ignored) and a list of

commits.


This settings is ignored when mergeMethod is set to rebase.


mergeCommitMessage: |
  {title} (#{number})
  {body}


rules (default: none)


Rules allow more flexibility configuring conditions for automatically merging. Each rule is defined by

multiple conditions. All conditions inside a rule must be met before a rule triggers a merge. Any of the

defined rules can trigger a merge individually.


An example of a configuration with 2 rules that will trigger a merge upon 1 approval from an owner or a merge label:


rules:
- minApprovals:
    OWNER: 1
- requiredLabels:
    - merge


This can be combined with conditions on global level, as the global conditions will take precedence. The following example will not trigger a merge when a PR has the blocking label, regardless what the rules say:


blockingLabels:
- blocking
rules:
- minApprovals:
    OWNER: 1
- requiredLabels:
    - merge


Note: remove the whole rules section when you're not using any rules.


requiredAuthorRole (default: none)


Using the requiredAuthorRole condition you can specify conditions based on the role of the pull request author.

For instance, using rules, one can be more loose when the author is an owner, and more restrictive otherwise.


Here's an example of a configuration that requires acceptance of 2 owners or 1 owner if the other owner made the PR:


rules:
- requiredAuthorRole: OWNER
  minApprovals:
    OWNER: 1
- minApprovals:
    OWNER: 2


Development


Setup


# Install dependencies
npm install

# Run typescript
npm run build


Testing


npm run test


or during development:


npm run test:watch


Running


See https://probot.github.io/docs/development/#configuring-a-github-app


npm run build && npm run dev


Running on Docker


This will build and run the app on a container called probot-auto-merge:


npm run docker


To just build the container image:


npm run docker:build


To run the built image:


npm run docker:run


Running the linter


This will run the linter, pointing out the infractions, but it won't fix them automatically.


npm run lint


Deployment


To deploy probot-auto-merge yourself, please follow the guidelines defined by Probot on deploying GitHub applications.


The permissions and events needed for the app to function can be found below.


Permissions



Events



Contributing


If you have suggestions for how probot-auto-merge could be improved, or want to report a bug, open an issue! We'd love all and any contributions.


For more, check out the Contributing Guide.


License


ISC © 2018 Bob van der Linden bobvanderlinden@gmail.com (https://github.com/bobvanderlinden/probot-auto-merge)


auto-label-merge-conflicts


A Github action to auto-label PRs with merge conflicts


Purpose


This action checks all open Pull Requests for merge conflicts and marks them with a Github label.


image


Once a conflict is resolved the label is automatically removed.


The typical use case is to run this action post merge (e.g. push to master) to quickly see which other PRs are now in conflict.


We use this setup e.g. on our monorepo at Comtravo. Instead of a grumpy CTO pinging developers to fix their merge conflicts there's now a shiny bot.


Set up


To configure the action on your repo you have to do 2 things:


  1. pick a Github label that should be used to mark PRs with conflicts


This label will then be managed by this action. It will be added to PRs with merge conflicts and removed from PRs without conflicts.


  1. configure the new workflow by creating a YML config file in your .github/workflows folder:


on:
  push:
    branches:
      - master
jobs:
  triage:
    runs-on: ubuntu-latest
    steps:
      - uses: mschilde/auto-label-merge-conflicts@master
        with:
          CONFLICT_LABEL_NAME: "has conflicts"
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          MAX_RETRIES: 5
          WAIT_MS: 5000


The label from step 1 should be referenced in the parameter CONFLICT_LABEL_NAME


Take a look at this repo for an example setup.


Arguments:



Limitations


Github does not reliably compute the mergeable status which is used by this action to detect merge conflicts.


If master changes the mergeable status is unknown until someone (most likely this action) requests it. Github then tries to compute the status with an async job.


This is usually quick and simple, but there are no guarantees and Github might have issues.

You can tweak MAX_RETRIES and WAIT_MS to increase the timeout before giving up on a Pull Request.


Local dev setup


To play around with the code base, you need Docker and make set up locally.


Run make build, make develop, then yarn install.

How to use PR Valet

Step 1: Install PR Valet.

Step 2: Add the valet:merge label to your pull request.

Step 3: Work on your other tasks while PR Valet takes care of merging your pull request.

https://docs.mergify.io/

https://snyk.io/