github2gerrit 0.1.8__tar.gz → 0.1.10__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 (90) hide show
  1. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.github/workflows/github2gerrit.yaml +22 -16
  2. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.pre-commit-config.yaml +7 -6
  3. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/PKG-INFO +28 -6
  4. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/README.md +27 -5
  5. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/REUSE.toml +1 -0
  6. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/action.yaml +51 -42
  7. github2gerrit-0.1.10/docs/github2gerrit_token_permissions_classic.png +0 -0
  8. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/cli.py +30 -18
  9. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/config.py +79 -1
  10. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/core.py +22 -3
  11. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/duplicate_detection.py +4 -2
  12. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/external_api.py +3 -2
  13. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/github_api.py +2 -0
  14. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/gitutils.py +12 -4
  15. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/similarity.py +2 -1
  16. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit.egg-info/PKG-INFO +28 -6
  17. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit.egg-info/SOURCES.txt +1 -0
  18. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_duplicate_detection.py +4 -1
  19. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_external_api_framework.py +2 -1
  20. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_gerrit_change_id_footer.py +21 -8
  21. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_gerrit_rest_client.py +4 -1
  22. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_gitutils_helpers.py +2 -1
  23. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_pr_content_filter_integration.py +6 -2
  24. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_url_parser.py +1 -1
  25. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.editorconfig +0 -0
  26. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.github/actionlint.yaml +0 -0
  27. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.github/dependabot.yml +0 -0
  28. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.github/release-drafter.yml +0 -0
  29. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.github/workflows/build-test-release.yaml +0 -0
  30. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.github/workflows/build-test.yaml +0 -0
  31. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.github/workflows/dependencies.yaml +0 -0
  32. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.github/workflows/release-drafter.yaml +0 -0
  33. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.github/workflows/semantic-pull-request.yaml +0 -0
  34. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.github/workflows/sha-pinned-actions.yaml +0 -0
  35. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.github/workflows/testing.yaml +0 -0
  36. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.gitignore +0 -0
  37. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.gitlint +0 -0
  38. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.markdownlint.yaml +0 -0
  39. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.readthedocs.yml +0 -0
  40. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/.yamllint +0 -0
  41. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/LICENSE +0 -0
  42. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/LICENSES/Apache-2.0.txt +0 -0
  43. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/pyproject.toml +0 -0
  44. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/setup.cfg +0 -0
  45. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/sitecustomize.py +0 -0
  46. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/__init__.py +0 -0
  47. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/commit_normalization.py +0 -0
  48. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/gerrit_rest.py +0 -0
  49. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/gerrit_urls.py +0 -0
  50. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/models.py +0 -0
  51. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/pr_content_filter.py +0 -0
  52. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/ssh_agent_setup.py +0 -0
  53. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/ssh_common.py +0 -0
  54. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/ssh_discovery.py +0 -0
  55. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit/utils.py +0 -0
  56. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit.egg-info/dependency_links.txt +0 -0
  57. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit.egg-info/entry_points.txt +0 -0
  58. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit.egg-info/requires.txt +0 -0
  59. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/src/github2gerrit.egg-info/top_level.txt +0 -0
  60. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/conftest.py +0 -0
  61. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/fixtures/__init__.py +0 -0
  62. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/fixtures/make_repo.py +0 -0
  63. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_change_id_deduplication.py +0 -0
  64. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_cli.py +0 -0
  65. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_cli_helpers.py +0 -0
  66. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_cli_outputs_file.py +0 -0
  67. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_cli_url_and_dryrun.py +0 -0
  68. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_commit_normalization.py +0 -0
  69. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_config_and_reviewers.py +0 -0
  70. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_config_helpers.py +0 -0
  71. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_core_close_pr_policy.py +0 -0
  72. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_core_config_and_errors.py +0 -0
  73. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_core_gerrit_backref_comment.py +0 -0
  74. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_core_gerrit_push_errors.py +0 -0
  75. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_core_gerrit_rest_results.py +0 -0
  76. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_core_integration_fixture_repo.py +0 -0
  77. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_core_prepare_commits.py +0 -0
  78. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_core_ssh_setup.py +0 -0
  79. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_gerrit_urls.py +0 -0
  80. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_gerrit_urls_more.py +0 -0
  81. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_ghe_and_gitreview_args.py +0 -0
  82. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_github_api_helpers.py +0 -0
  83. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_github_api_retry_and_helpers.py +0 -0
  84. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_misc_small_coverage.py +0 -0
  85. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_pr_content_filter.py +0 -0
  86. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_ssh_agent.py +0 -0
  87. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_ssh_common.py +0 -0
  88. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_ssh_discovery.py +0 -0
  89. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/tests/test_utils.py +0 -0
  90. {github2gerrit-0.1.8 → github2gerrit-0.1.10}/uv.lock +0 -0
