mergify-cli 2026.5.5.1__py3-none-win_amd64.whl
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.
- mergify_cli/__init__.py +20 -0
- mergify_cli/__main__.py +22 -0
- mergify_cli/_globals.py +30 -0
- mergify_cli/ci/__init__.py +0 -0
- mergify_cli/ci/cli.py +391 -0
- mergify_cli/ci/detector.py +297 -0
- mergify_cli/ci/git_refs/__init__.py +0 -0
- mergify_cli/ci/git_refs/detector.py +173 -0
- mergify_cli/ci/github_event.py +36 -0
- mergify_cli/ci/junit_processing/__init__.py +0 -0
- mergify_cli/ci/junit_processing/cli.py +306 -0
- mergify_cli/ci/junit_processing/junit.py +283 -0
- mergify_cli/ci/junit_processing/quarantine.py +149 -0
- mergify_cli/ci/junit_processing/upload.py +64 -0
- mergify_cli/ci/queue/__init__.py +0 -0
- mergify_cli/ci/queue/metadata.py +88 -0
- mergify_cli/ci/queue/notes.py +74 -0
- mergify_cli/ci/scopes/__init__.py +0 -0
- mergify_cli/ci/scopes/changed_files.py +120 -0
- mergify_cli/ci/scopes/cli.py +286 -0
- mergify_cli/ci/scopes/config/__init__.py +20 -0
- mergify_cli/ci/scopes/config/root.py +40 -0
- mergify_cli/ci/scopes/config/scopes.py +81 -0
- mergify_cli/ci/scopes/exceptions.py +5 -0
- mergify_cli/cli.py +107 -0
- mergify_cli/dym.py +43 -0
- mergify_cli/exit_codes.py +39 -0
- mergify_cli/freeze/__init__.py +0 -0
- mergify_cli/freeze/api.py +125 -0
- mergify_cli/freeze/cli.py +363 -0
- mergify_cli/github_types.py +29 -0
- mergify_cli/queue/__init__.py +0 -0
- mergify_cli/queue/api.py +161 -0
- mergify_cli/queue/cli.py +586 -0
- mergify_cli/stack/__init__.py +0 -0
- mergify_cli/stack/approvals.py +190 -0
- mergify_cli/stack/changes.py +378 -0
- mergify_cli/stack/checkout.py +113 -0
- mergify_cli/stack/cli.py +697 -0
- mergify_cli/stack/edit.py +51 -0
- mergify_cli/stack/hooks/scripts/commit-msg.sh +91 -0
- mergify_cli/stack/hooks/scripts/post-commit.sh +41 -0
- mergify_cli/stack/hooks/scripts/pre-push.sh +53 -0
- mergify_cli/stack/hooks/scripts/prepare-commit-msg.sh +109 -0
- mergify_cli/stack/hooks/wrappers/commit-msg +11 -0
- mergify_cli/stack/hooks/wrappers/post-commit +14 -0
- mergify_cli/stack/hooks/wrappers/pre-push +11 -0
- mergify_cli/stack/hooks/wrappers/prepare-commit-msg +11 -0
- mergify_cli/stack/list.py +488 -0
- mergify_cli/stack/list_schema.py +82 -0
- mergify_cli/stack/move.py +97 -0
- mergify_cli/stack/new.py +79 -0
- mergify_cli/stack/note.py +138 -0
- mergify_cli/stack/open.py +125 -0
- mergify_cli/stack/push.py +1390 -0
- mergify_cli/stack/reorder.py +286 -0
- mergify_cli/stack/replay.py +233 -0
- mergify_cli/stack/setup.py +249 -0
- mergify_cli/stack/slug.py +208 -0
- mergify_cli/stack/squash.py +166 -0
- mergify_cli/stack/sync.py +347 -0
- mergify_cli/tests/__init__.py +0 -0
- mergify_cli/tests/ci/__init__.py +0 -0
- mergify_cli/tests/ci/fixtures/junit_example.xml +47 -0
- mergify_cli/tests/ci/fixtures/junit_example_nested_single_suite.xml +7 -0
- mergify_cli/tests/ci/fixtures/junit_example_single_suite.xml +12 -0
- mergify_cli/tests/ci/fixtures/report.xml +15 -0
- mergify_cli/tests/ci/fixtures/report_all_pass.xml +8 -0
- mergify_cli/tests/ci/fixtures/report_invalid.xml +1 -0
- mergify_cli/tests/ci/fixtures/report_mixed.xml +15 -0
- mergify_cli/tests/ci/fixtures/report_no_testcases.xml +5 -0
- mergify_cli/tests/ci/git_refs/test_git_refs_detector.py +398 -0
- mergify_cli/tests/ci/junit_processing/__init__.py +0 -0
- mergify_cli/tests/ci/junit_processing/test_check_failing_spans.py +223 -0
- mergify_cli/tests/ci/junit_processing/test_cli.py +947 -0
- mergify_cli/tests/ci/junit_processing/test_upload.py +111 -0
- mergify_cli/tests/ci/pull_request.json +449 -0
- mergify_cli/tests/ci/push_event.json +46 -0
- mergify_cli/tests/ci/queue/__init__.py +0 -0
- mergify_cli/tests/ci/queue/test_metadata.py +181 -0
- mergify_cli/tests/ci/queue/test_notes.py +136 -0
- mergify_cli/tests/ci/scopes/__init__.py +0 -0
- mergify_cli/tests/ci/scopes/test_changed_files.py +246 -0
- mergify_cli/tests/ci/scopes/test_cli.py +756 -0
- mergify_cli/tests/ci/test_cli.py +719 -0
- mergify_cli/tests/ci/test_cli_exit_codes.py +53 -0
- mergify_cli/tests/ci/test_detector.py +546 -0
- mergify_cli/tests/ci/test_github_event.py +75 -0
- mergify_cli/tests/ci/test_junit.py +945 -0
- mergify_cli/tests/conftest.py +156 -0
- mergify_cli/tests/freeze/__init__.py +0 -0
- mergify_cli/tests/freeze/test_cli.py +514 -0
- mergify_cli/tests/queue/__init__.py +0 -0
- mergify_cli/tests/queue/test_cli.py +528 -0
- mergify_cli/tests/queue/test_show.py +363 -0
- mergify_cli/tests/queue/test_skill.py +79 -0
- mergify_cli/tests/stack/__init__.py +0 -0
- mergify_cli/tests/stack/test_approvals.py +713 -0
- mergify_cli/tests/stack/test_checkout.py +235 -0
- mergify_cli/tests/stack/test_edit.py +203 -0
- mergify_cli/tests/stack/test_list.py +771 -0
- mergify_cli/tests/stack/test_move.py +333 -0
- mergify_cli/tests/stack/test_new.py +206 -0
- mergify_cli/tests/stack/test_note.py +292 -0
- mergify_cli/tests/stack/test_open.py +441 -0
- mergify_cli/tests/stack/test_push.py +3063 -0
- mergify_cli/tests/stack/test_reorder.py +361 -0
- mergify_cli/tests/stack/test_replay.py +353 -0
- mergify_cli/tests/stack/test_setup.py +517 -0
- mergify_cli/tests/stack/test_slug.py +115 -0
- mergify_cli/tests/stack/test_squash.py +496 -0
- mergify_cli/tests/stack/test_squash_cli.py +53 -0
- mergify_cli/tests/stack/test_sync.py +1220 -0
- mergify_cli/tests/test_cli.py +150 -0
- mergify_cli/tests/test_dym.py +73 -0
- mergify_cli/tests/test_exit_code_contract.py +66 -0
- mergify_cli/tests/test_exit_codes.py +42 -0
- mergify_cli/tests/test_port_status.py +158 -0
- mergify_cli/tests/test_utils.py +398 -0
- mergify_cli/tests/utils.py +252 -0
- mergify_cli/utils.py +475 -0
- mergify_cli-2026.5.5.1.data/scripts/mergify.exe +0 -0
- mergify_cli-2026.5.5.1.dist-info/METADATA +94 -0
- mergify_cli-2026.5.5.1.dist-info/RECORD +127 -0
- mergify_cli-2026.5.5.1.dist-info/WHEEL +4 -0
- mergify_cli-2026.5.5.1.dist-info/licenses/LICENSE +176 -0
- mergify_cli-2026.5.5.1.dist-info/sboms/mergify-cli.cyclonedx.json +6725 -0
mergify_cli/__init__.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright © 2021-2026 Mergify SAS
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
5
|
+
# not use this file except in compliance with the License. You may obtain
|
|
6
|
+
# a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
12
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
13
|
+
# License for the specific language governing permissions and limitations
|
|
14
|
+
# under the License.
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
from mergify_cli._globals import VERSION as VERSION
|
|
19
|
+
from mergify_cli._globals import console as console
|
|
20
|
+
from mergify_cli._globals import console_error as console_error
|
mergify_cli/__main__.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright © 2021-2026 Mergify SAS
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
5
|
+
# not use this file except in compliance with the License. You may obtain
|
|
6
|
+
# a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
12
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
13
|
+
# License for the specific language governing permissions and limitations
|
|
14
|
+
# under the License.
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
from mergify_cli.cli import main
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
if __name__ == "__main__":
|
|
22
|
+
main()
|
mergify_cli/_globals.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright © 2021-2026 Mergify SAS
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
5
|
+
# not use this file except in compliance with the License. You may obtain
|
|
6
|
+
# a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
12
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
13
|
+
# License for the specific language governing permissions and limitations
|
|
14
|
+
# under the License.
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import importlib.metadata
|
|
19
|
+
|
|
20
|
+
import rich.console
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
console = rich.console.Console(log_path=False, log_time=False)
|
|
24
|
+
|
|
25
|
+
VERSION = importlib.metadata.version("mergify-cli")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def console_error(message: str) -> None:
|
|
29
|
+
"""Print a consistently formatted error message."""
|
|
30
|
+
console.print(f"error: {message}", style="red", markup=False)
|
|
File without changes
|
mergify_cli/ci/cli.py
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import glob
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
import pathlib
|
|
7
|
+
import shlex
|
|
8
|
+
import uuid
|
|
9
|
+
|
|
10
|
+
import click
|
|
11
|
+
|
|
12
|
+
from mergify_cli import utils
|
|
13
|
+
from mergify_cli.ci import detector
|
|
14
|
+
from mergify_cli.ci.git_refs import detector as git_refs_detector
|
|
15
|
+
from mergify_cli.ci.junit_processing import cli as junit_processing_cli
|
|
16
|
+
from mergify_cli.ci.queue import metadata as queue_metadata
|
|
17
|
+
from mergify_cli.ci.scopes import cli as scopes_cli
|
|
18
|
+
from mergify_cli.ci.scopes import exceptions as scopes_exc
|
|
19
|
+
from mergify_cli.dym import DYMGroup
|
|
20
|
+
from mergify_cli.exit_codes import ExitCode
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _expand_junit_patterns(
|
|
24
|
+
ctx: click.Context,
|
|
25
|
+
param: click.Parameter,
|
|
26
|
+
value: tuple[str, ...],
|
|
27
|
+
) -> tuple[str, ...]:
|
|
28
|
+
# Accept raw glob patterns and expand them here so callers don't have to
|
|
29
|
+
# rely on shell expansion — preferable for large test suites.
|
|
30
|
+
results: dict[str, None] = {}
|
|
31
|
+
for entry in value:
|
|
32
|
+
literal = pathlib.Path(entry)
|
|
33
|
+
# Existing literal paths take precedence so filenames that happen to
|
|
34
|
+
# contain glob metacharacters (e.g. `report[1].xml`) keep working.
|
|
35
|
+
if literal.is_file():
|
|
36
|
+
results.setdefault(entry, None)
|
|
37
|
+
continue
|
|
38
|
+
|
|
39
|
+
if glob.has_magic(entry):
|
|
40
|
+
matches = [
|
|
41
|
+
match
|
|
42
|
+
for match in glob.iglob(entry, recursive=True) # noqa: PTH207
|
|
43
|
+
if pathlib.Path(match).is_file()
|
|
44
|
+
]
|
|
45
|
+
if not matches:
|
|
46
|
+
raise click.BadParameter(
|
|
47
|
+
f"Pattern '{entry}' did not match any file.\n\n"
|
|
48
|
+
"This usually indicates that a previous CI step failed to generate the test results.\n"
|
|
49
|
+
"Please check if your test execution step completed successfully and produced the expected output files.",
|
|
50
|
+
ctx=ctx,
|
|
51
|
+
param=param,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
results.update(dict.fromkeys(matches))
|
|
55
|
+
continue
|
|
56
|
+
|
|
57
|
+
if literal.is_dir():
|
|
58
|
+
raise click.BadParameter(
|
|
59
|
+
f"'{entry}' is a directory, not a JUnit XML file.\n\n"
|
|
60
|
+
"Pass a file path or a quoted glob pattern (e.g. 'reports/**/*.xml') instead.",
|
|
61
|
+
ctx=ctx,
|
|
62
|
+
param=param,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
raise click.BadParameter(
|
|
66
|
+
f"JUnit XML file '{entry}' does not exist.\n\n"
|
|
67
|
+
"This usually indicates that a previous CI step failed to generate the test results.\n"
|
|
68
|
+
"Please check if your test execution step completed successfully and produced the expected output file.",
|
|
69
|
+
ctx=ctx,
|
|
70
|
+
param=param,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
return tuple(results)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _process_tests_target_branch(
|
|
77
|
+
_ctx: click.Context,
|
|
78
|
+
_param: click.Parameter,
|
|
79
|
+
value: str | None,
|
|
80
|
+
) -> str | None:
|
|
81
|
+
"""Process the tests_target_branch parameter to strip refs/heads/ prefix from GITHUB_REF."""
|
|
82
|
+
return value.removeprefix("refs/heads/") if value else value
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@click.group(
|
|
86
|
+
cls=DYMGroup,
|
|
87
|
+
invoke_without_command=True,
|
|
88
|
+
help="Mergify's CI related commands",
|
|
89
|
+
)
|
|
90
|
+
@click.pass_context
|
|
91
|
+
def ci(ctx: click.Context) -> None:
|
|
92
|
+
if ctx.invoked_subcommand is None:
|
|
93
|
+
click.echo(ctx.get_help())
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@ci.command(help="Upload JUnit XML reports", deprecated="Use `junit-process` instead")
|
|
97
|
+
@click.option(
|
|
98
|
+
"--api-url",
|
|
99
|
+
"-u",
|
|
100
|
+
help="URL of the Mergify API",
|
|
101
|
+
required=True,
|
|
102
|
+
envvar="MERGIFY_API_URL",
|
|
103
|
+
default=utils.MERGIFY_API_DEFAULT_URL,
|
|
104
|
+
show_default=True,
|
|
105
|
+
)
|
|
106
|
+
@click.option(
|
|
107
|
+
"--token",
|
|
108
|
+
"-t",
|
|
109
|
+
help="CI Issues Application Key",
|
|
110
|
+
required=True,
|
|
111
|
+
envvar="MERGIFY_TOKEN",
|
|
112
|
+
)
|
|
113
|
+
@click.option(
|
|
114
|
+
"--repository",
|
|
115
|
+
"-r",
|
|
116
|
+
help="Repository full name (owner/repo)",
|
|
117
|
+
required=True,
|
|
118
|
+
default=detector.get_github_repository,
|
|
119
|
+
)
|
|
120
|
+
@click.option(
|
|
121
|
+
"--test-framework",
|
|
122
|
+
help="Test framework",
|
|
123
|
+
)
|
|
124
|
+
@click.option(
|
|
125
|
+
"--test-language",
|
|
126
|
+
help="Test language",
|
|
127
|
+
)
|
|
128
|
+
@click.option(
|
|
129
|
+
"--tests-target-branch",
|
|
130
|
+
"-ttb",
|
|
131
|
+
help="The branch used to check if failing tests can be ignored with Mergify's Quarantine.",
|
|
132
|
+
required=True,
|
|
133
|
+
default=detector.get_tests_target_branch,
|
|
134
|
+
callback=_process_tests_target_branch,
|
|
135
|
+
)
|
|
136
|
+
@click.option(
|
|
137
|
+
"--test-exit-code",
|
|
138
|
+
"-e",
|
|
139
|
+
help="Exit code of the test runner process. Used to detect silent failures where the runner crashed but the JUnit report appears clean.",
|
|
140
|
+
type=int,
|
|
141
|
+
required=False,
|
|
142
|
+
default=None,
|
|
143
|
+
envvar="MERGIFY_TEST_EXIT_CODE",
|
|
144
|
+
)
|
|
145
|
+
@click.argument(
|
|
146
|
+
"files",
|
|
147
|
+
nargs=-1,
|
|
148
|
+
required=True,
|
|
149
|
+
callback=_expand_junit_patterns,
|
|
150
|
+
)
|
|
151
|
+
@utils.run_with_asyncio
|
|
152
|
+
async def junit_upload(
|
|
153
|
+
*,
|
|
154
|
+
api_url: str,
|
|
155
|
+
token: str,
|
|
156
|
+
repository: str,
|
|
157
|
+
test_framework: str | None,
|
|
158
|
+
test_language: str | None,
|
|
159
|
+
tests_target_branch: str,
|
|
160
|
+
test_exit_code: int | None,
|
|
161
|
+
files: tuple[str, ...],
|
|
162
|
+
) -> None:
|
|
163
|
+
await junit_processing_cli.process_junit_files(
|
|
164
|
+
api_url=api_url,
|
|
165
|
+
token=token,
|
|
166
|
+
repository=repository,
|
|
167
|
+
test_framework=test_framework,
|
|
168
|
+
test_language=test_language,
|
|
169
|
+
tests_target_branch=tests_target_branch,
|
|
170
|
+
files=files,
|
|
171
|
+
test_exit_code=test_exit_code,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
@ci.command(
|
|
176
|
+
help=(
|
|
177
|
+
"Upload JUnit XML reports and ignore failed tests with Mergify's CI"
|
|
178
|
+
" Insights Quarantine.\n\nFILES can be literal paths or quoted glob"
|
|
179
|
+
" patterns (e.g. 'reports/**/*.xml'); quoting lets Mergify expand the"
|
|
180
|
+
" pattern rather than the shell, which is recommended for large test"
|
|
181
|
+
" suites."
|
|
182
|
+
),
|
|
183
|
+
short_help=(
|
|
184
|
+
"Upload JUnit XML reports and ignore failed tests with Mergify's CI"
|
|
185
|
+
" Insights Quarantine"
|
|
186
|
+
),
|
|
187
|
+
)
|
|
188
|
+
@click.option(
|
|
189
|
+
"--api-url",
|
|
190
|
+
"-u",
|
|
191
|
+
help="URL of the Mergify API",
|
|
192
|
+
required=True,
|
|
193
|
+
envvar="MERGIFY_API_URL",
|
|
194
|
+
default=utils.MERGIFY_API_DEFAULT_URL,
|
|
195
|
+
show_default=True,
|
|
196
|
+
)
|
|
197
|
+
@click.option(
|
|
198
|
+
"--token",
|
|
199
|
+
"-t",
|
|
200
|
+
help="CI Issues Application Key",
|
|
201
|
+
required=True,
|
|
202
|
+
envvar="MERGIFY_TOKEN",
|
|
203
|
+
)
|
|
204
|
+
@click.option(
|
|
205
|
+
"--repository",
|
|
206
|
+
"-r",
|
|
207
|
+
help="Repository full name (owner/repo)",
|
|
208
|
+
required=True,
|
|
209
|
+
default=detector.get_github_repository,
|
|
210
|
+
)
|
|
211
|
+
@click.option(
|
|
212
|
+
"--test-framework",
|
|
213
|
+
help="Test framework",
|
|
214
|
+
)
|
|
215
|
+
@click.option(
|
|
216
|
+
"--test-language",
|
|
217
|
+
help="Test language",
|
|
218
|
+
)
|
|
219
|
+
@click.option(
|
|
220
|
+
"--tests-target-branch",
|
|
221
|
+
"-ttb",
|
|
222
|
+
help="The branch used to check if failing tests can be ignored with Mergify's Quarantine.",
|
|
223
|
+
required=True,
|
|
224
|
+
default=detector.get_tests_target_branch,
|
|
225
|
+
callback=_process_tests_target_branch,
|
|
226
|
+
)
|
|
227
|
+
@click.option(
|
|
228
|
+
"--test-exit-code",
|
|
229
|
+
"-e",
|
|
230
|
+
help="Exit code of the test runner process. Used to detect silent failures where the runner crashed but the JUnit report appears clean.",
|
|
231
|
+
type=int,
|
|
232
|
+
required=False,
|
|
233
|
+
default=None,
|
|
234
|
+
envvar="MERGIFY_TEST_EXIT_CODE",
|
|
235
|
+
)
|
|
236
|
+
@click.argument(
|
|
237
|
+
"files",
|
|
238
|
+
nargs=-1,
|
|
239
|
+
required=True,
|
|
240
|
+
callback=_expand_junit_patterns,
|
|
241
|
+
)
|
|
242
|
+
@utils.run_with_asyncio
|
|
243
|
+
async def junit_process(
|
|
244
|
+
*,
|
|
245
|
+
api_url: str,
|
|
246
|
+
token: str,
|
|
247
|
+
repository: str,
|
|
248
|
+
test_framework: str | None,
|
|
249
|
+
test_language: str | None,
|
|
250
|
+
tests_target_branch: str,
|
|
251
|
+
test_exit_code: int | None,
|
|
252
|
+
files: tuple[str, ...],
|
|
253
|
+
) -> None:
|
|
254
|
+
await junit_processing_cli.process_junit_files(
|
|
255
|
+
api_url=api_url,
|
|
256
|
+
token=token,
|
|
257
|
+
repository=repository,
|
|
258
|
+
test_framework=test_framework,
|
|
259
|
+
test_language=test_language,
|
|
260
|
+
tests_target_branch=tests_target_branch,
|
|
261
|
+
files=files,
|
|
262
|
+
test_exit_code=test_exit_code,
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
@ci.command(
|
|
267
|
+
help="""Give the base/head git references of the pull request""",
|
|
268
|
+
short_help="""Give the base/head git references of the pull request""",
|
|
269
|
+
)
|
|
270
|
+
@click.option(
|
|
271
|
+
"--format",
|
|
272
|
+
"output_format",
|
|
273
|
+
type=click.Choice(["text", "shell", "json"]),
|
|
274
|
+
default="text",
|
|
275
|
+
show_default=True,
|
|
276
|
+
help=(
|
|
277
|
+
"Output format. 'text' is human-readable. "
|
|
278
|
+
"'shell' emits MERGIFY_GIT_REFS_{BASE,HEAD,SOURCE}=... lines for `eval`. "
|
|
279
|
+
"'json' emits a single-line JSON object."
|
|
280
|
+
),
|
|
281
|
+
)
|
|
282
|
+
def git_refs(output_format: str) -> None:
|
|
283
|
+
ref = git_refs_detector.detect()
|
|
284
|
+
|
|
285
|
+
if output_format == "shell":
|
|
286
|
+
click.echo(f"MERGIFY_GIT_REFS_BASE={shlex.quote(ref.base or '')}")
|
|
287
|
+
click.echo(f"MERGIFY_GIT_REFS_HEAD={shlex.quote(ref.head)}")
|
|
288
|
+
click.echo(f"MERGIFY_GIT_REFS_SOURCE={shlex.quote(ref.source)}")
|
|
289
|
+
elif output_format == "json":
|
|
290
|
+
click.echo(
|
|
291
|
+
json.dumps({"base": ref.base, "head": ref.head, "source": ref.source}),
|
|
292
|
+
)
|
|
293
|
+
else:
|
|
294
|
+
click.echo(f"Base: {ref.base}")
|
|
295
|
+
click.echo(f"Head: {ref.head}")
|
|
296
|
+
|
|
297
|
+
ref.maybe_write_to_github_outputs()
|
|
298
|
+
ref.maybe_write_to_buildkite_metadata()
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
@ci.command(
|
|
302
|
+
help="""Give the list scope impacted by changed files""",
|
|
303
|
+
short_help="""Give the list scope impacted by changed files""",
|
|
304
|
+
)
|
|
305
|
+
@click.option(
|
|
306
|
+
"--config",
|
|
307
|
+
"config_path",
|
|
308
|
+
type=click.Path(dir_okay=False),
|
|
309
|
+
envvar="MERGIFY_CONFIG_PATH",
|
|
310
|
+
default=detector.get_mergify_config_path,
|
|
311
|
+
help="Path to YAML config file.",
|
|
312
|
+
)
|
|
313
|
+
@click.option(
|
|
314
|
+
"--base",
|
|
315
|
+
help="The base git reference to use to look for changed files",
|
|
316
|
+
)
|
|
317
|
+
@click.option(
|
|
318
|
+
"--head",
|
|
319
|
+
help="The head git reference to use to look for changed files",
|
|
320
|
+
)
|
|
321
|
+
@click.option(
|
|
322
|
+
"--write",
|
|
323
|
+
"-w",
|
|
324
|
+
type=click.Path(),
|
|
325
|
+
help="Write the detected scopes to a file (json).",
|
|
326
|
+
)
|
|
327
|
+
def scopes(
|
|
328
|
+
config_path: str | None,
|
|
329
|
+
write: str | None = None,
|
|
330
|
+
head: str | None = None,
|
|
331
|
+
base: str | None = None,
|
|
332
|
+
) -> None:
|
|
333
|
+
# Empty envvar (MERGIFY_CONFIG_PATH="") should fall back to autodetect
|
|
334
|
+
if config_path is not None and not config_path:
|
|
335
|
+
config_path = detector.get_mergify_config_path()
|
|
336
|
+
|
|
337
|
+
if config_path is None:
|
|
338
|
+
locations = ", ".join(detector.MERGIFY_CONFIG_PATHS)
|
|
339
|
+
msg = f"Mergify configuration file not found. Looked in: {locations}"
|
|
340
|
+
raise utils.MergifyError(msg, exit_code=ExitCode.CONFIGURATION_ERROR)
|
|
341
|
+
|
|
342
|
+
if not pathlib.Path(config_path).is_file():
|
|
343
|
+
msg = f"Config file '{config_path}' does not exist."
|
|
344
|
+
raise utils.MergifyError(msg, exit_code=ExitCode.CONFIGURATION_ERROR)
|
|
345
|
+
|
|
346
|
+
if base or head:
|
|
347
|
+
ref = git_refs_detector.References(
|
|
348
|
+
base=base,
|
|
349
|
+
head=head or "HEAD",
|
|
350
|
+
source="manual",
|
|
351
|
+
)
|
|
352
|
+
else:
|
|
353
|
+
ref = git_refs_detector.detect()
|
|
354
|
+
|
|
355
|
+
try:
|
|
356
|
+
scopes = scopes_cli.detect(
|
|
357
|
+
config_path=config_path,
|
|
358
|
+
references=ref,
|
|
359
|
+
)
|
|
360
|
+
except scopes_exc.ScopesError as e:
|
|
361
|
+
raise utils.MergifyError(
|
|
362
|
+
str(e),
|
|
363
|
+
exit_code=ExitCode.CONFIGURATION_ERROR,
|
|
364
|
+
) from e
|
|
365
|
+
|
|
366
|
+
if write is not None:
|
|
367
|
+
scopes.save_to_file(write)
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
@ci.command(
|
|
371
|
+
help="""Output merge queue batch metadata from the current pull request event""",
|
|
372
|
+
short_help="""Output merge queue batch metadata""",
|
|
373
|
+
)
|
|
374
|
+
def queue_info() -> None:
|
|
375
|
+
metadata = queue_metadata.detect()
|
|
376
|
+
if metadata is None:
|
|
377
|
+
raise utils.MergifyError(
|
|
378
|
+
"Not running in a merge queue context. "
|
|
379
|
+
"This command must be run on a merge queue draft pull request.",
|
|
380
|
+
exit_code=ExitCode.INVALID_STATE,
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
click.echo(json.dumps(metadata, indent=2))
|
|
384
|
+
|
|
385
|
+
gha = os.environ.get("GITHUB_OUTPUT")
|
|
386
|
+
if gha:
|
|
387
|
+
delimiter = f"ghadelimiter_{uuid.uuid4()}"
|
|
388
|
+
with pathlib.Path(gha).open("a", encoding="utf-8") as fh:
|
|
389
|
+
fh.write(
|
|
390
|
+
f"queue_metadata<<{delimiter}\n{json.dumps(metadata)}\n{delimiter}\n",
|
|
391
|
+
)
|