Skip to content

feat(github): add client-side pull request merge option#8204

Merged
olblak merged 7 commits into
updatecli:mainfrom
LeC-D:feat/github-client-side-merge
Apr 5, 2026
Merged

feat(github): add client-side pull request merge option#8204
olblak merged 7 commits into
updatecli:mainfrom
LeC-D:feat/github-client-side-merge

Conversation

@LeC-D

@LeC-D LeC-D commented Mar 28, 2026

Copy link
Copy Markdown
Contributor

Fix #2312

Add a new clientsidemerge option to the GitHub action spec that allows updatecli to merge a pull request directly via the GitHub GraphQL API (mergePullRequest mutation), bypassing the need for server-side auto-merge which requires a paid plan or a public repository.

Changes

  • Added ClientSideMerge bool field to ActionSpec in pkg/plugins/scms/github/pullrequest.go
  • Added mutationMergePullRequest GraphQL mutation struct
  • Added MergePullRequest(retry int) error method on PullRequest
  • CreateAction now calls MergePullRequest when clientsidemerge: true

Usage

actions:
  default:
    title: 'Update dependency'
    kind: github/pullrequest
    spec:
      clientsidemerge: true      # merge immediately via API (no server-side automerge needed)
      mergemethod: squash        # optional, defaults to 'merge'

The merge method is controlled by the existing mergemethod field. The usetitleforautomerge flag is also respected for custom commit headlines on squash/rebase merges.

Unlike automerge (server-side), this performs the merge immediately — it will fail if the PR is not in a mergeable state (conflicts, pending required checks, etc.).

Test

To test this pull request, you can run the following commands:

cd pkg/plugins/scms/github
go test

Additional Information

Checklist

  • I have updated the documentation via pull request in website repository.

Tradeoff

This approach merges immediately without waiting for CI checks to pass. Users should be aware that enabling clientsidemerge without required branch protection rules could merge a PR with failing tests.

Potential improvement

A future improvement could add a polling mechanism to wait until all required checks pass before attempting the merge (similar to what gh pr merge --auto does).

@LeC-D LeC-D force-pushed the feat/github-client-side-merge branch from 49e6d51 to 0512748 Compare March 29, 2026 16:04
@LeC-D

LeC-D commented Mar 29, 2026

Copy link
Copy Markdown
Contributor Author

Rebased on upstream main (2026-03-29) to bring the branch back up to date.

@olblak

olblak commented Mar 30, 2026

Copy link
Copy Markdown
Member

Awesome thanks for the pullrequest.

This approach merges immediately without waiting for CI checks to pass. Users should be aware that enabling clientsidemerge without required branch protection rules could merge a PR with failing tests.

I am wondering if we couldn't expose a parameter to keep a pull request open for a specific amount of days so Updatecli wouldn't try to merge a pull request right after creating it.

But it's already great that it won't try to merge a pullrequest with failing requirements

@olblak

olblak commented Mar 30, 2026

Copy link
Copy Markdown
Member

Don't worry to maintain this pull request up to date for now, I would like to test it manually

@olblak olblak added enhancement New feature or request pullrequest-github labels Mar 30, 2026
@LeC-D

LeC-D commented Mar 30, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the thoughtful feedback, @olblak!

The idea of a keep_open_days (or similar merge_after) parameter makes a lot of sense — it would let users add a mandatory baking period before Updatecli attempts a merge, giving CI time to run, reviewers time to weigh in, etc. I'd be happy to implement that if you'd like it as part of this PR, or I can open a follow-up issue to track it separately.

In the meantime, take your time testing — happy to address any findings!

@LeC-D LeC-D force-pushed the feat/github-client-side-merge branch from 0512748 to 5c70ed0 Compare March 30, 2026 18:04
@LeC-D

LeC-D commented Mar 30, 2026

Copy link
Copy Markdown
Contributor Author

Rebased on upstream main (2026-03-30) to bring the branch back up to date.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new GitHub Pull Request action option to merge PRs directly via the GitHub GraphQL API (“client-side merge”), intended to bypass GitHub’s server-side auto-merge limitations (paid plan / public repo constraints).

Changes:

  • Introduces clientsidemerge in the GitHub PR action spec (ActionSpec) to trigger an immediate merge after PR creation/update.
  • Adds a mergePullRequest GraphQL mutation wrapper and a PullRequest.MergePullRequest method.
  • Updates CreateAction to call MergePullRequest when clientsidemerge: true.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/plugins/scms/github/pullrequest.go Outdated
Comment thread pkg/plugins/scms/github/pullrequest.go Outdated
Comment thread pkg/plugins/scms/github/pullrequest.go Outdated
@olblak

olblak commented Apr 1, 2026

Copy link
Copy Markdown
Member
  • Could I ask you to review copilot comments?

  • Could I also ask you to improve this pull request by not merging pullrequest newer than Xhour something like this

actions:
  default:
    title: 'Update dependency'
    kind: github/pullrequest
    spec:
      merge:
        strategy: client        # client | auto | manual, default to manual 
        client: true      # merge immediately via API (no server-side automerge needed)
        after: 24h # Never merge pullrequest before waiting for 24 h
        reseton: commit # Track the latest commit