@@ -25,7 +25,7 @@ on:
25
25
  type: string
26
26
  GERRIT_KNOWN_HOSTS:
27
27
  description: "known hosts"
28
- required: true
28
+ required: false
29
29
  type: string
30
30
  GERRIT_SERVER:
31
31
  description: "Gerrit hostname ex: git.opendaylight.org"
@@ -44,11 +44,11 @@ on:
44
44
  type: string
45
45
  GERRIT_SSH_USER_G2G:
46
46
  description: "Gerrit user-id for SSH"
47
- required: true
47
+ required: false
48
48
  type: string
49
49
  GERRIT_SSH_USER_G2G_EMAIL:
50
50
  description: "Email of the SSH user"
51
- required: true
51
+ required: false
52
52
  type: string
53
53
  ORGANIZATION:
54
54
  description: "Organization name, e.g. opendaylight"
@@ -95,6 +95,11 @@ on:
95
95
  required: false
96
96
  default: ""
97
97
  type: string
98
+ ALLOW_DUPLICATES:
99
+ description: "Allow submitting duplicate changes without error"
100
+ required: false
101
+ default: false
102
+ type: boolean
98
103
  secrets:
99
104
  GERRIT_SSH_PRIVKEY_G2G:
100
105
  description: "SSH Private key"
@@ -116,22 +121,18 @@ on:
116
121
  required: false
117
122
  default: false
118
123
  type: boolean
119
- FETCH_DEPTH:
120
- description: "fetch-depth for the clone. (Default: 10)"
121
- required: false
122
- default: "10"
123
- type: string
124
+
124
125
  GERRIT_KNOWN_HOSTS:
125
126
  description: "known hosts"
126
- required: true
127
+ required: false
127
128
  type: string
128
129
  GERRIT_SSH_USER_G2G:
129
130
  description: "Gerrit user-id for SSH"
130
- required: true
131
+ required: false
131
132
  type: string
132
133
  GERRIT_SSH_USER_G2G_EMAIL:
133
134
  description: "Email of the SSH user"
134
- required: true
135
+ required: false
135
136
  type: string
136
137
 
137
138
  PRESERVE_GITHUB_PRS:
@@ -149,6 +150,11 @@ on:
149
150
  required: false
150
151
  default: ""
151
152
  type: string
153
+ ALLOW_DUPLICATES:
154
+ description: "Allow submitting duplicate changes without error"
155
+ required: false
156
+ default: false
157
+ type: boolean
152
158
 
153
159
  concurrency:
154
160
  group: reusable-${{ github.workflow }}-${{ github.run_id }}
@@ -159,7 +165,7 @@ jobs:
159
165
  # Manual run: allow optional PR_NUMBER (0 => process all PRs)
160
166
  if: ${{ github.event_name == 'workflow_dispatch' }}
161
167
  runs-on: ubuntu-latest
162
- timeout-minutes: 6
168
+ timeout-minutes: 12
163
169
  steps:
164
170
  # yamllint disable rule:line-length
165
171
  # PR_NUMBER normalization is handled by the composite action
@@ -169,13 +175,12 @@ jobs:
169
175
  with:
170
176
  SUBMIT_SINGLE_COMMITS: ${{ inputs.SUBMIT_SINGLE_COMMITS }}
171
177
  USE_PR_AS_COMMIT: ${{ inputs.USE_PR_AS_COMMIT }}
172
- FETCH_DEPTH: ${{ inputs.FETCH_DEPTH }}
178
+
173
179
  GERRIT_KNOWN_HOSTS: ${{ inputs.GERRIT_KNOWN_HOSTS }}
174
180
  GERRIT_SSH_PRIVKEY_G2G: ${{ secrets.GERRIT_SSH_PRIVKEY_G2G }}
175
181
  GERRIT_SSH_USER_G2G: ${{ inputs.GERRIT_SSH_USER_G2G }}
176
182
  GERRIT_SSH_USER_G2G_EMAIL: ${{ inputs.GERRIT_SSH_USER_G2G_EMAIL }}
177
- ORGANIZATION: ${{ inputs.ORGANIZATION }}
178
- ALLOW_GHE_URLS: ${{ inputs.ALLOW_GHE_URLS }}
183
+ ALLOW_DUPLICATES: ${{ inputs.ALLOW_DUPLICATES }}
179
184
  PRESERVE_GITHUB_PRS: ${{ inputs.PRESERVE_GITHUB_PRS }}
180
185
  DRY_RUN: ${{ inputs.DRY_RUN }}
181
186
  ISSUE_ID: ${{ inputs.ISSUE_ID }}
@@ -185,7 +190,7 @@ jobs:
185
190
  # Only run if we have a proper pull request context
