repoactive 0.2.7__tar.gz → 0.2.8.dev2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/PKG-INFO +1 -1
  2. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/pyproject.toml +1 -1
  3. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/platforms/gitlab.py +39 -19
  4. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/.gitignore +0 -0
  5. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/LICENSE +0 -0
  6. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/README.md +0 -0
  7. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/__init__.py +0 -0
  8. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/boxquote.py +0 -0
  9. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/cli.py +0 -0
  10. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/config.py +0 -0
  11. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/constants.py +0 -0
  12. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/graph.py +0 -0
  13. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/jj.py +0 -0
  14. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/jobtree.py +0 -0
  15. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/lock.py +0 -0
  16. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/platforms/__init__.py +0 -0
  17. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/platforms/base.py +0 -0
  18. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/platforms/github.py +0 -0
  19. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/progress.py +0 -0
  20. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/runner.py +0 -0
  21. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/selection.py +0 -0
  22. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/settings.py +0 -0
  23. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/trailers.py +0 -0
  24. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/ui.py +0 -0
  25. {repoactive-0.2.7 → repoactive-0.2.8.dev2}/src/repoactive/updates.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: repoactive
3
- Version: 0.2.7
3
+ Version: 0.2.8.dev2
4
4
  Summary: Script-driven code changes with automated merge requests
5
5
  License-Expression: GPL-3.0-or-later
6
6
  License-File: LICENSE
@@ -10,7 +10,7 @@ only-include = ["src"]
10
10
 
11
11
  [project]
12
12
  name = "repoactive"
13
- version = "0.2.7"
13
+ version = "0.2.8.dev2"
14
14
  description = "Script-driven code changes with automated merge requests"
15
15
  readme = "README.md"
16
16
  requires-python = ">=3.11"
@@ -11,14 +11,16 @@ from repoactive.platforms.base import MRParams, Platform, PlatformError
11
11
  _DRAFT_PREFIX = "Draft: "
12
12
 
13
13
  # detailed_merge_status / merge_status values that mean GitLab's async
14
- # mergeability check hasn't finished yet. Setting auto-merge while the check is
15
- # pending returns 422 "Branch cannot be merged".
14
+ # mergeability check hasn't finished yet. On GitLab without the auto_merge
15
+ # parameter (< 17.11), setting auto-merge while the check is pending returns
16
+ # 422 "Branch cannot be merged".
16
17
  _MERGE_CHECK_PENDING = frozenset({"unchecked", "checking", "preparing"})
17
18
 
18
- # A freshly created MR is not immediately ready for auto-merge: GitLab runs the
19
- # mergeability check and creates the MR pipeline in the background. Poll for
20
- # that to settle, bounded by this timeout; the next run re-attempts if it never
21
- # does.
19
+ # Fallback for GitLab without the auto_merge parameter: a freshly created MR is
20
+ # not immediately ready for merge_when_pipeline_succeeds because GitLab runs
21
+ # the mergeability check and creates the MR pipeline in the background. Poll
22
+ # for that to settle, bounded by this timeout; the next run re-attempts if it
23
+ # never does.
22
24
  _AUTO_MERGE_TIMEOUT = 60.0
23
25
  _AUTO_MERGE_POLL_INTERVAL = 3.0
24
26
 
@@ -92,21 +94,39 @@ class GitLabPlatform(Platform):
92
94
  return web_url
93
95
 
94
96
  def _enable_auto_merge(self, mr: ProjectMergeRequest) -> None:
95
- """Set merge_when_pipeline_succeeds once the MR is ready, else warn.
96
-
97
- Re-fetches the MR (the list/create payloads omit head_pipeline) and
98
- polls until it is ready for auto-merge or the timeout passes. A repo
99
- with no CI never grows a pipeline; there the poll times out and the
100
- final call merges immediately, the best available behavior.
97
+ """Enable auto-merge on ``mr``, retrying until it is accepted.
98
+
99
+ The merge call sends both auto-merge parameters: on GitLab >= 17.11
100
+ ``auto_merge`` selects the "merge when checks pass" strategy and older
101
+ GitLab ignores it and honors the deprecated
102
+ merge_when_pipeline_succeeds. Right after a push GitLab rejects the
103
+ call (405/422) while its state is still settling - the mergeability
104
+ check runs, the MR pipeline gets created and linked - so a rejection
105
+ is retried until the deadline, waiting in between for the MR to look
106
+ ready (re-fetched, since list/create payloads omit head_pipeline).
107
+ That readiness gate keeps the old-GitLab semantics: retrying without a
108
+ pipeline there would merge immediately and skip CI. A repo with no CI
109
+ never grows a pipeline; there the wait times out and one final call
110
+ merges immediately, the best available behavior.
101
111
  """
102
112
  iid = mr.iid
103
113
  deadline = time.monotonic() + _AUTO_MERGE_TIMEOUT
114
+ final_attempt = False
104
115
  while True:
105
- mr = self._project.mergerequests.get(iid)
106
- if _ready_for_auto_merge(mr) or time.monotonic() >= deadline:
107
- break
116
+ try:
117
+ mr.merge(merge_when_pipeline_succeeds=True, auto_merge=True)
118
+ return
119
+ except GitlabMRClosedError as e:
120
+ # python-gitlab wraps every merge failure in
121
+ # GitlabMRClosedError; this is usually the 422/405 "not ready
122
+ # yet" case, not a closed MR.
123
+ if final_attempt:
124
+ print(f" warning: could not enable auto-merge ({e})")
125
+ return
108
126
  time.sleep(_AUTO_MERGE_POLL_INTERVAL)
109
- try:
110
- mr.merge(merge_when_pipeline_succeeds=True)
111
- except GitlabMRClosedError as e:
112
- print(f" warning: could not enable auto-merge ({e})")
127
+ while True:
128
+ mr = self._project.mergerequests.get(iid)
129
+ if _ready_for_auto_merge(mr) or time.monotonic() >= deadline:
130
+ break
131
+ time.sleep(_AUTO_MERGE_POLL_INTERVAL)
132
+ final_attempt = time.monotonic() >= deadline
File without changes
File without changes
File without changes