github2gerrit 1.3.3__tar.gz → 1.4.0__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.3 → github2gerrit-1.4.0}/.pre-commit-config.yaml +5 -5
- github2gerrit-1.4.0/PKG-INFO +386 -0
- github2gerrit-1.4.0/README.md +340 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/action.yaml +2 -2
- github2gerrit-1.4.0/docs/cli.md +319 -0
- github2gerrit-1.4.0/docs/development.md +161 -0
- github2gerrit-1.4.0/docs/features.md +731 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/pyproject.toml +0 -15
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/cli.py +3 -2
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_automation_only.py +24 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/uv.lock +75 -85
- github2gerrit-1.3.3/PKG-INFO +0 -1734
- github2gerrit-1.3.3/README.md +0 -1688
- github2gerrit-1.3.3/docs/COMPOSITE_ACTION_TESTING.md +0 -219
- github2gerrit-1.3.3/docs/PR_UPDATE_IMPLEMENTATION.md +0 -542
- github2gerrit-1.3.3/docs/RELEASE-v0.2.0.md +0 -630
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/.editorconfig +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/.gitignore +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/.gitlint +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/.markdownlint.yaml +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/.readthedocs.yml +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/.yamllint +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/LICENSE +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/LICENSES/Apache-2.0.txt +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/REUSE.toml +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/SECURITY.md +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/docs/COMMIT_RULES.md +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/docs/github2gerrit_token_permissions_classic.png +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/sitecustomize.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/__init__.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/commit_normalization.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/commit_rules.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/config.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/constants.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/core.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/duplicate_detection.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/error_codes.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/external_api.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/gerrit_pr_closer.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/gerrit_query.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/gerrit_rest.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/gerrit_ssh.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/gerrit_urls.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/github_api.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/gitreview.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/gitutils.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/mapping_comment.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/models.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/netrc.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/orchestrator/__init__.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/orchestrator/reconciliation.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/pr_commands.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/pr_content_filter.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/reconcile_matcher.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/rich_display.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/rich_logging.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/similarity.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/ssh_agent_setup.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/ssh_common.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/ssh_config_parser.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/ssh_discovery.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/trailers.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/src/github2gerrit/utils.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/conftest.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/fixtures/__init__.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/fixtures/make_repo.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/fixtures/ssh_config_samples.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_action_environment_mapping.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_action_outputs.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_action_pr_number_handling.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_action_step_validation.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_change_id_deduplication.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_clean_squash_title.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_cli.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_cli_helpers.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_cli_netrc_options.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_cli_outputs_file.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_cli_url_and_dryrun.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_commit_normalization.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_commit_rules.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_composite_action_coverage.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_config_and_reviewers.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_config_helpers.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_core_close_pr_policy.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_core_config_and_errors.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_core_gerrit_backref_comment.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_core_gerrit_push_errors.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_core_gerrit_rest_results.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_core_integration_fixture_repo.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_core_prepare_commits.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_core_shallow_clone.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_core_ssh_setup.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_core_ssrf_protection.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_dependency_supersession.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_dns_validation_and_no_gerrit.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_duplicate_detection.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_email_case_normalization.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_error_codes.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_external_api_framework.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_force_flag_cli.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_gerrit_change_id_footer.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_gerrit_change_status_checks.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_gerrit_pr_closer.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_gerrit_rest_client.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_gerrit_ssh_abandon.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_gerrit_urls.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_gerrit_urls_more.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_ghe_and_gitreview_args.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_github_api_error_handling.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_github_api_helpers.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_github_api_retry_and_helpers.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_gitreview.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_gitutils_helpers.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_issue_157_regressions.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_mapping_comment_additional.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_mapping_comment_digest_and_backref.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_metadata_and_reconciliation.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_metadata_trailer_separation_bug.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_misc_small_coverage.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_netrc.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_orphan_rest_side_effects.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_pr_commands.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_pr_content_filter.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_pr_content_filter_integration.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_pr_update_detection.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_reconciliation_extracted_module.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_reconciliation_plan_and_orphans.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_reconciliation_scenarios.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_ssh_agent.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_ssh_agent_ownership.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_ssh_artifact_prevention.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_ssh_common.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_ssh_discovery.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_ssh_discovery_dry_run.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_trailers_additional.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_url_parser.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/test_utils.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/unit/test_config_integration.py +0 -0
- {github2gerrit-1.3.3 → github2gerrit-1.4.0}/tests/unit/test_ssh_config_parser.py +0 -0
|
@@ -59,7 +59,7 @@ repos:
|
|
|
59
59
|
types: [yaml]
|
|
60
60
|
|
|
61
61
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
62
|
-
rev:
|
|
62
|
+
rev: c59bba8fb259db0fec2bbb77ad8ba51ea7341b56 # frozen: v0.15.20
|
|
63
63
|
hooks:
|
|
64
64
|
- id: ruff
|
|
65
65
|
files: ^(src|scripts|tests)/.+\.py$
|
|
@@ -89,7 +89,7 @@ repos:
|
|
|
89
89
|
- id: shellcheck
|
|
90
90
|
|
|
91
91
|
- repo: https://github.com/igorshubovych/markdownlint-cli
|
|
92
|
-
rev:
|
|
92
|
+
rev: a4d5d37e66ebcd6b3705204a1d6dbb56dea66338 # frozen: v0.49.0
|
|
93
93
|
hooks:
|
|
94
94
|
- id: markdownlint
|
|
95
95
|
args: ["--fix", "--config", ".markdownlint.yaml"]
|
|
@@ -115,18 +115,18 @@ repos:
|
|
|
115
115
|
|
|
116
116
|
# Requires a mirror, primary repo lacks .pre-commit-hooks.yaml
|
|
117
117
|
- repo: https://github.com/DetachHead/basedpyright-prek-mirror
|
|
118
|
-
rev:
|
|
118
|
+
rev: d55eabd2531b4f4a4c49c30fba627ce3a636ab79 # frozen: 1.39.9
|
|
119
119
|
hooks:
|
|
120
120
|
- id: basedpyright
|
|
121
121
|
files: ^src/.+\.py$
|
|
122
122
|
|
|
123
123
|
- repo: https://github.com/lfreleng-actions/gha-workflow-linter
|
|
124
|
-
rev:
|
|
124
|
+
rev: 4c3079dcb6e9e3c295f961ce5bd5b8585db698ca # frozen: v1.2.2
|
|
125
125
|
hooks:
|
|
126
126
|
- id: gha-workflow-linter
|
|
127
127
|
|
|
128
128
|
- repo: https://github.com/python-jsonschema/check-jsonschema
|
|
129
|
-
rev:
|
|
129
|
+
rev: 1a4bb160cab6417b3045e1b37b6b72449243e658 # frozen: 0.37.4
|
|
130
130
|
hooks:
|
|
131
131
|
- id: check-github-actions
|
|
132
132
|
- id: check-github-workflows
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: github2gerrit
|
|
3
|
+
Version: 1.4.0
|
|
4
|
+
Summary: Submit a GitHub pull request to a Gerrit repository.
|
|
5
|
+
Project-URL: Homepage, https://github.com/lfreleng-actions/github2gerrit-action
|
|
6
|
+
Project-URL: Repository, https://github.com/lfreleng-actions/github2gerrit-action
|
|
7
|
+
Project-URL: Issues, https://github.com/lfreleng-actions/github2gerrit-action/issues
|
|
8
|
+
Author-email: Matthew Watkins <mwatkins@linuxfoundation.org>
|
|
9
|
+
License-Expression: Apache-2.0
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: actions,ci,cli,gerrit,github,typer
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
22
|
+
Classifier: Topic :: Software Development :: Version Control
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.11
|
|
25
|
+
Requires-Dist: click>=8.1.7
|
|
26
|
+
Requires-Dist: cryptography>=48.0.1
|
|
27
|
+
Requires-Dist: git-review>=2.5.0
|
|
28
|
+
Requires-Dist: pygerrit2>=2.0.15
|
|
29
|
+
Requires-Dist: pygithub>=2.8.1
|
|
30
|
+
Requires-Dist: pynacl>=1.6.2
|
|
31
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
32
|
+
Requires-Dist: rich>=14.2.0
|
|
33
|
+
Requires-Dist: typer>=0.20.1
|
|
34
|
+
Requires-Dist: urllib3>=2.6.3
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: coverage[toml]>=7.10.6; extra == 'dev'
|
|
37
|
+
Requires-Dist: mypy>=1.17.1; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest-mock>=3.15.1; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest>=9.0.2; extra == 'dev'
|
|
41
|
+
Requires-Dist: responses>=0.25.8; extra == 'dev'
|
|
42
|
+
Requires-Dist: ruff>=0.6.3; extra == 'dev'
|
|
43
|
+
Requires-Dist: types-requests>=2.31.0; extra == 'dev'
|
|
44
|
+
Requires-Dist: types-urllib3>=1.26.25.14; extra == 'dev'
|
|
45
|
+
Description-Content-Type: text/markdown
|
|
46
|
+
|
|
47
|
+
<!--
|
|
48
|
+
SPDX-License-Identifier: Apache-2.0
|
|
49
|
+
SPDX-FileCopyrightText: 2025 The Linux Foundation
|
|
50
|
+
-->
|
|
51
|
+
|
|
52
|
+
# github2gerrit
|
|
53
|
+
|
|
54
|
+
Mirror GitHub pull requests into Gerrit changes.
|
|
55
|
+
|
|
56
|
+
github2gerrit serves projects where Gerrit is the source of truth and
|
|
57
|
+
GitHub hosts a read-only mirror. Automation tools such as Dependabot
|
|
58
|
+
raise pull requests against the GitHub mirror; this action translates
|
|
59
|
+
those pull requests into Gerrit changes, keeping the two systems in
|
|
60
|
+
sync across the entire lifecycle: creation, updates/rebases, metadata
|
|
61
|
+
edits, closure, and cleanup.
|
|
62
|
+
|
|
63
|
+
The implementation is a Python CLI tool (`github2gerrit`, published to
|
|
64
|
+
PyPI) wrapped in a GitHub composite action, plus a reusable workflow
|
|
65
|
+
for straightforward deployment in consuming repositories.
|
|
66
|
+
|
|
67
|
+
## Goals and purpose
|
|
68
|
+
|
|
69
|
+
- Let Gerrit-based projects receive dependency updates (Dependabot)
|
|
70
|
+
and other automated changes raised against a GitHub mirror.
|
|
71
|
+
- Keep GitHub PRs and Gerrit changes synchronized in both directions:
|
|
72
|
+
PR updates become new patchsets, merged/abandoned changes close
|
|
73
|
+
their source PRs, and closed PRs abandon their Gerrit changes.
|
|
74
|
+
- Avoid duplicate Gerrit changes through Change-Id reuse and
|
|
75
|
+
reconciliation when automation rebases or re-raises PRs.
|
|
76
|
+
|
|
77
|
+
## How it works
|
|
78
|
+
|
|
79
|
+
```mermaid
|
|
80
|
+
flowchart TD
|
|
81
|
+
A[PR event on GitHub mirror] --> B[github2gerrit action]
|
|
82
|
+
B --> C{Operation mode}
|
|
83
|
+
C -->|opened| D[Create Gerrit change]
|
|
84
|
+
C -->|synchronize| E[New patchset on existing change]
|
|
85
|
+
C -->|edited| F[Sync PR metadata to Gerrit]
|
|
86
|
+
C -->|closed| G[Abandon Gerrit change]
|
|
87
|
+
D --> H[Comment Gerrit URL on PR]
|
|
88
|
+
E --> H
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
In more detail, a run:
|
|
92
|
+
|
|
93
|
+
1. Reads PR context and inputs; detects the operation mode
|
|
94
|
+
(CREATE, UPDATE, EDIT, CLOSE) from the triggering event.
|
|
95
|
+
2. Reads `.gitreview` for the Gerrit host, port, and project
|
|
96
|
+
(or uses explicit `GERRIT_SERVER` / `GERRIT_PROJECT` inputs).
|
|
97
|
+
3. Sets up git and SSH for Gerrit, derives missing credentials from
|
|
98
|
+
the organization name where possible.
|
|
99
|
+
4. Prepares commits: squashed single commit (default), one-by-one
|
|
100
|
+
cherry-picks (`SUBMIT_SINGLE_COMMITS`), or PR title/body as the
|
|
101
|
+
commit message (`USE_PR_AS_COMMIT`). Reuses existing Change-Id
|
|
102
|
+
trailers on updates so pushes create new patchsets, not new
|
|
103
|
+
changes.
|
|
104
|
+
5. Pushes to `refs/for/<branch>` with a Gerrit topic derived from the
|
|
105
|
+
project and PR number (prefix configurable via `G2G_TOPIC_PREFIX`,
|
|
106
|
+
default `GH`), queries Gerrit for the resulting URL/number/SHA, and
|
|
107
|
+
cross-links: a back-reference comment in Gerrit and the change
|
|
108
|
+
URL(s) on the PR.
|
|
109
|
+
|
|
110
|
+
See [docs/features.md](docs/features.md) for detailed feature
|
|
111
|
+
documentation: PR update handling, comment commands, duplicate
|
|
112
|
+
detection, reconciliation, cleanup, commit normalization,
|
|
113
|
+
configuration precedence, and credential derivation.
|
|
114
|
+
|
|
115
|
+
## Quick start
|
|
116
|
+
|
|
117
|
+
### Prerequisites
|
|
118
|
+
|
|
119
|
+
- A Gerrit account for the automation user, with SSH access and
|
|
120
|
+
permission to push to `refs/for/*` on the target project.
|
|
121
|
+
- The SSH private key stored as a repository or organization secret:
|
|
122
|
+
`GERRIT_SSH_PRIVKEY_G2G`.
|
|
123
|
+
- A `.gitreview` file in the repository (recommended). Without it,
|
|
124
|
+
pass `GERRIT_SERVER`, `GERRIT_SERVER_PORT`, and `GERRIT_PROJECT`
|
|
125
|
+
explicitly.
|
|
126
|
+
- Optional repository/organization variables: `GERRIT_KNOWN_HOSTS`,
|
|
127
|
+
`GERRIT_SSH_USER_G2G`, `GERRIT_SSH_USER_G2G_EMAIL`. The tool
|
|
128
|
+
derives missing values from the organization name and populates
|
|
129
|
+
known hosts automatically on first run.
|
|
130
|
+
|
|
131
|
+
### Option A: reusable workflow (recommended)
|
|
132
|
+
|
|
133
|
+
Add a thin caller workflow to the consuming repository:
|
|
134
|
+
|
|
135
|
+
```yaml
|
|
136
|
+
# .github/workflows/github2gerrit.yaml
|
|
137
|
+
name: github2gerrit
|
|
138
|
+
|
|
139
|
+
on:
|
|
140
|
+
pull_request_target:
|
|
141
|
+
types: [opened, reopened, edited, synchronize, closed]
|
|
142
|
+
push:
|
|
143
|
+
branches: [main, master]
|
|
144
|
+
workflow_dispatch:
|
|
145
|
+
inputs:
|
|
146
|
+
PR_NUMBER:
|
|
147
|
+
description: "PR number to process; 0 processes all open"
|
|
148
|
+
required: false
|
|
149
|
+
default: "0"
|
|
150
|
+
type: string
|
|
151
|
+
|
|
152
|
+
permissions: {}
|
|
153
|
+
|
|
154
|
+
jobs:
|
|
155
|
+
github2gerrit:
|
|
156
|
+
permissions:
|
|
157
|
+
contents: read
|
|
158
|
+
pull-requests: write
|
|
159
|
+
issues: write
|
|
160
|
+
# yamllint disable-line rule:line-length
|
|
161
|
+
uses: lfreleng-actions/github2gerrit-action/.github/workflows/github2gerrit.yaml@main
|
|
162
|
+
with:
|
|
163
|
+
GERRIT_KNOWN_HOSTS: ${{ vars.GERRIT_KNOWN_HOSTS }}
|
|
164
|
+
GERRIT_SSH_USER_G2G: ${{ vars.GERRIT_SSH_USER_G2G }}
|
|
165
|
+
GERRIT_SSH_USER_G2G_EMAIL: ${{ vars.GERRIT_SSH_USER_G2G_EMAIL }}
|
|
166
|
+
PR_NUMBER: ${{ inputs.PR_NUMBER || '0' }}
|
|
167
|
+
secrets:
|
|
168
|
+
GERRIT_SSH_PRIVKEY_G2G: ${{ secrets.GERRIT_SSH_PRIVKEY_G2G }}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
The `push` trigger enables closing PRs whose Gerrit changes have
|
|
172
|
+
merged; `workflow_dispatch` enables manual processing. Repositories
|
|
173
|
+
using the Gerrit-side dispatch integration should also declare
|
|
174
|
+
`GERRIT_CHANGE_URL`, `GERRIT_EVENT_TYPE`, and `GERRIT_BRANCH` as
|
|
175
|
+
dispatch inputs and forward them the same way.
|
|
176
|
+
|
|
177
|
+
Pin `@main` to a release tag or commit SHA for production use.
|
|
178
|
+
|
|
179
|
+
### Option B: composite action
|
|
180
|
+
|
|
181
|
+
Call the action directly for full control over all inputs:
|
|
182
|
+
|
|
183
|
+
```yaml
|
|
184
|
+
name: github2gerrit
|
|
185
|
+
|
|
186
|
+
on:
|
|
187
|
+
pull_request_target:
|
|
188
|
+
types: [opened, reopened, edited, synchronize, closed]
|
|
189
|
+
workflow_dispatch:
|
|
190
|
+
|
|
191
|
+
permissions:
|
|
192
|
+
contents: read
|
|
193
|
+
pull-requests: write
|
|
194
|
+
issues: write
|
|
195
|
+
|
|
196
|
+
jobs:
|
|
197
|
+
submit-to-gerrit:
|
|
198
|
+
runs-on: ubuntu-latest
|
|
199
|
+
steps:
|
|
200
|
+
- name: Submit PR to Gerrit
|
|
201
|
+
id: g2g
|
|
202
|
+
uses: lfreleng-actions/github2gerrit-action@main
|
|
203
|
+
with:
|
|
204
|
+
GERRIT_KNOWN_HOSTS: ${{ vars.GERRIT_KNOWN_HOSTS }}
|
|
205
|
+
GERRIT_SSH_PRIVKEY_G2G: ${{ secrets.GERRIT_SSH_PRIVKEY_G2G }}
|
|
206
|
+
GERRIT_SSH_USER_G2G: ${{ vars.GERRIT_SSH_USER_G2G }}
|
|
207
|
+
GERRIT_SSH_USER_G2G_EMAIL: ${{ vars.GERRIT_SSH_USER_G2G_EMAIL }}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Option C: command-line tool
|
|
211
|
+
|
|
212
|
+
The underlying Python CLI supports local and ad-hoc use (for example,
|
|
213
|
+
processing a single PR URL or bulk-processing a repository). This is
|
|
214
|
+
a secondary use case; see [docs/cli.md](docs/cli.md).
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
uvx github2gerrit https://github.com/onap/portal-ng-bff/pull/33
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Action inputs
|
|
221
|
+
|
|
222
|
+
<!-- markdownlint-disable MD013 -->
|
|
223
|
+
|
|
224
|
+
| Input | Required | Default | Description |
|
|
225
|
+
| --------------------------- | -------- | ---------------- | -------------------------------------------------------------- |
|
|
226
|
+
| `GERRIT_SSH_PRIVKEY_G2G` | Yes | — | SSH private key content used to authenticate to Gerrit |
|
|
227
|
+
| `GERRIT_KNOWN_HOSTS` | No | — | Known hosts entries for Gerrit SSH (auto-populated when empty) |
|
|
228
|
+
| `GERRIT_SSH_USER_G2G` | No | `""` | Gerrit SSH username; derived when not supplied |
|
|
229
|
+
| `GERRIT_SSH_USER_G2G_EMAIL` | No | `""` | Gerrit user email address; derived when not supplied |
|
|
230
|
+
| `GERRIT_SERVER` | No | `""` | Gerrit server hostname; `.gitreview` preferred |
|
|
231
|
+
| `GERRIT_SERVER_PORT` | No | `"29418"` | Gerrit SSH port |
|
|
232
|
+
| `GERRIT_PROJECT` | No | `""` | Gerrit project name; `.gitreview` preferred |
|
|
233
|
+
| `GERRIT_HTTP_BASE_PATH` | No | `""` | HTTP base path for Gerrit REST API (e.g. `/r`) |
|
|
234
|
+
| `GERRIT_HTTP_USER` | No | `""` | Gerrit HTTP user for REST queries |
|
|
235
|
+
| `GERRIT_HTTP_PASSWORD` | No | `""` | Gerrit HTTP password/token for REST queries |
|
|
236
|
+
| `ORGANIZATION` | No | repository owner | GitHub organization/owner used for credential derivation |
|
|
237
|
+
| `PR_NUMBER` | No | `"0"` | PR number to process; `0` processes all open PRs (dispatch) |
|
|
238
|
+
| `FETCH_DEPTH` | No | `"10"` | Fetch depth for checkout |
|
|
239
|
+
| `SUBMIT_SINGLE_COMMITS` | No | `"false"` | Submit one commit at a time to Gerrit |
|
|
240
|
+
| `USE_PR_AS_COMMIT` | No | `"false"` | Use PR title and body as the commit message |
|
|
241
|
+
| `PRESERVE_GITHUB_PRS` | No | `"true"` | Do not close GitHub PRs after pushing to Gerrit |
|
|
242
|
+
| `CLOSE_MERGED_PRS` | No | `"true"` | Close GitHub PRs when their Gerrit change merges |
|
|
243
|
+
| `CLEANUP_ABANDONED` | No | `"true"` | Close GitHub PRs for abandoned Gerrit changes |
|
|
244
|
+
| `CLEANUP_GERRIT` | No | `"true"` | Abandon Gerrit changes when their GitHub PR closes |
|
|
245
|
+
| `CREATE_MISSING` | No | `"false"` | Create a new change when UPDATE finds no existing change |
|
|
246
|
+
| `ALLOW_DUPLICATES` | No | `"true"` | Allow submitting duplicate changes without error |
|
|
247
|
+
| `DUPLICATE_TYPES` | No | `"open"` | Comma-separated Gerrit states checked for duplicates |
|
|
248
|
+
| `AUTOMATION_ONLY` | No | `"true"` | Accept PRs from known automation tools only |
|
|
249
|
+
| `NORMALISE_COMMIT` | No | `"false"` | Normalize commit messages to conventional commit format |
|
|
250
|
+
| `COMMIT_RULES_JSON` | No | `""` | JSON commit message validation rules (see docs) |
|
|
251
|
+
| `ISSUE_ID` | No | `""` | Issue ID trailer to include (e.g. `ABC-123`) |
|
|
252
|
+
| `ISSUE_ID_LOOKUP_JSON` | No | `"[]"` | JSON array mapping GitHub actors to Issue IDs |
|
|
253
|
+
| `REVIEWERS_EMAIL` | No | `""` | Comma-separated reviewer emails |
|
|
254
|
+
| `DRY_RUN` | No | `"false"` | Check settings and PR metadata; do not write to Gerrit |
|
|
255
|
+
| `FORCE` | No | `"false"` | Force PR closure regardless of Gerrit change status |
|
|
256
|
+
| `G2G_USE_SSH_AGENT` | No | `"true"` | Use SSH agent instead of file-based keys |
|
|
257
|
+
| `G2G_NO_GERRIT` | No | `"false"` | Run the pipeline without contacting Gerrit (forces dry-run) |
|
|
258
|
+
| `G2G_DISABLED` | No | `""` | Kill switch: skip all processing when `true` |
|
|
259
|
+
| `ALLOW_GHE_URLS` | No | `"false"` | Allow GitHub Enterprise URLs in direct URL mode |
|
|
260
|
+
| `VERBOSE` | No | `"false"` | Verbose output (sets log level to DEBUG) |
|
|
261
|
+
| `CI_TESTING` | No | `"false"` | CI testing mode; overrides `.gitreview` |
|
|
262
|
+
| `USE_LOCAL_ACTION` | No | `"false"` | Use local repository code instead of the PyPI package |
|
|
263
|
+
|
|
264
|
+
<!-- markdownlint-enable MD013 -->
|
|
265
|
+
|
|
266
|
+
Every input maps to an environment variable of the same name
|
|
267
|
+
(`VERBOSE` maps to `G2G_VERBOSE`), and most have matching CLI
|
|
268
|
+
flags. Reconciliation tuning (`SIMILARITY_SUBJECT`,
|
|
269
|
+
`SIMILARITY_UPDATE_FACTOR`, `SIMILARITY_FILES`, `REUSE_STRATEGY`) is
|
|
270
|
+
available through environment variables and CLI flags only; set these
|
|
271
|
+
via `env:` on the action step when needed. See
|
|
272
|
+
[docs/cli.md](docs/cli.md) for the full option reference and
|
|
273
|
+
[docs/features.md](docs/features.md) for feature-specific settings.
|
|
274
|
+
|
|
275
|
+
## Action outputs
|
|
276
|
+
|
|
277
|
+
<!-- markdownlint-disable MD013 -->
|
|
278
|
+
|
|
279
|
+
| Output | Description |
|
|
280
|
+
| --------------------------- | ------------------------------------------ |
|
|
281
|
+
| `gerrit_change_request_url` | Gerrit change URL(s), newline-separated |
|
|
282
|
+
| `gerrit_change_request_num` | Gerrit change number(s), newline-separated |
|
|
283
|
+
| `gerrit_commit_sha` | Patch set commit SHA(s), newline-separated |
|
|
284
|
+
|
|
285
|
+
<!-- markdownlint-enable MD013 -->
|
|
286
|
+
|
|
287
|
+
Access outputs in later steps with
|
|
288
|
+
`${{ steps.<step-id>.outputs.<output-name> }}`. The reusable workflow
|
|
289
|
+
re-exports all three outputs to callers.
|
|
290
|
+
|
|
291
|
+
## Reusable workflow interface
|
|
292
|
+
|
|
293
|
+
The reusable workflow (`.github/workflows/github2gerrit.yaml`) wraps
|
|
294
|
+
the composite action for `workflow_call`, supporting caller triggers
|
|
295
|
+
`pull_request_target`, `push` (close PRs for merged Gerrit changes),
|
|
296
|
+
and `workflow_dispatch` (manual runs and Gerrit-event dispatches).
|
|
297
|
+
Input defaults match the composite action defaults.
|
|
298
|
+
|
|
299
|
+
<!-- markdownlint-disable MD013 -->
|
|
300
|
+
|
|
301
|
+
| Input | Type | Default | Description |
|
|
302
|
+
| --------------------------- | ------- | ---------------- | ------------------------------------------------ |
|
|
303
|
+
| `GERRIT_KNOWN_HOSTS` | string | `""` | Known hosts entries for Gerrit SSH |
|
|
304
|
+
| `GERRIT_SSH_USER_G2G` | string | `""` | Gerrit SSH username |
|
|
305
|
+
| `GERRIT_SSH_USER_G2G_EMAIL` | string | `""` | Gerrit user email address |
|
|
306
|
+
| `GERRIT_SERVER` | string | `""` | Gerrit server hostname |
|
|
307
|
+
| `GERRIT_SERVER_PORT` | string | `"29418"` | Gerrit SSH port |
|
|
308
|
+
| `GERRIT_PROJECT` | string | `""` | Gerrit project name |
|
|
309
|
+
| `GERRIT_HTTP_BASE_PATH` | string | `""` | HTTP base path for Gerrit REST |
|
|
310
|
+
| `GERRIT_HTTP_USER` | string | `""` | Gerrit HTTP user for REST queries |
|
|
311
|
+
| `GERRIT_HTTP_PASSWORD` | string | `""` | Gerrit HTTP password/token for REST queries |
|
|
312
|
+
| `G2G_USE_SSH_AGENT` | boolean | `true` | Use SSH agent instead of file-based keys |
|
|
313
|
+
| `ORGANIZATION` | string | repository owner | GitHub organization/owner |
|
|
314
|
+
| `PR_NUMBER` | string | `"0"` | PR to process on dispatch; `0` processes all |
|
|
315
|
+
| `FETCH_DEPTH` | string | `"10"` | Fetch depth for checkout |
|
|
316
|
+
| `SUBMIT_SINGLE_COMMITS` | boolean | `false` | Submit one commit at a time |
|
|
317
|
+
| `USE_PR_AS_COMMIT` | boolean | `false` | Use PR title and body as the commit message |
|
|
318
|
+
| `PRESERVE_GITHUB_PRS` | boolean | `true` | Do not close GitHub PRs after pushing |
|
|
319
|
+
| `CLOSE_MERGED_PRS` | boolean | `true` | Close GitHub PRs when their Gerrit change merges |
|
|
320
|
+
| `CLEANUP_ABANDONED` | boolean | `true` | Close GitHub PRs for abandoned Gerrit changes |
|
|
321
|
+
| `CLEANUP_GERRIT` | boolean | `true` | Abandon Gerrit changes when their PR closes |
|
|
322
|
+
| `CREATE_MISSING` | boolean | `false` | Create a change when UPDATE finds none |
|
|
323
|
+
| `AUTOMATION_ONLY` | boolean | `true` | Accept PRs from known automation tools only |
|
|
324
|
+
| `NORMALISE_COMMIT` | boolean | `false` | Normalize commit messages |
|
|
325
|
+
| `COMMIT_RULES_JSON` | string | `""` | JSON commit message validation rules |
|
|
326
|
+
| `ALLOW_DUPLICATES` | boolean | `true` | Allow submitting duplicate changes |
|
|
327
|
+
| `DUPLICATE_TYPES` | string | `"open"` | Gerrit states checked for duplicates |
|
|
328
|
+
| `FORCE` | boolean | `false` | Force PR closure regardless of change status |
|
|
329
|
+
| `VERBOSE` | boolean | `false` | Verbose output (DEBUG log level) |
|
|
330
|
+
| `ALLOW_GHE_URLS` | boolean | `false` | Allow GitHub Enterprise URLs |
|
|
331
|
+
| `DRY_RUN` | boolean | `false` | Check only; do not write to Gerrit |
|
|
332
|
+
| `ISSUE_ID` | string | `""` | Issue ID trailer to include |
|
|
333
|
+
| `ISSUE_ID_LOOKUP_JSON` | string | `"[]"` | JSON array mapping GitHub actors to Issue IDs |
|
|
334
|
+
| `REVIEWERS_EMAIL` | string | `""` | Comma-separated reviewer emails |
|
|
335
|
+
| `GERRIT_CHANGE_URL` | string | `""` | Gerrit change URL from a Gerrit event dispatch¹ |
|
|
336
|
+
| `GERRIT_EVENT_TYPE` | string | `""` | Gerrit event type (e.g. `change-merged`)¹ |
|
|
337
|
+
| `GERRIT_BRANCH` | string | `""` | Target branch override (Gerrit event dispatch)¹ |
|
|
338
|
+
|
|
339
|
+
| Secret | Required | Description |
|
|
340
|
+
| ------------------------ | -------- | ---------------------------------------------- |
|
|
341
|
+
| `GERRIT_SSH_PRIVKEY_G2G` | Yes | SSH private key for the Gerrit automation user |
|
|
342
|
+
|
|
343
|
+
| Output | Description |
|
|
344
|
+
| --------------------------- | ------------------------------------------ |
|
|
345
|
+
| `gerrit_change_request_url` | Gerrit change URL(s), newline-separated |
|
|
346
|
+
| `gerrit_change_request_num` | Gerrit change number(s), newline-separated |
|
|
347
|
+
| `gerrit_commit_sha` | Patch set commit SHA(s), newline-separated |
|
|
348
|
+
|
|
349
|
+
<!-- markdownlint-enable MD013 -->
|
|
350
|
+
|
|
351
|
+
¹ Gerrit → GitHub reverse flow: when Gerrit-side automation
|
|
352
|
+
dispatches the caller workflow to report a merged or abandoned
|
|
353
|
+
change, forward these dispatch inputs and the tool closes the source
|
|
354
|
+
GitHub PR instead of processing pull requests.
|
|
355
|
+
|
|
356
|
+
Setting the repository variable `G2G_NO_GERRIT` to `true` makes runs
|
|
357
|
+
skip Gerrit interaction. Test-only settings (`CI_TESTING`,
|
|
358
|
+
`USE_LOCAL_ACTION`) remain composite-action-only by design.
|
|
359
|
+
|
|
360
|
+
## Documentation
|
|
361
|
+
|
|
362
|
+
<!-- markdownlint-disable MD013 -->
|
|
363
|
+
|
|
364
|
+
| Document | Contents |
|
|
365
|
+
| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
366
|
+
| [docs/features.md](docs/features.md) | Feature reference: PR updates, comment commands, cleanup, duplicate detection, reconciliation, normalization, configuration |
|
|
367
|
+
| [docs/cli.md](docs/cli.md) | CLI installation, options, environment variables, exit codes, debugging |
|
|
368
|
+
| [docs/COMMIT_RULES.md](docs/COMMIT_RULES.md) | Commit message validation rules and `COMMIT_RULES_JSON` format |
|
|
369
|
+
| [docs/development.md](docs/development.md) | Contributor guide: local setup, testing, composite action test suite |
|
|
370
|
+
|
|
371
|
+
<!-- markdownlint-enable MD013 -->
|
|
372
|
+
|
|
373
|
+
## Security notes
|
|
374
|
+
|
|
375
|
+
- Do not hardcode secrets or keys. Provide the private key through
|
|
376
|
+
workflow secrets and known hosts through repository or organization
|
|
377
|
+
variables.
|
|
378
|
+
- SSH handling is non-invasive: the tool creates temporary SSH files
|
|
379
|
+
in the workspace without modifying user SSH configuration or keys,
|
|
380
|
+
and cleans them up after execution.
|
|
381
|
+
- SSH connections use `IdentitiesOnly=yes` to avoid unintended key
|
|
382
|
+
usage (e.g. signing keys requiring biometric authentication).
|
|
383
|
+
|
|
384
|
+
## License
|
|
385
|
+
|
|
386
|
+
Apache License 2.0. See [LICENSE](LICENSE).
|