186
191
  if: ${{ github.event.pull_request.number || github.event.issue.number }}
187
192
  runs-on: ubuntu-latest
188
- timeout-minutes: 15
193
+ timeout-minutes: 12
189
194
  permissions:
190
195
  contents: read
191
196
  pull-requests: write
@@ -206,6 +211,7 @@ jobs:
206
211
  ALLOW_GHE_URLS: ${{ inputs.ALLOW_GHE_URLS }}
207
212
  PRESERVE_GITHUB_PRS: ${{ inputs.PRESERVE_GITHUB_PRS }}
208
213
  DRY_RUN: ${{ inputs.DRY_RUN }}
214
+ ALLOW_DUPLICATES: ${{ inputs.ALLOW_DUPLICATES }}
209
215
  ISSUE_ID: ${{ inputs.ISSUE_ID }}
210
216
  GERRIT_SERVER: ${{ inputs.GERRIT_SERVER }}
211
217
  GERRIT_SERVER_PORT: ${{ inputs.GERRIT_SERVER_PORT }}
@@ -58,7 +58,7 @@ repos:
58
58
  types: [yaml]
59
59
 
60
60
  - repo: https://github.com/astral-sh/ruff-pre-commit
61
- rev: 54a455f7ce629598b7535ff828fd5fb796f4b83f # frozen: v0.12.9
61
+ rev: 0acff885bcb16381b67930fefb91e460202f172c # frozen: v0.12.10
62
62
  hooks:
63
63
  - id: ruff
64
64
  files: ^(src|scripts|tests)/.+\.py$
@@ -74,11 +74,12 @@ repos:
74
74
  - types-PyYAML
75
75
  - types-requests
76
76
 
77
- - repo: https://github.com/RobertCraigie/pyright-python
78
- rev: d393df1703a808473b84bd14a2702f4793014031 # frozen: v1.1.404
79
- hooks:
80
- - id: pyright
81
- files: ^(src|scripts|tests)/.+\.py$
77
+ # Doesn't seem to run reliably inside pre-commit.ci
78
+ # - repo: https://github.com/RobertCraigie/pyright-python
79
+ # rev: d393df1703a808473b84bd14a2702f4793014031 # frozen: v1.1.404
80
+ # hooks:
81
+ # - id: pyright
82
+ # files: ^(src|scripts|tests)/.+\.py$
82
83
 
83
84
  - repo: https://github.com/btford/write-good
84
85
  rev: ab66ce10136dfad5146e69e70f82a3efac8842c1 # frozen: v1.0.8
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: github2gerrit
3
- Version: 0.1.8
3
+ Version: 0.1.10
4
4
  Summary: Submit a GitHub pull request to a Gerrit repository.
5
5
  Author-email: Matthew Watkins <mwatkins@linuxfoundation.org>
6
6
  License-Expression: Apache-2.0
@@ -140,6 +140,27 @@ with:
140
140
  When allowed, duplicates generate warnings but processing continues.
141
141
  The tool exits with code 3 when it detects duplicates and they are not allowed.
142
142
 
143
+ ### Configuring duplicate detection scope
144
+
145
+ By default, the duplicate detector considers changes with status `open` when searching for potential duplicates.
146
+ You can customize which Gerrit change states to check using `--duplicate-types` or setting `DUPLICATE_TYPES`:
147
+
148
+ ```bash
149
+ # CLI usage - check against open and merged changes
150
+ github2gerrit --duplicate-types=open,merged https://github.com/org/repo
151
+
152
+ # Environment variable
153
+ DUPLICATE_TYPES=open,merged,abandoned github2gerrit https://github.com/org/repo
154
+
155
+ # GitHub Actions
156
+ uses: onap/github2gerrit@main
157
+ with:
158
+ DUPLICATE_TYPES: 'open,merged'
159
+ ```
160
+
161
+ Valid change states include `open`, `merged`, and `abandoned`. This setting determines which existing changes
162
+ to check when evaluating whether a new change would be a duplicate.
163
+
143
164
  ## Commit Message Normalization
144
165
 
145
166
  The tool includes intelligent commit message normalization that automatically
@@ -297,7 +318,7 @@ jobs:
297
318
  steps:
298
319
  - name: Submit PR to Gerrit
299
320
  id: g2g
300
- uses: lfit/github2gerrit@main
321
+ uses: lfreleng-actions/github2gerrit-action@main
301
322
  with:
302
323
  SUBMIT_SINGLE_COMMITS: "false"
303
324
  USE_PR_AS_COMMIT: "false"
@@ -343,7 +364,7 @@ uv run github2gerrit
343
364
  uvx github2gerrit https://github.com/owner/repo/pull/123
344
365
 
345
366
  # Install from specific version/source