Please note that I am making a suggestion to use nested merge parameter, not mandatory but I am wondering if it looks better. So it would mean deprecating automerge into merge.strategy: auto

To deprecate automerge if we could simplify change this line to a pointer of string. Then if nil then we set merge.strategy to manual otherwise we should a deprecation message and then set merge.strategy to "auto"

@LeC-D LeC-D force-pushed the feat/github-client-side-merge branch from 5c70ed0 to 11568ed Compare April 1, 2026 10:11
@LeC-D

LeC-D commented Apr 1, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed feedback, @olblak! I've addressed all three points in the latest commit (11568ed):

  • Nested merge spec: Replaced clientsidemerge: bool with a structured Merge sub-spec supporting strategy (client | auto | manual) and after (e.g. 24h) — exactly the shape you suggested.
  • automerge deprecation: Changed AutoMerge to a *bool pointer; when set, it emits a deprecation warning and maps to merge.strategy: auto. nil pointer now correctly defaults to manual.
  • Copilot suggestions applied: Minimized the mutationMergePullRequest response struct to avoid fetching unneeded fields, added a nil-guard for rateLimit before calling .Pause(), and added a guard to prevent concurrent server-side automerge + client-side merge.

Take your time testing — happy to address any further findings!

LeC-D added 2 commits April 1, 2026 12:04
Add a new 'clientsidemerge' option to the GitHub action spec that allows
updatecli to merge a pull request directly via the GitHub GraphQL API
(mergePullRequest mutation), bypassing the need for server-side auto-merge
which requires a paid plan or a public repository.

When 'clientsidemerge: true' is set, updatecli will attempt to merge
the pull request immediately after it is created or updated. The merge
will fail if the PR is not in a mergeable state (e.g. has conflicts or
failing required checks).

The merge method is controlled by the existing 'mergemethod' field and
defaults to GitHub's default ('MERGE') if not specified. The
'usetitleforautomerge' flag is also respected to set a custom commit
headline for squash and rebase merges.

Fixes updatecli#2312
- Replace ClientSideMerge bool with nested Merge.Strategy/After fields
- Deprecate AutoMerge bool -> *bool with migration warning to merge.strategy: auto
- Add merge.after support to delay client-side merge by a configured duration
- Minimize mutationMergePullRequest response struct (Copilot suggestion)
- Guard nil rateLimit before calling Pause() in MergePullRequest
- Add CreatedAt field to PullRequestApi
@LeC-D LeC-D force-pushed the feat/github-client-side-merge branch from 11568ed to 105465d Compare April 1, 2026 16:05
@LeC-D

LeC-D commented Apr 1, 2026

Copy link
Copy Markdown
Contributor Author

Rebased on upstream main (2026-04-01) to resolve the merge conflict in pullrequest.go — the conflict arose from an upstream change that still references the old AutoMerge bool field; kept our restructured Merge.Strategy switch. Branch is clean again.

@LeC-D

LeC-D commented Apr 3, 2026

Copy link
Copy Markdown
Contributor Author

Rebased on upstream main (2026-04-03) to bring the branch back up to date.

olblak and others added 5 commits April 3, 2026 23:51
…i#8155)

* feat: add PyPI resource and pyproject autodiscovery plugins

Add Python ecosystem support to updatecli with two new plugins:

- pypi resource: queries PyPI JSON API for package versions,
  with PEP 440 to semver normalization (a/b/rc pre-releases),
  private registry support (Bearer token), and yanked version filtering.

- pyproject autodiscovery: discovers pyproject.toml + uv.lock pairs,
  parses PEP 508 dependencies, generates manifests using pypi source
  and uv add shell target. Named pyproject (alias python/uv) for
  multi-PM extensibility following the npm pattern.

Signed-off-by: Loïs Postula <lois@postu.la>

* fix: cursor comments

---------

Signed-off-by: Loïs Postula <lois@postu.la>
* use constants for merge client strategy
* add closing pullrequest in cleanAction
* set default value to 24h for auto merge client
* correctly fallback from automerge setting to either manual or auto

Signed-off-by: Olblak <me@olblak.com>
Signed-off-by: Olblak <me@olblak.com>
@olblak

olblak commented Apr 5, 2026

Copy link
Copy Markdown
Member

Thanks for the pullrequest, I run some tests and it worked almost as expected. My last commits added the missing parts

  • use constants for merge client strategy
  • add closing pullrequest in cleanAction
  • set default value to 24h for auto merge client
  • correctly fallback from automerge setting to either manual or auto

@olblak

olblak commented Apr 5, 2026

Copy link
Copy Markdown
Member

Especially the default waiting time to 24h, I know it's an arbitrary value, but I think it's better to have some waiting by default

@olblak

olblak commented Apr 5, 2026

Copy link
Copy Markdown
Member

Thansk @LeC-D for the pr

@olblak olblak merged commit c457824 into updatecli:main Apr 5, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request pullrequest-github

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: client side Gtihub Pull Request auto-merge

4 participants