gerrit-clone 2.0.2__tar.gz → 2.2.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.
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/.pre-commit-config.yaml +5 -5
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/PKG-INFO +26 -5
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/README.md +25 -4
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/action.yaml +44 -1
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/pyproject.toml +0 -6
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/cli.py +418 -110
- gerrit_clone-2.2.0/src/gerrit_clone/content_filter.py +1321 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/file_logging.py +7 -1
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/mirror_manager.py +145 -71
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/models.py +66 -10
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/netrc.py +7 -4
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/refresh_manager.py +18 -3
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/refresh_worker.py +722 -45
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/integration/test_github_clone.py +7 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_clone_manager_github_refresh.py +1 -1
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_config.py +48 -0
- gerrit_clone-2.2.0/tests/test_content_filter.py +1260 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_file_logging_changes.py +36 -1
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_mirror_manager.py +292 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_models.py +32 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_netrc.py +2 -4
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_refresh_worker.py +715 -11
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_worker.py +2 -2
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/unit/test_discovery.py +4 -3
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/.gitignore +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/IMPLEMENTATION.md +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/LICENSE +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/__init__.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/clone_manager.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/clone_utils.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/concurrent_utils.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/config.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/discovery.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/error_codes.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/gerrit_api.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/git_comparison.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/git_utils.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/github_api.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/github_discovery.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/github_worker.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/logging.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/output_utils.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/pathing.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/progress.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/py.typed +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/rate_limit.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/reset_manager.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/reset_models.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/retry.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/rich_status.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/ssh_discovery.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/unified_discovery.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/src/gerrit_clone/worker.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/__init__.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/conftest.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/integration/__init__.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/integration/test_discovery_integration.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_action_cli_alignment.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_cli_netrc_options.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_clone_utils.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_gerrit_api.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_git_comparison.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_git_utils.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_github_api.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_logging.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_output_utils.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_pathing.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_project_filtering.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_rate_limit.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_refresh_manager.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_reset_manager.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_reset_models.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/test_retry.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/unit/__init__.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/unit/test_github_discovery.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/unit/test_github_worker.py +0 -0
- {gerrit_clone-2.0.2 → gerrit_clone-2.2.0}/tests/unit/test_unified_discovery.py +0 -0
|
@@ -51,7 +51,7 @@ repos:
|
|
|
51
51
|
types: [yaml]
|
|
52
52
|
|
|
53
53
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
54
|
-
rev:
|
|
54
|
+
rev: 01a675ea018f2fb714478a5ffb83fcea8374bb06 # frozen: v0.15.21
|
|
55
55
|
hooks:
|
|
56
56
|
- id: ruff
|
|
57
57
|
files: ^(scripts|tests|custom_components)/.+\.py$
|
|
@@ -60,7 +60,7 @@ repos:
|
|
|
60
60
|
files: ^(scripts|tests|custom_components)/.+\.py$
|
|
61
61
|
|
|
62
62
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
63
|
-
rev:
|
|
63
|
+
rev: 41e691678310dfd3833f7ab4e180ddb014310356 # frozen: v2.3.0
|
|
64
64
|
hooks:
|
|
65
65
|
- id: mypy
|
|
66
66
|
additional_dependencies:
|
|
@@ -109,17 +109,17 @@ repos:
|
|
|
109
109
|
|
|
110
110
|
# Requires a mirror, primary repo lacks .pre-commit-hooks.yaml
|
|
111
111
|
- repo: https://github.com/DetachHead/basedpyright-prek-mirror
|
|
112
|
-
rev:
|
|
112
|
+
rev: d55eabd2531b4f4a4c49c30fba627ce3a636ab79 # frozen: 1.39.9
|
|
113
113
|
hooks:
|
|
114
114
|
- id: basedpyright
|
|
115
115
|
|
|
116
116
|
- repo: https://github.com/lfreleng-actions/gha-workflow-linter
|
|
117
|
-
rev:
|
|
117
|
+
rev: 4c3079dcb6e9e3c295f961ce5bd5b8585db698ca # frozen: v1.2.2
|
|
118
118
|
hooks:
|
|
119
119
|
- id: gha-workflow-linter
|
|
120
120
|
|
|
121
121
|
- repo: https://github.com/python-jsonschema/check-jsonschema
|
|
122
|
-
rev:
|
|
122
|
+
rev: 1a4bb160cab6417b3045e1b37b6b72449243e658 # frozen: 0.37.4
|
|
123
123
|
hooks:
|
|
124
124
|
- id: check-github-actions
|
|
125
125
|
- id: check-github-workflows
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gerrit-clone
|
|
3
|
-
Version: 2.0
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: A multi-threaded CLI tool for bulk cloning repositories from Gerrit servers
|
|
5
5
|
Project-URL: Homepage, https://github.com/lfreleng-actions/gerrit-clone-action
|
|
6
6
|
Project-URL: Documentation, https://github.com/lfreleng-actions/gerrit-clone-action#readme
|
|
@@ -57,16 +57,18 @@ reliability, speed, and CI/CD compatibility.
|
|
|
57
57
|
- **Bulk Repository Discovery**: Fetches all projects via Gerrit REST API with
|
|
58
58
|
intelligent filtering
|
|
59
59
|
- **Multi-threaded Cloning**: Concurrent operations with auto-scaling thread
|
|
60
|
-
pools (
|
|
61
|
-
|
|
60
|
+
pools (Gerrit uses a conservative auto-default of at most 8 concurrent SSH
|
|
61
|
+
sessions to avoid server-side throttling; GitHub uses up to 64 with a 2x
|
|
62
|
+
multiplier; override either with `--threads`)
|
|
62
63
|
- **Hierarchy Preservation**: Maintains complete Gerrit project folder
|
|
63
64
|
structure without flattening
|
|
64
65
|
- **Complete Metadata Cloning**: Uses `git clone --mirror` by default to
|
|
65
66
|
capture all refs, tags, and branches for complete repository backups
|
|
66
67
|
- **GitHub Mirroring**: Mirror Gerrit repositories to GitHub organizations
|
|
67
68
|
with automatic name transformation
|
|
68
|
-
- **Robust Retry Logic**: Exponential backoff with jitter for transient
|
|
69
|
-
network and server failures
|
|
69
|
+
- **Robust Retry Logic**: Exponential backoff with full jitter for transient
|
|
70
|
+
network and server failures, including a small bounded retry for Gerrit SSH
|
|
71
|
+
throttling that can surface as a transient "Permission denied" rejection
|
|
70
72
|
- **SSH Integration**: Full SSH agent, identity file, and config support
|
|
71
73
|
- **CI/CD Ready**: Non-interactive operation with structured JSON manifests
|
|
72
74
|
- **Smart Filtering**: Automatically excludes system repos and archived
|
|
@@ -253,6 +255,25 @@ Automatically stash uncommitted changes before refresh:
|
|
|
253
255
|
gerrit-clone refresh --output-path ~/onap --auto-stash
|
|
254
256
|
```
|
|
255
257
|
|
|
258
|
+
Force refresh (stash local changes, fix detached HEAD, restore feature-branch
|
|
259
|
+
checkouts to the default branch):
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
gerrit-clone refresh --output-path ~/onap --force
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Hard reset: make local content exactly match the remote, discarding local-only
|
|
266
|
+
commits and any divergence. This is the single, explicit way to force-reset
|
|
267
|
+
local content and is a strict superset of `--force`:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
gerrit-clone refresh --output-path ~/onap --force-hard
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
> **Note:** `--force-hard` is destructive: it permanently discards
|
|
274
|
+
> local-only commits on the default branch. It leaves other local
|
|
275
|
+
> branches untouched.
|
|
276
|
+
|
|
256
277
|
Use rebase strategy instead of merge:
|
|
257
278
|
|
|
258
279
|
```bash
|
|
@@ -16,16 +16,18 @@ reliability, speed, and CI/CD compatibility.
|
|
|
16
16
|
- **Bulk Repository Discovery**: Fetches all projects via Gerrit REST API with
|
|
17
17
|
intelligent filtering
|
|
18
18
|
- **Multi-threaded Cloning**: Concurrent operations with auto-scaling thread
|
|
19
|
-
pools (
|
|
20
|
-
|
|
19
|
+
pools (Gerrit uses a conservative auto-default of at most 8 concurrent SSH
|
|
20
|
+
sessions to avoid server-side throttling; GitHub uses up to 64 with a 2x
|
|
21
|
+
multiplier; override either with `--threads`)
|
|
21
22
|
- **Hierarchy Preservation**: Maintains complete Gerrit project folder
|
|
22
23
|
structure without flattening
|
|
23
24
|
- **Complete Metadata Cloning**: Uses `git clone --mirror` by default to
|
|
24
25
|
capture all refs, tags, and branches for complete repository backups
|
|
25
26
|
- **GitHub Mirroring**: Mirror Gerrit repositories to GitHub organizations
|
|
26
27
|
with automatic name transformation
|
|
27
|
-
- **Robust Retry Logic**: Exponential backoff with jitter for transient
|
|
28
|
-
network and server failures
|
|
28
|
+
- **Robust Retry Logic**: Exponential backoff with full jitter for transient
|
|
29
|
+
network and server failures, including a small bounded retry for Gerrit SSH
|
|
30
|
+
throttling that can surface as a transient "Permission denied" rejection
|
|
29
31
|
- **SSH Integration**: Full SSH agent, identity file, and config support
|
|
30
32
|
- **CI/CD Ready**: Non-interactive operation with structured JSON manifests
|
|
31
33
|
- **Smart Filtering**: Automatically excludes system repos and archived
|
|
@@ -212,6 +214,25 @@ Automatically stash uncommitted changes before refresh:
|
|
|
212
214
|
gerrit-clone refresh --output-path ~/onap --auto-stash
|
|
213
215
|
```
|
|
214
216
|
|
|
217
|
+
Force refresh (stash local changes, fix detached HEAD, restore feature-branch
|
|
218
|
+
checkouts to the default branch):
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
gerrit-clone refresh --output-path ~/onap --force
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Hard reset: make local content exactly match the remote, discarding local-only
|
|
225
|
+
commits and any divergence. This is the single, explicit way to force-reset
|
|
226
|
+
local content and is a strict superset of `--force`:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
gerrit-clone refresh --output-path ~/onap --force-hard
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
> **Note:** `--force-hard` is destructive: it permanently discards
|
|
233
|
+
> local-only commits on the default branch. It leaves other local
|
|
234
|
+
> branches untouched.
|
|
235
|
+
|
|
215
236
|
Use rebase strategy instead of merge:
|
|
216
237
|
|
|
217
238
|
```bash
|
|
@@ -232,6 +232,29 @@ inputs:
|
|
|
232
232
|
description: "File logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)"
|
|
233
233
|
required: false
|
|
234
234
|
default: "DEBUG"
|
|
235
|
+
remove-files:
|
|
236
|
+
description: >-
|
|
237
|
+
Comma-separated list of file path patterns to remove
|
|
238
|
+
from cloned repositories. Supports shell-style globs
|
|
239
|
+
(e.g. '.github/**', '*.jar') and regex patterns
|
|
240
|
+
(prefix with 'regex:'). Uses git filter-repo when
|
|
241
|
+
available, falls back to worktree-based removal.
|
|
242
|
+
required: false
|
|
243
|
+
git-filter:
|
|
244
|
+
description: >-
|
|
245
|
+
Replace tokens in git history for matching projects.
|
|
246
|
+
Format: 'project:token1,token2;project2:token3'.
|
|
247
|
+
Semicolons separate project entries. Colons separate
|
|
248
|
+
project patterns from comma-separated tokens.
|
|
249
|
+
required: false
|
|
250
|
+
redact-secrets:
|
|
251
|
+
description: >-
|
|
252
|
+
Scan repository content for well-known credential
|
|
253
|
+
patterns (e.g. GitLab PATs, GitHub PATs, AWS keys)
|
|
254
|
+
and replace them with safe placeholder values.
|
|
255
|
+
Uses git filter-repo to rewrite history.
|
|
256
|
+
required: false
|
|
257
|
+
default: "false"
|
|
235
258
|
build-from-source:
|
|
236
259
|
description: >-
|
|
237
260
|
Build CLI from the action's own source instead of
|
|
@@ -460,6 +483,13 @@ runs:
|
|
|
460
483
|
INPUT_LOG_FILE: ${{ inputs.log-file }}
|
|
461
484
|
INPUT_DISABLE_LOG_FILE: ${{ inputs.disable-log-file }}
|
|
462
485
|
INPUT_LOG_LEVEL: ${{ inputs.log-level }}
|
|
486
|
+
INPUT_REMOVE_FILES: ${{ inputs.remove-files }}
|
|
487
|
+
# Passed straight to the CLI via its GERRIT_GIT_FILTER envvar
|
|
488
|
+
# rather than as a --git-filter argument, so the value (which
|
|
489
|
+
# may embed credential tokens) is never echoed in the command
|
|
490
|
+
# line logged below.
|
|
491
|
+
GERRIT_GIT_FILTER: ${{ inputs.git-filter }}
|
|
492
|
+
INPUT_REDACT_SECRETS: ${{ inputs.redact-secrets }}
|
|
463
493
|
run: |
|
|
464
494
|
# WARNING: Do NOT use literal empty expression syntax (dollar
|
|
465
495
|
# brace-brace with nothing inside) anywhere in this run block,
|
|
@@ -470,7 +500,7 @@ runs:
|
|
|
470
500
|
# Use action-managed SSH agent socket if it exists; otherwise,
|
|
471
501
|
# fall back to any existing SSH_AUTH_SOCK on the runner so that
|
|
472
502
|
# SSH-based clones using the runner's default agent/keys still work.
|
|
473
|
-
SSH_AGENT_SOCK="/tmp/ssh_agent_${
|
|
503
|
+
SSH_AGENT_SOCK="/tmp/ssh_agent_${GITHUB_RUN_ID}.sock"
|
|
474
504
|
if [ -S "$SSH_AGENT_SOCK" ]; then
|
|
475
505
|
export SSH_AUTH_SOCK="$SSH_AGENT_SOCK"
|
|
476
506
|
fi
|
|
@@ -638,6 +668,19 @@ runs:
|
|
|
638
668
|
cmd+=(--config-file "${INPUT_CONFIG_FILE}")
|
|
639
669
|
fi
|
|
640
670
|
|
|
671
|
+
# Content filtering options
|
|
672
|
+
if [ -n "$INPUT_REMOVE_FILES" ]; then
|
|
673
|
+
cmd+=(--remove-files "$INPUT_REMOVE_FILES")
|
|
674
|
+
fi
|
|
675
|
+
|
|
676
|
+
# The git filter value is supplied to the CLI through the
|
|
677
|
+
# GERRIT_GIT_FILTER environment variable (set in the step env
|
|
678
|
+
# above) so it never appears in the echoed command line.
|
|
679
|
+
|
|
680
|
+
if [ "$INPUT_REDACT_SECRETS" = "true" ]; then
|
|
681
|
+
cmd+=(--redact-secrets)
|
|
682
|
+
fi
|
|
683
|
+
|
|
641
684
|
# Add include-projects options (supports multiple)
|
|
642
685
|
# Use env var to avoid shell injection from expression
|
|
643
686
|
# interpolation in command substitutions; normalize
|
|
@@ -346,9 +346,3 @@ dev = [
|
|
|
346
346
|
"pytest-mock>=3.15.1",
|
|
347
347
|
"types-pyyaml>=6.0.12.20250915",
|
|
348
348
|
]
|
|
349
|
-
|
|
350
|
-
[tool.uv]
|
|
351
|
-
# Supply-chain cooldown: do not resolve anything published in the last
|
|
352
|
-
# 7 days (rolling window; uv records it as a relative span in uv.lock).
|
|
353
|
-
# Requires uv >= 0.9.17 for the relative-duration ("7 days") form.
|
|
354
|
-
exclude-newer = "7 days"
|