346
- uvx --from git+https://github.com/lfit/github2gerrit@main github2gerrit https://github.com/owner/repo/pull/123
367
+ uvx --from git+https://github.com/lfreleng-actions/github2gerrit-action@main github2gerrit https://github.com/owner/repo/pull/123
347
368
  ```
348
369
 
349
370
  ### Available Options
@@ -368,6 +389,7 @@ Key options include:
368
389
  - `--use-pr-as-commit`: Use PR title/body as commit message (`USE_PR_AS_COMMIT`)
369
390
  - `--issue-id`: Add an Issue-ID trailer (e.g., "Issue-ID: ABC-123") to the commit message (`ISSUE_ID`)
370
391
  - `--preserve-github-prs`: Don't close GitHub PRs after submission (`PRESERVE_GITHUB_PRS`)
392
+ - `--duplicate-types`: Configure which Gerrit change states to check for duplicates (`DUPLICATE_TYPES`)
371
393
 
372
394
  For a complete list of all available options, see the [Inputs](#inputs) section.
373
395
 
@@ -524,7 +546,7 @@ jobs:
524
546
 
525
547
  - name: Submit PR to Gerrit (with explicit overrides)
526
548
  id: g2g
527
- uses: lfit/github2gerrit@main
549
+ uses: lfreleng-actions/github2gerrit-action@main
528
550
  with:
529
551
  # Behavior
530
552
  SUBMIT_SINGLE_COMMITS: "false"
@@ -593,7 +615,7 @@ alignment between action inputs, environment variables, and CLI flags:
593
615
  | `CI_TESTING` | `CI_TESTING` | `--ci-testing` | No | `"false"` | Enable CI testing mode (overrides .gitreview) |
594
616
  | `ISSUE_ID` | `ISSUE_ID` | `--issue-id` | No | `""` | Issue ID to include (e.g., ABC-123) |
595
617
  | `G2G_USE_SSH_AGENT` | `G2G_USE_SSH_AGENT` | N/A | No | `"true"` | Use SSH agent for authentication |
596
- | `DUPLICATES` | `DUPLICATES` | `--duplicates` | No | `"open"` | Comma-separated Gerrit statuses for duplicate detection |
618
+ | `DUPLICATE_TYPES` | `DUPLICATE_TYPES` | `--duplicate-types` | No | `"open"` | Comma-separated Gerrit change states to check for duplicate detection |
597
619
  | `GERRIT_SERVER` | `GERRIT_SERVER` | `--gerrit-server` | No² | `""` | Gerrit server hostname (auto-derived if enabled) |
598
620
  | `GERRIT_SERVER_PORT` | `GERRIT_SERVER_PORT` | `--gerrit-server-port` | No | `"29418"` | Gerrit SSH port |
599
621
  | `GERRIT_PROJECT` | `GERRIT_PROJECT` | `--gerrit-project` | No² | `""` | Gerrit project name |
@@ -777,7 +799,7 @@ For CI/CD pipelines (like GitHub Actions), use `uvx` to install and run without
777
799
  uvx github2gerrit <PR_URL> --dry-run
778
800
 
779
801
  # Install from a specific version or source
780
- uvx --from git+https://github.com/lfit/github2gerrit@main github2gerrit <PR_URL>
802
+ uvx --from git+https://github.com/lfreleng-actions/github2gerrit-action@main github2gerrit <PR_URL>
781
803
 
782
804
  # Run with specific Python version
783
805
  uvx --python 3.11 github2gerrit <PR_URL>
@@ -100,6 +100,27 @@ with:
100
100
  When allowed, duplicates generate warnings but processing continues.
101
101
  The tool exits with code 3 when it detects duplicates and they are not allowed.
102
102
 
103
+ ### Configuring duplicate detection scope
104
+
105
+ By default, the duplicate detector considers changes with status `open` when searching for potential duplicates.
106
+ You can customize which Gerrit change states to check using `--duplicate-types` or setting `DUPLICATE_TYPES`:
107
+
108
+ ```bash
109
+ # CLI usage - check against open and merged changes
110
+ github2gerrit --duplicate-types=open,merged https://github.com/org/repo
111
+
112
+ # Environment variable
113
+ DUPLICATE_TYPES=open,merged,abandoned github2gerrit https://github.com/org/repo
114
+
115
+ # GitHub Actions
116
+ uses: onap/github2gerrit@main
117
+ with:
118
+ DUPLICATE_TYPES: 'open,merged'
119
+ ```
120
+
121
+ Valid change states include `open`, `merged`, and `abandoned`. This setting determines which existing changes
122
+ to check when evaluating whether a new change would be a duplicate.
123
+
103
124
  ## Commit Message Normalization
104
125
 
105
126
  The tool includes intelligent commit message normalization that automatically
@@ -257,7 +278,7 @@ jobs:
257
278
  steps:
258
279
  - name: Submit PR to Gerrit
259
280
  id: g2g
260
- uses: lfit/github2gerrit@main
281
+ uses: lfreleng-actions/github2gerrit-action@main
261
282
  with:
262
283
  SUBMIT_SINGLE_COMMITS: "false"
263
284
  USE_PR_AS_COMMIT: "false"
@@ -303,7 +324,7 @@ uv run github2gerrit
303
324
  uvx github2gerrit https://github.com/owner/repo/pull/123
304
325
 
305
326
  # Install from specific version/source
306
- uvx --from git+https://github.com/lfit/github2gerrit@main github2gerrit https://github.com/owner/repo/pull/123
327
+ uvx --from git+https://github.com/lfreleng-actions/github2gerrit-action@main github2gerrit https://github.com/owner/repo/pull/123
307
328
  ```
