github2gerrit 1.3.2__tar.gz → 1.3.3__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.
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/PKG-INFO +1 -1
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_dependency_supersession.py +68 -41
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_gitutils_helpers.py +73 -27
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/.editorconfig +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/.gitignore +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/.gitlint +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/.markdownlint.yaml +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/.pre-commit-config.yaml +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/.readthedocs.yml +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/.yamllint +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/LICENSE +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/LICENSES/Apache-2.0.txt +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/README.md +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/REUSE.toml +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/SECURITY.md +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/action.yaml +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/docs/COMMIT_RULES.md +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/docs/COMPOSITE_ACTION_TESTING.md +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/docs/PR_UPDATE_IMPLEMENTATION.md +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/docs/RELEASE-v0.2.0.md +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/docs/github2gerrit_token_permissions_classic.png +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/pyproject.toml +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/sitecustomize.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/__init__.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/cli.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/commit_normalization.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/commit_rules.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/config.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/constants.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/core.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/duplicate_detection.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/error_codes.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/external_api.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/gerrit_pr_closer.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/gerrit_query.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/gerrit_rest.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/gerrit_ssh.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/gerrit_urls.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/github_api.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/gitreview.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/gitutils.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/mapping_comment.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/models.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/netrc.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/orchestrator/__init__.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/orchestrator/reconciliation.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/pr_commands.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/pr_content_filter.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/reconcile_matcher.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/rich_display.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/rich_logging.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/similarity.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/ssh_agent_setup.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/ssh_common.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/ssh_config_parser.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/ssh_discovery.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/trailers.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/utils.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/conftest.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/fixtures/__init__.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/fixtures/make_repo.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/fixtures/ssh_config_samples.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_action_environment_mapping.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_action_outputs.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_action_pr_number_handling.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_action_step_validation.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_automation_only.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_change_id_deduplication.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_clean_squash_title.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_cli.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_cli_helpers.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_cli_netrc_options.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_cli_outputs_file.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_cli_url_and_dryrun.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_commit_normalization.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_commit_rules.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_composite_action_coverage.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_config_and_reviewers.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_config_helpers.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_core_close_pr_policy.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_core_config_and_errors.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_core_gerrit_backref_comment.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_core_gerrit_push_errors.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_core_gerrit_rest_results.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_core_integration_fixture_repo.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_core_prepare_commits.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_core_shallow_clone.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_core_ssh_setup.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_core_ssrf_protection.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_dns_validation_and_no_gerrit.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_duplicate_detection.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_email_case_normalization.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_error_codes.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_external_api_framework.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_force_flag_cli.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_gerrit_change_id_footer.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_gerrit_change_status_checks.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_gerrit_pr_closer.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_gerrit_rest_client.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_gerrit_ssh_abandon.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_gerrit_urls.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_gerrit_urls_more.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_ghe_and_gitreview_args.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_github_api_error_handling.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_github_api_helpers.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_github_api_retry_and_helpers.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_gitreview.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_issue_157_regressions.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_mapping_comment_additional.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_mapping_comment_digest_and_backref.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_metadata_and_reconciliation.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_metadata_trailer_separation_bug.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_misc_small_coverage.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_netrc.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_orphan_rest_side_effects.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_pr_commands.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_pr_content_filter.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_pr_content_filter_integration.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_pr_update_detection.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_reconciliation_extracted_module.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_reconciliation_plan_and_orphans.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_reconciliation_scenarios.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_ssh_agent.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_ssh_agent_ownership.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_ssh_artifact_prevention.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_ssh_common.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_ssh_discovery.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_ssh_discovery_dry_run.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_trailers_additional.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_url_parser.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_utils.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/unit/test_config_integration.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/unit/test_ssh_config_parser.py +0 -0
- {github2gerrit-1.3.2 → github2gerrit-1.3.3}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: github2gerrit
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.3
|
|
4
4
|
Summary: Submit a GitHub pull request to a Gerrit repository.
|
|
5
5
|
Project-URL: Homepage, https://github.com/lfreleng-actions/github2gerrit-action
|
|
6
6
|
Project-URL: Repository, https://github.com/lfreleng-actions/github2gerrit-action
|
|
@@ -17,6 +17,7 @@ Covers two mechanisms:
|
|
|
17
17
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
|
+
import hashlib
|
|
20
21
|
from dataclasses import dataclass
|
|
21
22
|
from typing import Any
|
|
22
23
|
from unittest.mock import MagicMock
|
|
@@ -31,6 +32,7 @@ from github2gerrit.gerrit_query import query_open_changes_by_project
|
|
|
31
32
|
from github2gerrit.gitreview import GerritInfo
|
|
32
33
|
from github2gerrit.models import GitHubContext
|
|
33
34
|
from github2gerrit.similarity import extract_dependency_package_from_subject
|
|
35
|
+
from github2gerrit.utils import reset_warning_once
|
|
34
36
|
|
|
35
37
|
|
|
36
38
|
# -------------------------------------------------------------------
|
|
@@ -38,6 +40,46 @@ from github2gerrit.similarity import extract_dependency_package_from_subject
|
|
|
38
40
|
# -------------------------------------------------------------------
|
|
39
41
|
|
|
40
42
|
|
|
43
|
+
# Dependency fixture values reused across the supersession tests.
|
|
44
|
+
# Centralising them documents which data is significant to the logic under
|
|
45
|
+
# test (the *package name* must match for a change to be superseded) versus
|
|
46
|
+
# which is arbitrary (the exact version strings).
|
|
47
|
+
_DEP_PACKAGE = "requests"
|
|
48
|
+
_DEP_VERSION_OLD = "2.31.0"
|
|
49
|
+
_DEP_VERSION_NEW = "2.32.0"
|
|
50
|
+
_DEP_VERSION_INTERMEDIATE = "2.31.5"
|
|
51
|
+
_DEP_BUMP_TITLE = (
|
|
52
|
+
f"Bump {_DEP_PACKAGE} from {_DEP_VERSION_OLD} to {_DEP_VERSION_NEW}"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@pytest.fixture(autouse=True)
|
|
57
|
+
def _reset_warning_once_state() -> None:
|
|
58
|
+
"""Reset the one-time warning cache before each test.
|
|
59
|
+
|
|
60
|
+
Several tests assert warn-once behaviour (for example the truncation
|
|
61
|
+
warning emitted by the anonymous fallback), which relies on process-wide
|
|
62
|
+
global state. Resetting it automatically keeps every test isolated so
|
|
63
|
+
individual tests no longer need to call ``reset_warning_once`` by hand.
|
|
64
|
+
"""
|
|
65
|
+
reset_warning_once()
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _make_change_id(seed: str) -> str:
|
|
69
|
+
"""Return a valid-looking Gerrit Change-Id derived from ``seed``.
|
|
70
|
+
|
|
71
|
+
A real Gerrit Change-Id is the letter ``I`` followed by 40 hexadecimal
|
|
72
|
+
characters (a SHA-1 digest). Tests previously used mnemonic but invalid
|
|
73
|
+
values such as ``Iexist00...`` that contain non-hex characters. This
|
|
74
|
+
helper instead derives a truncated SHA-256 digest from a human-readable
|
|
75
|
+
seed: the exact hash algorithm is unimportant, it only needs to match
|
|
76
|
+
the ``I`` + 40-hex-character format while keeping failures easy to
|
|
77
|
+
trace.
|
|
78
|
+
"""
|
|
79
|
+
digest = hashlib.sha256(seed.encode("utf-8")).hexdigest()[:40]
|
|
80
|
+
return f"I{digest}"
|
|
81
|
+
|
|
82
|
+
|
|
41
83
|
def _gerrit_change(
|
|
42
84
|
*,
|
|
43
85
|
change_id: str = "Iaaaa000000000000000000000000000000000000",
|
|
@@ -202,10 +244,6 @@ class TestQueryOpenChangesByProject:
|
|
|
202
244
|
to drive the anonymous fallback, the helper must short-circuit and
|
|
203
245
|
never issue the request, returning an empty list.
|
|
204
246
|
"""
|
|
205
|
-
from github2gerrit.utils import reset_warning_once
|
|
206
|
-
|
|
207
|
-
reset_warning_once()
|
|
208
|
-
|
|
209
247
|
fake_client = MagicMock()
|
|
210
248
|
fake_client.is_authenticated = False
|
|
211
249
|
|
|
@@ -232,10 +270,6 @@ class TestQueryOpenChangesByProject:
|
|
|
232
270
|
The query must NOT use owner:self, and only changes whose
|
|
233
271
|
GitHub-PR trailer targets the current repository are returned.
|
|
234
272
|
"""
|
|
235
|
-
from github2gerrit.utils import reset_warning_once
|
|
236
|
-
|
|
237
|
-
reset_warning_once()
|
|
238
|
-
|
|
239
273
|
ours = _raw_change(
|
|
240
274
|
100,
|
|
241
275
|
"chore: bump requests from 2.31.0 to 2.32.0",
|
|
@@ -262,10 +296,6 @@ class TestQueryOpenChangesByProject:
|
|
|
262
296
|
|
|
263
297
|
def test_anonymous_fallback_repo_match_is_case_insensitive(self) -> None:
|
|
264
298
|
"""Repo trailer matching ignores case differences."""
|
|
265
|
-
from github2gerrit.utils import reset_warning_once
|
|
266
|
-
|
|
267
|
-
reset_warning_once()
|
|
268
|
-
|
|
269
299
|
ours = _raw_change(
|
|
270
300
|
200,
|
|
271
301
|
"chore: bump requests from 2.31.0 to 2.32.0",
|
|
@@ -283,10 +313,6 @@ class TestQueryOpenChangesByProject:
|
|
|
283
313
|
|
|
284
314
|
def test_anonymous_fallback_matches_ghes_host(self) -> None:
|
|
285
315
|
"""The host is ignored, so GitHub Enterprise URLs still match."""
|
|
286
|
-
from github2gerrit.utils import reset_warning_once
|
|
287
|
-
|
|
288
|
-
reset_warning_once()
|
|
289
|
-
|
|
290
316
|
ours = _raw_change(
|
|
291
317
|
210,
|
|
292
318
|
"chore: bump requests from 2.31.0 to 2.32.0",
|
|
@@ -310,10 +336,6 @@ class TestQueryOpenChangesByProject:
|
|
|
310
336
|
repo in its query string, a non-URL value, and a relative path
|
|
311
337
|
(e.g. ``/org/repo/pull/1``) are all correctly excluded.
|
|
312
338
|
"""
|
|
313
|
-
from github2gerrit.utils import reset_warning_once
|
|
314
|
-
|
|
315
|
-
reset_warning_once()
|
|
316
|
-
|
|
317
339
|
other = _raw_change(
|
|
318
340
|
220,
|
|
319
341
|
"chore: bump requests from 2.31.0 to 2.32.0",
|
|
@@ -346,10 +368,6 @@ class TestQueryOpenChangesByProject:
|
|
|
346
368
|
GitHub2Gerrit changes (which carry the GitHub-PR trailer) so busy
|
|
347
369
|
projects do not truncate before the relevant changes are seen.
|
|
348
370
|
"""
|
|
349
|
-
from github2gerrit.utils import reset_warning_once
|
|
350
|
-
|
|
351
|
-
reset_warning_once()
|
|
352
|
-
|
|
353
371
|
fake_client = MagicMock()
|
|
354
372
|
fake_client.is_authenticated = False
|
|
355
373
|
fake_client.get.return_value = []
|
|
@@ -369,10 +387,6 @@ class TestQueryOpenChangesByProject:
|
|
|
369
387
|
"""Hitting the result cap emits a one-time truncation warning."""
|
|
370
388
|
import logging
|
|
371
389
|
|
|
372
|
-
from github2gerrit.utils import reset_warning_once
|
|
373
|
-
|
|
374
|
-
reset_warning_once()
|
|
375
|
-
|
|
376
390
|
c1 = _raw_change(
|
|
377
391
|
300,
|
|
378
392
|
"chore: bump x from 1 to 2",
|
|
@@ -406,9 +420,6 @@ class TestQueryOpenChangesByProject:
|
|
|
406
420
|
self, monkeypatch: pytest.MonkeyPatch
|
|
407
421
|
) -> None:
|
|
408
422
|
"""Disabling the fallback flag skips even when repo is known."""
|
|
409
|
-
from github2gerrit.utils import reset_warning_once
|
|
410
|
-
|
|
411
|
-
reset_warning_once()
|
|
412
423
|
monkeypatch.setenv("G2G_ANON_SUPERSEDE_FALLBACK", "false")
|
|
413
424
|
|
|
414
425
|
fake_client = MagicMock()
|
|
@@ -422,10 +433,6 @@ class TestQueryOpenChangesByProject:
|
|
|
422
433
|
|
|
423
434
|
def test_anonymous_fallback_whitespace_repo_skips(self) -> None:
|
|
424
435
|
"""A blank/whitespace-only repository must not trigger a query."""
|
|
425
|
-
from github2gerrit.utils import reset_warning_once
|
|
426
|
-
|
|
427
|
-
reset_warning_once()
|
|
428
|
-
|
|
429
436
|
fake_client = MagicMock()
|
|
430
437
|
fake_client.is_authenticated = False
|
|
431
438
|
|
|
@@ -446,7 +453,16 @@ class TestQueryOpenChangesByProject:
|
|
|
446
453
|
new=lambda *_a, **_kw: "",
|
|
447
454
|
)
|
|
448
455
|
class TestAbandonSupersededDependencyChanges:
|
|
449
|
-
"""Tests for the post-push abandon sweep.
|
|
456
|
+
"""Tests for the post-push abandon sweep.
|
|
457
|
+
|
|
458
|
+
The class-level ``@patch`` stubs
|
|
459
|
+
``gerrit_urls._discover_base_path_for_host`` to return an empty base
|
|
460
|
+
path for *every* test method below, so URL construction does not attempt
|
|
461
|
+
host discovery (a network call). The patch is intentionally applied at
|
|
462
|
+
the class level because all methods exercise URL building; it is not
|
|
463
|
+
injected as a method argument because the stubbed value is never
|
|
464
|
+
inspected by the tests.
|
|
465
|
+
"""
|
|
450
466
|
|
|
451
467
|
@patch("github2gerrit.gerrit_rest.build_client_for_host")
|
|
452
468
|
@patch("github2gerrit.gerrit_query.query_open_changes_by_project")
|
|
@@ -789,7 +805,7 @@ class TestStrategy5Integration:
|
|
|
789
805
|
# Set up GitHub mocks — strategies 1-4 should all fail
|
|
790
806
|
mock_get_pull.return_value = _FakePullRequest(
|
|
791
807
|
number=42,
|
|
792
|
-
title=
|
|
808
|
+
title=_DEP_BUMP_TITLE,
|
|
793
809
|
user=_FakeGitHubUser(),
|
|
794
810
|
)
|
|
795
811
|
mock_get_repo.return_value = MagicMock()
|
|
@@ -803,10 +819,14 @@ class TestStrategy5Integration:
|
|
|
803
819
|
mock_gerrit_client.return_value = fake_gerrit
|
|
804
820
|
|
|
805
821
|
# Strategy 5 — return an open change bumping the same package
|
|
822
|
+
existing_change_id = _make_change_id("strategy5-existing")
|
|
806
823
|
existing_change = _gerrit_change(
|
|
807
|
-
change_id=
|
|
824
|
+
change_id=existing_change_id,
|
|
808
825
|
number="999",
|
|
809
|
-
subject=
|
|
826
|
+
subject=(
|
|
827
|
+
f"chore: bump {_DEP_PACKAGE} from "
|
|
828
|
+
f"{_DEP_VERSION_OLD} to {_DEP_VERSION_INTERMEDIATE}"
|
|
829
|
+
),
|
|
810
830
|
)
|
|
811
831
|
mock_query_open.return_value = [existing_change]
|
|
812
832
|
|
|
@@ -832,7 +852,7 @@ class TestStrategy5Integration:
|
|
|
832
852
|
)
|
|
833
853
|
|
|
834
854
|
result = orch._find_existing_change_for_pr(gh, gerrit)
|
|
835
|
-
assert result == [
|
|
855
|
+
assert result == [existing_change_id]
|
|
836
856
|
|
|
837
857
|
@patch("github2gerrit.core.build_client")
|
|
838
858
|
@patch("github2gerrit.core.get_repo_from_env")
|
|
@@ -956,7 +976,14 @@ class TestStrategy5Integration:
|
|
|
956
976
|
new=lambda *_a, **_kw: "",
|
|
957
977
|
)
|
|
958
978
|
class TestRealWorldScenarios:
|
|
959
|
-
"""Scenarios taken directly from the issue report.
|
|
979
|
+
"""Scenarios taken directly from the issue report.
|
|
980
|
+
|
|
981
|
+
As with :class:`TestAbandonSupersededDependencyChanges`, the class-level
|
|
982
|
+
``@patch`` stubs ``gerrit_urls._discover_base_path_for_host`` for every
|
|
983
|
+
method so URL construction avoids host discovery. The stub uses ``new=``
|
|
984
|
+
rather than a mock argument because its return value is fixed and never
|
|
985
|
+
asserted on.
|
|
986
|
+
"""
|
|
960
987
|
|
|
961
988
|
@patch("github2gerrit.gerrit_rest.build_client_for_host")
|
|
962
989
|
@patch("github2gerrit.gerrit_query.query_open_changes_by_project")
|
|
@@ -16,19 +16,40 @@ from github2gerrit.gitutils import run_cmd
|
|
|
16
16
|
from github2gerrit.gitutils import run_cmd_with_retries
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
# Environment variables that pytest, pytest-cov, and pytest-xdist inject so
|
|
20
|
+
# that coverage measurement and test metadata propagate into subprocesses.
|
|
21
|
+
# When a test spawns the current Python interpreter via ``run_cmd`` we clear
|
|
22
|
+
# these so the child does not start its own coverage run (which can emit
|
|
23
|
+
# warnings or write stray data files) and so its output stays deterministic
|
|
24
|
+
# regardless of how the outer pytest session was invoked.
|
|
25
|
+
#
|
|
26
|
+
# COV_CORE_SOURCE/CONFIG/DATAFILE pytest-cov subprocess coverage hooks
|
|
27
|
+
# COVERAGE_PROCESS_START triggers coverage startup in children
|
|
28
|
+
# COVERAGE_FILE / COVERAGE_RCFILE coverage data / config file locations
|
|
29
|
+
# PYTEST_ADDOPTS extra pytest args inherited by children
|
|
30
|
+
# PYTEST_CURRENT_TEST current test id (set per test by pytest)
|
|
31
|
+
# PYTEST_XDIST_WORKER xdist worker id when running in parallel
|
|
32
|
+
_COVERAGE_ENV_KEYS = (
|
|
33
|
+
"COV_CORE_SOURCE",
|
|
34
|
+
"COV_CORE_CONFIG",
|
|
35
|
+
"COV_CORE_DATAFILE",
|
|
36
|
+
"COVERAGE_PROCESS_START",
|
|
37
|
+
"COVERAGE_FILE",
|
|
38
|
+
"COVERAGE_RCFILE",
|
|
39
|
+
"PYTEST_ADDOPTS",
|
|
40
|
+
"PYTEST_CURRENT_TEST",
|
|
41
|
+
"PYTEST_XDIST_WORKER",
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
19
45
|
def _no_cov_env() -> dict[str, str]:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"PYTEST_ADDOPTS",
|
|
28
|
-
"PYTEST_CURRENT_TEST",
|
|
29
|
-
"PYTEST_XDIST_WORKER",
|
|
30
|
-
]
|
|
31
|
-
return dict.fromkeys(keys, "")
|
|
46
|
+
"""Return an env mapping that disables coverage in subprocesses.
|
|
47
|
+
|
|
48
|
+
Every key in :data:`_COVERAGE_ENV_KEYS` is mapped to an empty string so
|
|
49
|
+
a spawned child process inherits a clean, coverage-free environment. See
|
|
50
|
+
that constant for the rationale behind each cleared variable.
|
|
51
|
+
"""
|
|
52
|
+
return dict.fromkeys(_COVERAGE_ENV_KEYS, "")
|
|
32
53
|
|
|
33
54
|
|
|
34
55
|
def test_mask_text_replaces_tokens_and_ignores_empty() -> None:
|
|
@@ -93,24 +114,31 @@ def test_run_cmd_with_retries_retries_on_transient_error_then_succeeds(
|
|
|
93
114
|
|
|
94
115
|
monkeypatch.setattr("time.sleep", _fake_sleep)
|
|
95
116
|
|
|
96
|
-
#
|
|
97
|
-
# error
|
|
98
|
-
#
|
|
117
|
+
# The helper script creates a marker file and fails with a transient
|
|
118
|
+
# error on its first run, then succeeds once the marker exists. Writing
|
|
119
|
+
# the behaviour to a real script file (taking the marker path as an
|
|
120
|
+
# argument) keeps the test readable and avoids embedding Python source
|
|
121
|
+
# inside an f-string.
|
|
99
122
|
marker = tmp_path / "attempted"
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
import
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
""
|
|
123
|
+
script = tmp_path / "transient_then_succeed.py"
|
|
124
|
+
script.write_text(
|
|
125
|
+
"import pathlib\n"
|
|
126
|
+
"import sys\n"
|
|
127
|
+
"\n"
|
|
128
|
+
"marker = pathlib.Path(sys.argv[1])\n"
|
|
129
|
+
"if not marker.exists():\n"
|
|
130
|
+
' marker.write_text("1", encoding="utf-8")\n'
|
|
131
|
+
' print("could not resolve host: example.com", file=sys.stderr)\n'
|
|
132
|
+
" sys.exit(128)\n"
|
|
133
|
+
"else:\n"
|
|
134
|
+
' print("ok")\n',
|
|
135
|
+
encoding="utf-8",
|
|
136
|
+
)
|
|
111
137
|
|
|
112
138
|
res = run_cmd_with_retries(
|
|
113
|
-
[sys.executable,
|
|
139
|
+
[sys.executable, str(script), str(marker)],
|
|
140
|
+
cwd=tmp_path,
|
|
141
|
+
env=_no_cov_env(),
|
|
114
142
|
)
|
|
115
143
|
# Should succeed after retry, marker must exist, and we should have slept at
|
|
116
144
|
# least once
|
|
@@ -264,6 +292,24 @@ def test_git_last_commit_trailers_parsing_edge_cases(
|
|
|
264
292
|
]
|
|
265
293
|
|
|
266
294
|
|
|
295
|
+
def test_git_last_commit_trailers_returns_empty_on_git_error(
|
|
296
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
297
|
+
) -> None:
|
|
298
|
+
"""A failing ``git show`` (e.g. fresh repo) yields an empty mapping."""
|
|
299
|
+
from github2gerrit.gitutils import GitError
|
|
300
|
+
from github2gerrit.gitutils import git_last_commit_trailers
|
|
301
|
+
|
|
302
|
+
def _raise_git_error(rev: str, **_kw: object) -> str:
|
|
303
|
+
raise GitError("git show HEAD failed")
|
|
304
|
+
|
|
305
|
+
monkeypatch.setattr("github2gerrit.gitutils.git_show", _raise_git_error)
|
|
306
|
+
|
|
307
|
+
# The implementation catches GitError and returns an empty dict, both
|
|
308
|
+
# without and with a key filter.
|
|
309
|
+
assert git_last_commit_trailers() == {}
|
|
310
|
+
assert git_last_commit_trailers(keys=["Change-Id"]) == {}
|
|
311
|
+
|
|
312
|
+
|
|
267
313
|
def test_git_quiet_suppresses_failure_logging(
|
|
268
314
|
caplog: pytest.LogCaptureFixture, monkeypatch: pytest.MonkeyPatch
|
|
269
315
|
) -> None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{github2gerrit-1.3.2 → github2gerrit-1.3.3}/docs/github2gerrit_token_permissions_classic.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{github2gerrit-1.3.2 → github2gerrit-1.3.3}/src/github2gerrit/orchestrator/reconciliation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{github2gerrit-1.3.2 → github2gerrit-1.3.3}/tests/test_mapping_comment_digest_and_backref.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|