This action creates a pull request to merge commits from one branch into another. It is designed to run on every push to keep branches for newer versions up-to-date.
A sample workflow is included in the examples directory. The workflow acts on every push to matching branches and uses this action to create a pull request up to the next branch.
The branch selection algorithm will target the branch for the next SemVer
release with its pull request. For example, assuming a commit was pushed to
v1.3
, the branch selection will consider the following branches in order:
v1.4
v2.0
- The configured fallback branch (if set)
If no matching branch is found, the action exits without creating a pull request. The same applies when no mergeable commits are found. Once the merge-up pull request has been merged, the action will repeat the process until no matching branch has been found. It can thus be used to efficiently merge changes up through several releases, ensuring branch protection rules and CI requirements are met.
In addition to the branchNamePattern
you can also specify a
devBranchNamePattern
input. This can be used if you are maintaining multiple
major versions at the same time. Considering the default value for
branchNamePattern
(<major>.<minor>
) and a devBranchNamePattern
of
<major>.x
, the candidate branches when a commit is pushed to v1.3
looks like
this:
v1.4
v1.x
v2.0
v2.x
- The configured fallback branch (if set)
When pushing to a branch that matches the dev name pattern (e.g. v1.x
), only
branches for the next major version are considered:
v2.0
v2.x
- The configured fallback branch (if set)
If you have no GitHub Actions workflows that are run when a new pull request is pushed, you can rely on the default token as long as you specify additional permissions for it:
permissions:
contents: write
pull-requests: write
If you need to run actions on newly created pull request, create a custom token
with the repo
scope and use it instead of the default github.token
. Note
that you also need to pass a token to the checkout action to ensure credentials
are set in the Git repository to allow you to push a new branch.
The action creates an intermediate branch as head reference for the pull
request. For example, when merging v1.3
into v1.4
, the action will create a
branch named merge-v1.3-into-v1.4-<token>
. If there are conflicts in this
merge, you can resolve these conflicts in this branch. There are two approaches
for this:
In the example above, you can merge v1.4
into this intermediate branch and
resolve conflicts:
git merge --no-ff v1.4
After resolving conflicts, conclude the merge and push commits.
If you would instead like to perform the merge manually, you can start out fresh. In the example above, this would look something like this:
git reset --hard v1.4
git merge --no-ff v1.3
After resolving commits, conclude the merge and push commits. This will require force-pushing since the commit history of the branches will diverge.
The action supports the following input parameters:
The ref
input identifies the reference being pushed. Typically, this will be
${{ github.ref_name }}
The branchNamePattern
input can be used to configure the naming strategy for
versioned branches. It defaults to <major>.<minor>
. <major>
and <minor>
inside this pattern are used as placeholders and replaced accordingly. Note that
the pattern needs to contain both placeholders for the action to function
correctly. The branch name pattern is used for the following purposes:
- To check if the source ref name matches a versioned branch. For this purpose,
the
<major>
and<minor>
are replaced with[0-9]+
to perform aRegExp
match - To generate new branch names. When checking for branches, the placeholders are replaced with the computed values according to the SemVer release.
The devBranchNamePattern
input can be used to configure the naming strategy
for development (i.e. upcoming versions) branches. By default, it is empty and
supports <major>
as a placeholder. This pattern is used to match the branch
name if it does not match the branchNamePattern
, and is used to generate
candidate branch names, where the <major>
placeholder is replaced with the
computed value according to the SemVer release.
If your branch naming pattern involves a non-versioned branch for the upcoming
version (e.g. main
), the fallbackBranch
option can be used to specify this
branch name. If no versioned branch was found, the pull request will target this
fallback branch instead. The "Branch Selection" chapter above explains the order
of operations.
When this option is enabled (using a truish value), the resulting PR will have auto-merge enabled. Note that in order for this to work, the auto-merge functionality has to be enabled on the repository, and the "merge" merge strategy has to be available. Automatic merges are always done using the "merge" strategy.
There is a separate action named get-next-branch
that can be used to run the
branch detection logic and return the determined information. This is useful if
you want to run your own logic for handling merges.
- name: 'Determine branch to merge up to'
id: get-next-branch
uses: alcaeus/automatic-merge-up-action/get-next-branch@main
with:
ref: ${{ github.ref_name }}
branchNamePattern: 'v<major>.<minor>'
fallbackBranch: 'master'
The action takes the same inputs as the default create-pr action, except for the
enableAutoMerge
input which doesn't exist. The action sets two outputs:
hasNextBranch
: this bool output istrue
if the branch detection logic found a branch to merge up to,false
otherwise.branchName
: this is the name of the next branch in the merge chain. If no next branch was found (i.e.hasNextBranch
isfalse
), this value isnull
.