308
329
 
309
330
  ### Available Options
@@ -328,6 +349,7 @@ Key options include:
328
349
  - `--use-pr-as-commit`: Use PR title/body as commit message (`USE_PR_AS_COMMIT`)
329
350
  - `--issue-id`: Add an Issue-ID trailer (e.g., "Issue-ID: ABC-123") to the commit message (`ISSUE_ID`)
330
351
  - `--preserve-github-prs`: Don't close GitHub PRs after submission (`PRESERVE_GITHUB_PRS`)
352
+ - `--duplicate-types`: Configure which Gerrit change states to check for duplicates (`DUPLICATE_TYPES`)
331
353
 
332
354
  For a complete list of all available options, see the [Inputs](#inputs) section.
333
355
 
@@ -484,7 +506,7 @@ jobs:
484
506
 
485
507
  - name: Submit PR to Gerrit (with explicit overrides)
486
508
  id: g2g
487
- uses: lfit/github2gerrit@main
509
+ uses: lfreleng-actions/github2gerrit-action@main
488
510
  with:
489
511
  # Behavior
490
512
  SUBMIT_SINGLE_COMMITS: "false"
@@ -553,7 +575,7 @@ alignment between action inputs, environment variables, and CLI flags:
553
575
  | `CI_TESTING` | `CI_TESTING` | `--ci-testing` | No | `"false"` | Enable CI testing mode (overrides .gitreview) |
554
576
  | `ISSUE_ID` | `ISSUE_ID` | `--issue-id` | No | `""` | Issue ID to include (e.g., ABC-123) |
555
577
  | `G2G_USE_SSH_AGENT` | `G2G_USE_SSH_AGENT` | N/A | No | `"true"` | Use SSH agent for authentication |
556
- | `DUPLICATES` | `DUPLICATES` | `--duplicates` | No | `"open"` | Comma-separated Gerrit statuses for duplicate detection |
578
+ | `DUPLICATE_TYPES` | `DUPLICATE_TYPES` | `--duplicate-types` | No | `"open"` | Comma-separated Gerrit change states to check for duplicate detection |
557
579
  | `GERRIT_SERVER` | `GERRIT_SERVER` | `--gerrit-server` | No² | `""` | Gerrit server hostname (auto-derived if enabled) |
558
580
  | `GERRIT_SERVER_PORT` | `GERRIT_SERVER_PORT` | `--gerrit-server-port` | No | `"29418"` | Gerrit SSH port |
559
581
  | `GERRIT_PROJECT` | `GERRIT_PROJECT` | `--gerrit-project` | No² | `""` | Gerrit project name |
@@ -737,7 +759,7 @@ For CI/CD pipelines (like GitHub Actions), use `uvx` to install and run without
737
759
  uvx github2gerrit <PR_URL> --dry-run
738
760
 
739
761
  # Install from a specific version or source
740
- uvx --from git+https://github.com/lfit/github2gerrit@main github2gerrit <PR_URL>
762
+ uvx --from git+https://github.com/lfreleng-actions/github2gerrit-action@main github2gerrit <PR_URL>
741
763
 
742
764
  # Run with specific Python version
743
765
  uvx --python 3.11 github2gerrit <PR_URL>
@@ -7,6 +7,7 @@ version = 1
7
7
 
8
8
  [[annotations]]
9
9
  path = [
10
+ "docs/*.png",
10
11
  "*.lock"
11
12
  ]
12
13
  SPDX-License-Identifier = "Apache-2.0"
@@ -6,6 +6,10 @@ name: github2gerrit
6
6
  description: "Creates Gerrit changes from GitHub pull requests"
7
7
 
8
8
  inputs:
9
+ # Optional
10
+ GERRIT_SSH_PRIVKEY_G2G:
11
+ description: "SSH private key content used to authenticate to Gerrit"
12
+ required: true
9
13
  SUBMIT_SINGLE_COMMITS:
10
14
  description: "Submit one commit at a time to the Gerrit repository"
11
15
  required: false
@@ -22,35 +26,17 @@ inputs:
22
26
  description: "Pull request number to process, use 0 to process all open"
23
27
  required: false
24
28
  default: "0"
25
-
26
- # SSH and identity
27
29
  GERRIT_KNOWN_HOSTS:
28
30
  description: "Known hosts entries for Gerrit SSH (single or multi-line)"
29
- required: true
30
- GERRIT_SSH_PRIVKEY_G2G:
31
- description: "SSH private key content used to authenticate to Gerrit"
32
- required: true
31
+ required: false
33
32
  GERRIT_SSH_USER_G2G:
34
- description: >
35
- Gerrit SSH username (e.g. automation bot account). In GitHub Actions,
36
- automatically derived as [ORGANIZATION].gh2gerrit when not provided if
37
- G2G_ENABLE_DERIVATION=true (default: false). For local CLI usage,
38
- derivation is enabled by default; set
39
- G2G_ENABLE_DERIVATION=false to disable.
33
+ description: "Gerrit SSH username; derived if not supplied explicitly"
40
34
  required: false
41
35
  default: ""
42
36
  GERRIT_SSH_USER_G2G_EMAIL:
43
- description: >
44
- Email address associated to the Gerrit SSH user. In GitHub Actions,
45
- automatically derived as
46
- releng+[ORGANIZATION]-gh2gerrit@linuxfoundation.org when not provided if
47
- G2G_ENABLE_DERIVATION=true (default: false). For local CLI usage,
48
- derivation is enabled by default; set
49
- G2G_ENABLE_DERIVATION=false to disable.
37
+ description: "Gerrit user email address; derived if not supplied explicitly"
50
38
  required: false
51
39
  default: ""
52
-
53
- # Behavior and metadata
54
40
  ORGANIZATION:
55
41
  description: "GitHub organization/owner (defaults to repo owner)"
56
42
  required: false
@@ -76,7 +62,7 @@ inputs:
76
62
  required: false
77
63
  default: "false"
78
64
  CI_TESTING:
79
- description: "Enable CI testing mode (overrides .gitreview, handles unrelated repos)"
65
+ description: "Enable CI testing mode; overrides .gitreview, creates orphan commits"
80
66
  required: false
81
67
  default: "false"
82
68
  ISSUE_ID:
@@ -87,38 +73,26 @@ inputs:
87
73
  description: "Use SSH agent for authentication instead of file-based keys (recommended)"
88
74
  required: false
89
75
  default: "true"
90
-
91
- DUPLICATES:
92
- description: >
93
- Comma-separated Gerrit statuses to consider for duplicate
94
- detection (e.g., open,merged,abandoned)
76
+ DUPLICATE_TYPES:
77
+ description: "Comma-separated Gerrit states for evaluating duplicates"
95
78
  required: false
96
79
  default: "open"
97
80
  NORMALISE_COMMIT:
98
81
  description: "Normalize commit messages to conventional commit format"
99
82
  required: false
100
- default: "true"
101
-
102
- # Optional Gerrit overrides (used when .gitreview is missing)
83
+ default: "false"
103
84
  GERRIT_SERVER:
104
- description: >
105
- Gerrit server hostname (optional; use .gitreview if present). In GitHub
106
- Actions, automatically derived as gerrit.[ORGANIZATION].org when not
107
- provided if G2G_ENABLE_DERIVATION=true (default: false). For local CLI
108
- usage, derivation is enabled by default; set G2G_ENABLE_DERIVATION=false
109
- to disable.
85
+ description: "Gerrit server hostname; derived if not supplied explicitly"
110
86
  required: false
111
87
  default: ""
112
88
  GERRIT_SERVER_PORT:
113
- description: "Gerrit SSH port (default: 29418)"
89
+ description: "Gerrit serverSSH TCP/port"
114
90
  required: false
115
91
  default: "29418"
116
92
  GERRIT_PROJECT:
117
- description: "Gerrit project, optional if .gitreview exists"
93
+ description: "Gerrit project; optional if .gitreview exists"
118
94
  required: false
119
95
  default: ""
120
-
121
- # Optional Gerrit REST-related settings
122
96
  GERRIT_HTTP_BASE_PATH:
123
97
  description: "Optional HTTP base path for Gerrit REST (e.g. /r)"
124
98
  required: false
@@ -165,6 +139,41 @@ runs:
165
139
  # Ensure we are on the PR's head SHA when triggered by PR events
166
140
  ref: ${{ github.event.pull_request.head.sha || github.sha }}
167
141
 
142
+ - name: "Set key to use for JSON lookup"
143
+ if: ${{ inputs.ISSUE_ID == '' && vars.ISSUE_ID_LOOKUP == 'true' }}
144
+ shell: bash
145
+ run: |
146
+ # Set key to use for JSON lookup
147
+ ACTOR="${{ github.actor }}"
148
+ ACTOR_ID="${{ github.actor_id }}"
149
+ echo "Using GitHub actor as lookup key: $ACTOR [$ACTOR_ID]"
150
+ echo "key=$ACTOR" >> "$GITHUB_ENV"
151
+
152
+ - name: "Get ticket from JSON lookup table"
153
+ if: ${{ inputs.ISSUE_ID == '' && vars.ISSUE_ID_LOOKUP == 'true' }}
154
+ id: json-lookup
155
+ uses: lfit/releng-reusable-workflows/.github/actions/json-key-value-lookup-action@main
156
+ with:
157
+ json: ${{ vars.ISSUE_ID_LOOKUP_JSON }}
158
+ key: ${{ env.key }}
159
+
160
+ - name: "Set IssueID in GITHUB_ENV"
161
+ if: ${{ inputs.ISSUE_ID == '' && vars.ISSUE_ID_LOOKUP == 'true' }}
162
+ shell: bash
163
+ # yamllint disable rule:line-length
164
+ run: |
165
+ set -euo pipefail
166
+ val="${{ steps.json-lookup.outputs.value }}"
167
+ if [ -z "$val" ]; then
168
+ alt="${{ env.value }}"
169
+ if [ -n "$alt" ]; then
170
+ val="$alt"
171
+ fi
172
+ fi
173
+ if [ -n "$val" ]; then
174
+ echo "RESOLVED_ISSUE_ID=$val" >> "$GITHUB_ENV"
175
+ fi
176
+
168
177
  - name: Install required dependencies
169
178
  shell: bash
170
179
  run: |
@@ -253,9 +262,9 @@ runs:
253
262
  PRESERVE_GITHUB_PRS: ${{ inputs.PRESERVE_GITHUB_PRS }}
254
263
  DRY_RUN: ${{ inputs.DRY_RUN }}
255
264
  ALLOW_DUPLICATES: ${{ inputs.ALLOW_DUPLICATES }}
256
- ISSUE_ID: ${{ inputs.ISSUE_ID }}
265
+ ISSUE_ID: ${{ inputs.ISSUE_ID != '' && inputs.ISSUE_ID || env.RESOLVED_ISSUE_ID }}
257
266
  CI_TESTING: ${{ inputs.CI_TESTING }}
258
- DUPLICATES: ${{ inputs.DUPLICATES }}
267
+ DUPLICATE_TYPES: ${{ inputs.DUPLICATE_TYPES }}
259
268
  NORMALISE_COMMIT: ${{ inputs.NORMALISE_COMMIT }}
260
269
  G2G_USE_SSH_AGENT: ${{ inputs.G2G_USE_SSH_AGENT }}
261
270
 
@@ -3,13 +3,10 @@
3
3
 
4
4
  from __future__ import annotations
5
5
 
6
- import io
7
6
  import json
8
7
  import logging
9
8
  import os
10
- import shutil
11
9
  import tempfile
12
- import zipfile
13
10
  from collections.abc import Callable
14
11
  from concurrent.futures import ThreadPoolExecutor
15
12
  from concurrent.futures import as_completed
@@ -20,8 +17,6 @@ from typing import Protocol
20
17
  from typing import TypeVar
21
18
  from typing import cast
22
19
  from urllib.parse import urlparse
23
- from urllib.request import Request
24
- from urllib.request import urlopen
25
20
 
26
21
  import click
27
22
  import typer
@@ -270,12 +265,13 @@ def main(
270
265
  envvar="CI_TESTING",
271
266
  help="Enable CI testing mode (overrides .gitreview, handles unrelated repos).",
272
267
  ),
273
- duplicates: str = typer.Option(
268
+ duplicate_types: str = typer.Option(
274
269
  "open",
275
- "--duplicates",
276
- envvar="DUPLICATES",
270
+ "--duplicate-types",
271
+ envvar="DUPLICATE_TYPES",
277
272
  help=(
278
- 'Gerrit statuses for duplicate detection (comma-separated). E.g. "open,merged,abandoned". Default: "open".'
273
+ "Gerrit change states to evaluate when determining if a change should be considered a duplicate "
274
+ '(comma-separated). E.g. "open,merged,abandoned". Default: "open".'
279
275
  ),
280
276
  ),
281
277
  normalise_commit: bool = typer.Option(
@@ -295,11 +291,14 @@ def main(
295
291
  """
296
292
  Tool to convert GitHub pull requests into Gerrit changes
297
293
 
298
- - Providing a URL to a pull request: converts that pull request into a Gerrit change
294
+ - Providing a URL to a pull request: converts that pull request
295
+ into a Gerrit change
299
296
 
300
- - Providing a URL to a GitHub repository converts all open pull requests into Gerrit changes
297
+ - Providing a URL to a GitHub repository converts all open pull
298
+ requests into Gerrit changes
301
299
 
302
- - No arguments for CI/CD environment; reads parameters from environment variables
300
+ - No arguments for CI/CD environment; reads parameters from
301
+ environment variables
303
302
  """
304
303
  # Override boolean parameters with properly parsed environment variables
305
304
  # This ensures that string "false" from GitHub Actions is handled correctly
@@ -356,20 +355,26 @@ def main(
356
355
  os.environ["ISSUE_ID"] = issue_id
357
356
  os.environ["ALLOW_DUPLICATES"] = "true" if allow_duplicates else "false"
358
357
  os.environ["CI_TESTING"] = "true" if ci_testing else "false"
359
- if duplicates:
360
- os.environ["DUPLICATES"] = duplicates
358
+ if duplicate_types:
359
+ os.environ["DUPLICATE_TYPES"] = duplicate_types
361
360
  # URL mode handling
362
361
  if target_url:
363
362
  org, repo, pr = _parse_github_target(target_url)
363
+ log.debug("Parsed GitHub URL: org=%s, repo=%s, pr=%s", org, repo, pr)
364
364
  if org:
365
365
  os.environ["ORGANIZATION"] = org
366
+ log.debug("Set ORGANIZATION=%s", org)
366
367
  if org and repo:
367
- os.environ["GITHUB_REPOSITORY"] = f"{org}/{repo}"
368
+ github_repo = f"{org}/{repo}"
369
+ os.environ["GITHUB_REPOSITORY"] = github_repo
370
+ log.debug("Set GITHUB_REPOSITORY=%s", github_repo)
368
371
  if pr:
369
372
  os.environ["PR_NUMBER"] = str(pr)
370
373
  os.environ["SYNC_ALL_OPEN_PRS"] = "false"
374
+ log.debug("Set PR_NUMBER=%s", pr)
371
375
  else:
372
376
  os.environ["SYNC_ALL_OPEN_PRS"] = "true"
377
+ log.debug("Set SYNC_ALL_OPEN_PRS=true")
373
378
  os.environ["G2G_TARGET_URL"] = "1"
374
379
  # Debug: Show environment at CLI startup
375
380
  log.debug("CLI startup environment check:")
@@ -428,7 +433,7 @@ def _build_inputs_from_env() -> Inputs:
428
433
  issue_id=env_str("ISSUE_ID", ""),
429
434
  allow_duplicates=env_bool("ALLOW_DUPLICATES", False),
430
435
  ci_testing=env_bool("CI_TESTING", False),
431
- duplicates_filter=env_str("DUPLICATES", "open"),
436
+ duplicates_filter=env_str("DUPLICATE_TYPES", "open"),
432
437
  )
433
438
 
434
439
 
@@ -472,7 +477,7 @@ def _process_bulk(data: Inputs, gh: GitHubContext) -> bool:
472
477
 
473
478
  try:
474
479
  if data.duplicates_filter:
475
- os.environ["DUPLICATES"] = data.duplicates_filter
480
+ os.environ["DUPLICATE_TYPES"] = data.duplicates_filter
476
481
  check_for_duplicates(per_ctx, allow_duplicates=data.allow_duplicates)
477
482
  except DuplicateChangeError as exc:
478
483
  log_exception_conditionally(log, "Skipping PR #%d", pr_number)
@@ -748,6 +753,13 @@ def _prepare_local_checkout(workspace: Path, gh: GitHubContext, data: Inputs) ->
748
753
 
749
754
  def _fallback_to_api_archive(workspace: Path, gh: GitHubContext, data: Inputs, pr_num_str: str) -> None:
750
755
  """Fallback to GitHub API archive download for private repos."""
756
+ import io
757
+ import json
758
+ import shutil
759
+ import zipfile
760
+ from urllib.request import Request
761
+ from urllib.request import urlopen
762
+
751
763
  log.info("Attempting API archive fallback for PR #%s", pr_num_str)
752
764
 
753
765
  # Get GitHub token for authenticated requests
@@ -1011,7 +1023,7 @@ def _process() -> None:
1011
1023
  if gh.pr_number and not env_bool("SYNC_ALL_OPEN_PRS", False):
1012
1024
  try:
1013
1025
  if data.duplicates_filter:
1014
- os.environ["DUPLICATES"] = data.duplicates_filter
1026
+ os.environ["DUPLICATE_TYPES"] = data.duplicates_filter
1015
1027
  check_for_duplicates(gh, allow_duplicates=data.allow_duplicates)
1016
1028
  except DuplicateChangeError as exc:
1017
1029
  log_exception_conditionally(