pull-request-fixer 0.1.0__tar.gz → 0.1.2__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.
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/.gitignore +1 -0
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/PKG-INFO +265 -30
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/README.md +248 -15
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/pyproject.toml +92 -16
- pull_request_fixer-0.1.2/src/pull_request_fixer/_version.py +24 -0
- pull_request_fixer-0.1.2/src/pull_request_fixer/blocked_pr_scanner.py +216 -0
- pull_request_fixer-0.1.2/src/pull_request_fixer/cli.py +1855 -0
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/exceptions.py +6 -0
- pull_request_fixer-0.1.2/src/pull_request_fixer/file_fixer.py +245 -0
- pull_request_fixer-0.1.2/src/pull_request_fixer/git_config.py +258 -0
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/github_client.py +292 -4
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/models.py +31 -0
- pull_request_fixer-0.1.2/src/pull_request_fixer/pr_file_fixer.py +896 -0
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/pr_scanner.py +122 -5
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/progress_tracker.py +8 -8
- pull_request_fixer-0.1.0/src/pull_request_fixer/_version.py +0 -34
- pull_request_fixer-0.1.0/src/pull_request_fixer/cli.py +0 -1059
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/.pre-commit-hooks.yaml +0 -0
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/LICENSE +0 -0
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/LICENSES/Apache-2.0.txt +0 -0
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/scripts/README.md +0 -0
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/__init__.py +0 -0
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/graphql_queries.py +0 -0
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/pr_fixer.py +0 -0
- {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pull-request-fixer
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Pull request formatter and fixer with GitHub integration
|
|
5
5
|
Project-URL: Homepage, https://github.com/lfit/pull-request-fixer
|
|
6
6
|
Project-URL: Repository, https://github.com/lfit/pull-request-fixer.git
|
|
@@ -19,23 +19,25 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
23
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
23
24
|
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
24
|
-
Requires-Python:
|
|
25
|
-
Requires-Dist: aiolimiter>=1.2.
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Requires-Dist: aiolimiter>=1.2.1
|
|
27
|
+
Requires-Dist: dependamerge>=0.1.19
|
|
28
|
+
Requires-Dist: httpx[http2]>=0.28.1
|
|
29
|
+
Requires-Dist: pydantic>=2.12.5
|
|
30
|
+
Requires-Dist: rich>=14.2.0
|
|
31
|
+
Requires-Dist: tenacity>=9.1.2
|
|
32
|
+
Requires-Dist: typer>=0.20.0
|
|
31
33
|
Provides-Extra: dev
|
|
32
|
-
Requires-Dist: mypy>=1.
|
|
33
|
-
Requires-Dist: pre-commit>=4.0
|
|
34
|
-
Requires-Dist: pytest-asyncio>=
|
|
35
|
-
Requires-Dist: pytest-cov>=
|
|
36
|
-
Requires-Dist: pytest-mock>=3.
|
|
37
|
-
Requires-Dist: pytest>=
|
|
38
|
-
Requires-Dist: ruff>=0.8
|
|
34
|
+
Requires-Dist: mypy>=1.19.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pre-commit>=4.5.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-mock>=3.15.1; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest>=9.0.2; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff>=0.14.8; extra == 'dev'
|
|
39
41
|
Description-Content-Type: text/markdown
|
|
40
42
|
|
|
41
43
|
<!--
|
|
@@ -56,6 +58,10 @@ commit messages.
|
|
|
56
58
|
- **✍️ Title Fixing**: Set PR titles to match the first commit's subject line
|
|
57
59
|
- **📝 Body Fixing**: Set PR descriptions to match commit message bodies
|
|
58
60
|
(excluding trailers)
|
|
61
|
+
- **📄 File Fixing**: Apply regex-based search/replace to files in PRs (clones,
|
|
62
|
+
modifies, amends commit, and force-pushes changes)
|
|
63
|
+
- **🚫 Blocked PR Filtering**: Option to process PRs that cannot merge
|
|
64
|
+
(failing checks, conflicts, etc.)
|
|
59
65
|
- **🚀 Parallel Processing**: Process PRs concurrently for
|
|
60
66
|
performance
|
|
61
67
|
- **🔄 Dry Run Mode**: Preview changes before applying them
|
|
@@ -88,23 +94,46 @@ pull-request-fixer lfreleng-actions --fix-title
|
|
|
88
94
|
# Fix both titles and bodies
|
|
89
95
|
pull-request-fixer lfreleng-actions --fix-title --fix-body
|
|
90
96
|
|
|
97
|
+
# Show help (includes version)
|
|
98
|
+
pull-request-fixer --help
|
|
99
|
+
|
|
100
|
+
# Fix files in a specific PR using regex
|
|
101
|
+
pull-request-fixer https://github.com/owner/repo/pull/123 \
|
|
102
|
+
--fix-files \
|
|
103
|
+
--file-pattern './action.yaml' \
|
|
104
|
+
--search-pattern '^\s+type:\s+\S' \
|
|
105
|
+
--remove-lines \
|
|
106
|
+
--context-start 'inputs:' \
|
|
107
|
+
--context-end 'runs:' \
|
|
108
|
+
--dry-run \
|
|
109
|
+
--show-diff
|
|
110
|
+
|
|
91
111
|
# Preview changes without applying (dry run)
|
|
92
112
|
pull-request-fixer lfreleng-actions --fix-title --fix-body --dry-run
|
|
93
113
|
```
|
|
94
114
|
|
|
95
115
|
## Usage
|
|
96
116
|
|
|
97
|
-
### Basic
|
|
117
|
+
### Basic Commands
|
|
118
|
+
|
|
119
|
+
**Scan and fix an organization:**
|
|
98
120
|
|
|
99
121
|
```bash
|
|
100
122
|
pull-request-fixer ORGANIZATION [OPTIONS]
|
|
101
123
|
```
|
|
102
124
|
|
|
103
|
-
|
|
125
|
+
**Fix a specific PR:**
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
pull-request-fixer PR_URL [OPTIONS]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
You can specify the target as:
|
|
104
132
|
|
|
105
133
|
- Organization name: `myorg`
|
|
106
134
|
- GitHub URL: `https://github.com/myorg`
|
|
107
135
|
- GitHub URL with path: `https://github.com/myorg/`
|
|
136
|
+
- Specific PR URL: `https://github.com/owner/repo/pull/123`
|
|
108
137
|
|
|
109
138
|
### Fix Options
|
|
110
139
|
|
|
@@ -144,6 +173,94 @@ log in with special characters in passwords.
|
|
|
144
173
|
|
|
145
174
|
The `Signed-off-by:` trailer is automatically removed.
|
|
146
175
|
|
|
176
|
+
#### `--fix-files`
|
|
177
|
+
|
|
178
|
+
Fixes files in pull requests using regex-based search and replace. This feature:
|
|
179
|
+
|
|
180
|
+
1. Clones the PR branch
|
|
181
|
+
2. Finds files matching `--file-pattern` (regex)
|
|
182
|
+
3. Applies search/replace using `--search-pattern` and `--replacement`
|
|
183
|
+
4. Amends the last commit with the changes
|
|
184
|
+
5. Force-pushes the updated commit back to the PR
|
|
185
|
+
|
|
186
|
+
**Required options when using `--fix-files`:**
|
|
187
|
+
|
|
188
|
+
- `--file-pattern`: Regex to match file paths (e.g., `'./action.yaml'` or
|
|
189
|
+
`'.*\.yaml$'`)
|
|
190
|
+
- `--search-pattern`: Regex pattern to find in matched files
|
|
191
|
+
- Either `--replacement` (text to replace matches) or `--remove-lines` (to
|
|
192
|
+
delete matching lines)
|
|
193
|
+
|
|
194
|
+
**Optional context options (for line removal):**
|
|
195
|
+
|
|
196
|
+
- `--context-start`: Regex to define where the removal context begins (e.g., `'inputs:'`)
|
|
197
|
+
- `--context-end`: Regex to define where the removal context ends (e.g., `'runs:'`)
|
|
198
|
+
|
|
199
|
+
**Optional display options:**
|
|
200
|
+
|
|
201
|
+
- `--show-diff`: Show unified diff output for file changes
|
|
202
|
+
|
|
203
|
+
#### Update Methods (for `--fix-files` only)
|
|
204
|
+
|
|
205
|
+
The tool supports two methods for applying file fixes:
|
|
206
|
+
|
|
207
|
+
**API Method (default)** - Uses GitHub API to create new commits:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
pull-request-fixer https://github.com/owner/repo/pull/123 \
|
|
211
|
+
--fix-files \
|
|
212
|
+
--file-pattern './action.yaml' \
|
|
213
|
+
--search-pattern 'pattern'
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
- Creates new commits via GitHub API
|
|
217
|
+
- Shows as "Verified" by GitHub
|
|
218
|
+
- No Git operations required
|
|
219
|
+
- Faster and simpler
|
|
220
|
+
- Default method for ease of use
|
|
221
|
+
|
|
222
|
+
**Git Method** - Clones repo, amends commit, force-pushes:
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
pull-request-fixer https://github.com/owner/repo/pull/123 \
|
|
226
|
+
--fix-files \
|
|
227
|
+
--update-method git \
|
|
228
|
+
--file-pattern './action.yaml' \
|
|
229
|
+
--search-pattern 'pattern'
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
- Respects your local Git signing configuration
|
|
233
|
+
- Amends the existing commit (preserves commit history)
|
|
234
|
+
- Requires Git operations (clone, amend, push)
|
|
235
|
+
- Use when you need to amend commits or use your own signature
|
|
236
|
+
|
|
237
|
+
**Example - Remove type definitions from GitHub Actions:**
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
pull-request-fixer https://github.com/owner/repo/pull/123 \
|
|
241
|
+
--fix-files \
|
|
242
|
+
--file-pattern './action.yaml' \
|
|
243
|
+
--search-pattern '^\s+type:\s+\S' \
|
|
244
|
+
--remove-lines \
|
|
245
|
+
--context-start 'inputs:' \
|
|
246
|
+
--context-end 'runs:' \
|
|
247
|
+
--dry-run \
|
|
248
|
+
--show-diff
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
This will remove lines containing `type:` that appear between `inputs:` and `runs:`
|
|
252
|
+
sections in `action.yaml` files.
|
|
253
|
+
|
|
254
|
+
**Example - Replace text with regex:**
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
pull-request-fixer https://github.com/owner/repo/pull/456 \
|
|
258
|
+
--fix-files \
|
|
259
|
+
--file-pattern '.*\.py$' \
|
|
260
|
+
--search-pattern 'old_function_name' \
|
|
261
|
+
--replacement 'new_function_name'
|
|
262
|
+
```
|
|
263
|
+
|
|
147
264
|
### Common Usage Patterns
|
|
148
265
|
|
|
149
266
|
**Fix titles:**
|
|
@@ -182,6 +299,38 @@ pull-request-fixer myorg --fix-title --workers 16
|
|
|
182
299
|
pull-request-fixer myorg --fix-title --quiet
|
|
183
300
|
```
|
|
184
301
|
|
|
302
|
+
**Verbose mode for debugging:**
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
pull-request-fixer myorg --fix-files --file-pattern '*.yaml' \
|
|
306
|
+
--search-pattern '^\s+type:\s+\S' --remove-lines \
|
|
307
|
+
--verbose # Shows detailed DEBUG logs including file operations
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
**Process blocked PRs:**
|
|
311
|
+
|
|
312
|
+
<!-- write-good-disable -->
|
|
313
|
+
```bash
|
|
314
|
+
pull-request-fixer myorg --fix-title --blocked-only
|
|
315
|
+
```
|
|
316
|
+
<!-- write-good-enable -->
|
|
317
|
+
|
|
318
|
+
**Fix files across PRs:**
|
|
319
|
+
|
|
320
|
+
<!-- write-good-disable -->
|
|
321
|
+
```bash
|
|
322
|
+
pull-request-fixer myorg \
|
|
323
|
+
--fix-files \
|
|
324
|
+
--file-pattern './action.yaml' \
|
|
325
|
+
--search-pattern '^\s+type:\s+\S' \
|
|
326
|
+
--remove-lines \
|
|
327
|
+
--context-start 'inputs:' \
|
|
328
|
+
--context-end 'runs:' \
|
|
329
|
+
--blocked-only \
|
|
330
|
+
--dry-run
|
|
331
|
+
```
|
|
332
|
+
<!-- write-good-enable -->
|
|
333
|
+
|
|
185
334
|
## PR Comments
|
|
186
335
|
|
|
187
336
|
When the tool applies fixes (not in dry-run mode), it automatically adds a
|
|
@@ -207,19 +356,34 @@ comment.
|
|
|
207
356
|
|
|
208
357
|
## Options
|
|
209
358
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
|
214
|
-
|
|
|
215
|
-
| `--
|
|
216
|
-
| `--
|
|
217
|
-
| `--
|
|
218
|
-
| `--
|
|
219
|
-
| `--
|
|
220
|
-
| `--
|
|
221
|
-
| `--
|
|
222
|
-
| `--
|
|
359
|
+
<!-- markdownlint-disable MD013 -->
|
|
360
|
+
<!-- write-good-disable -->
|
|
361
|
+
|
|
362
|
+
| Flag | Short | Default | Description |
|
|
363
|
+
| ------------------ | ----- | --------------- | ----------------------------------------------------- |
|
|
364
|
+
| `--help` | `-h` | | Show help message and exit (displays version) |
|
|
365
|
+
| `--token` | `-t` | `$GITHUB_TOKEN` | GitHub personal access token |
|
|
366
|
+
| `--fix-title` | | `false` | Fix PR title to match first commit subject |
|
|
367
|
+
| `--fix-body` | | `false` | Fix PR body to match commit message body |
|
|
368
|
+
| `--fix-files` | | `false` | Fix files in PR using regex search/replace |
|
|
369
|
+
| `--file-pattern` | | | Regex to match file paths (required w/ `--fix-files`) |
|
|
370
|
+
| `--search-pattern` | | | Regex to search in files (required w/ `--fix-files`) |
|
|
371
|
+
| `--replacement` | | | Replacement string for matched patterns |
|
|
372
|
+
| `--remove-lines` | | `false` | Remove matching lines instead of replacing |
|
|
373
|
+
| `--context-start` | | | Regex pattern for context start (for line removal) |
|
|
374
|
+
| `--context-end` | | | Regex pattern for context end (for line removal) |
|
|
375
|
+
| `--show-diff` | | `false` | Show unified diff output for file changes |
|
|
376
|
+
| `--include-drafts` | | `false` | Include draft PRs in scan |
|
|
377
|
+
| `--blocked-only` | | `false` | Process PRs that cannot merge |
|
|
378
|
+
| `--dry-run` | | `false` | Preview changes without applying them |
|
|
379
|
+
| `--workers` | `-j` | `4` | Number of parallel workers (1-32) |
|
|
380
|
+
| `--verbose` | `-v` | `false` | Enable verbose output (DEBUG logs) |
|
|
381
|
+
| `--quiet` | `-q` | `false` | Suppress output except errors |
|
|
382
|
+
| `--log-level` | | `INFO` | Set logging level |
|
|
383
|
+
| `--version` | | | Show version and exit |
|
|
384
|
+
|
|
385
|
+
<!-- write-good-enable -->
|
|
386
|
+
<!-- markdownlint-enable MD013 -->
|
|
223
387
|
|
|
224
388
|
## How It Works
|
|
225
389
|
|
|
@@ -343,6 +507,77 @@ Example timing for 100 repositories with 50 blocked PRs using 8 workers:
|
|
|
343
507
|
- PR processing: ~20-30 seconds
|
|
344
508
|
- **Total: ~50-90 seconds**
|
|
345
509
|
|
|
510
|
+
### Example 4: Fix Files in a Blocked PR
|
|
511
|
+
|
|
512
|
+
This example removes invalid `type:` definitions from a GitHub composite action:
|
|
513
|
+
|
|
514
|
+
```bash
|
|
515
|
+
pull-request-fixer https://github.com/lfreleng-actions/make-action/pull/40 \
|
|
516
|
+
--fix-files \
|
|
517
|
+
--file-pattern './action.yaml' \
|
|
518
|
+
--search-pattern '^\s+type:\s+\S' \
|
|
519
|
+
--remove-lines \
|
|
520
|
+
--context-start 'inputs:' \
|
|
521
|
+
--context-end 'runs:' \
|
|
522
|
+
--dry-run \
|
|
523
|
+
--show-diff
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
Output:
|
|
527
|
+
|
|
528
|
+
```text
|
|
529
|
+
🔍 Processing PR: https://github.com/lfreleng-actions/make-action/pull/40
|
|
530
|
+
🔧 Will fix: files
|
|
531
|
+
🏃 Dry run mode: the tool will not apply changes
|
|
532
|
+
|
|
533
|
+
📝 Fixing files in PR...
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
✅ Would fix 1 file
|
|
537
|
+
📂 action.yaml
|
|
538
|
+
--- action.yaml
|
|
539
|
+
+++ action.yaml
|
|
540
|
+
@@ -10,7 +10,6 @@
|
|
541
|
+
repository:
|
|
542
|
+
description: 'Remote Git repository URL'
|
|
543
|
+
required: false
|
|
544
|
+
|
|
545
|
+
- type: 'string'
|
|
546
|
+
debug:
|
|
547
|
+
description: 'Enable debug mode'
|
|
548
|
+
required: false
|
|
549
|
+
- type: 'boolean'
|
|
550
|
+
|
|
551
|
+
Dry-run completed!
|
|
552
|
+
|
|
553
|
+
```text
|
|
554
|
+
|
|
555
|
+
Without `--dry-run`, the output would show:
|
|
556
|
+
|
|
557
|
+
```text
|
|
558
|
+
✅ Updated 1 file
|
|
559
|
+
🔀 action.yaml
|
|
560
|
+
--- action.yaml
|
|
561
|
+
+++ action.yaml
|
|
562
|
+
@@ -10,7 +10,6 @@
|
|
563
|
+
repository:
|
|
564
|
+
description: 'Remote Git repository URL'
|
|
565
|
+
required: false
|
|
566
|
+
- type: 'string'
|
|
567
|
+
debug:
|
|
568
|
+
description: 'Enable debug mode'
|
|
569
|
+
required: false
|
|
570
|
+
- type: 'boolean'
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
This would:
|
|
574
|
+
|
|
575
|
+
1. Clone the PR branch
|
|
576
|
+
2. Remove all lines containing `type:` from the `inputs:` section of `action.yaml`
|
|
577
|
+
3. Amend the last commit with the changes
|
|
578
|
+
4. Force-push the updated commit
|
|
579
|
+
5. Add a comment to the PR explaining the fix
|
|
580
|
+
|
|
346
581
|
## Troubleshooting
|
|
347
582
|
|
|
348
583
|
### No PRs Found
|
|
@@ -16,6 +16,10 @@ commit messages.
|
|
|
16
16
|
- **✍️ Title Fixing**: Set PR titles to match the first commit's subject line
|
|
17
17
|
- **📝 Body Fixing**: Set PR descriptions to match commit message bodies
|
|
18
18
|
(excluding trailers)
|
|
19
|
+
- **📄 File Fixing**: Apply regex-based search/replace to files in PRs (clones,
|
|
20
|
+
modifies, amends commit, and force-pushes changes)
|
|
21
|
+
- **🚫 Blocked PR Filtering**: Option to process PRs that cannot merge
|
|
22
|
+
(failing checks, conflicts, etc.)
|
|
19
23
|
- **🚀 Parallel Processing**: Process PRs concurrently for
|
|
20
24
|
performance
|
|
21
25
|
- **🔄 Dry Run Mode**: Preview changes before applying them
|
|
@@ -48,23 +52,46 @@ pull-request-fixer lfreleng-actions --fix-title
|
|
|
48
52
|
# Fix both titles and bodies
|
|
49
53
|
pull-request-fixer lfreleng-actions --fix-title --fix-body
|
|
50
54
|
|
|
55
|
+
# Show help (includes version)
|
|
56
|
+
pull-request-fixer --help
|
|
57
|
+
|
|
58
|
+
# Fix files in a specific PR using regex
|
|
59
|
+
pull-request-fixer https://github.com/owner/repo/pull/123 \
|
|
60
|
+
--fix-files \
|
|
61
|
+
--file-pattern './action.yaml' \
|
|
62
|
+
--search-pattern '^\s+type:\s+\S' \
|
|
63
|
+
--remove-lines \
|
|
64
|
+
--context-start 'inputs:' \
|
|
65
|
+
--context-end 'runs:' \
|
|
66
|
+
--dry-run \
|
|
67
|
+
--show-diff
|
|
68
|
+
|
|
51
69
|
# Preview changes without applying (dry run)
|
|
52
70
|
pull-request-fixer lfreleng-actions --fix-title --fix-body --dry-run
|
|
53
71
|
```
|
|
54
72
|
|
|
55
73
|
## Usage
|
|
56
74
|
|
|
57
|
-
### Basic
|
|
75
|
+
### Basic Commands
|
|
76
|
+
|
|
77
|
+
**Scan and fix an organization:**
|
|
58
78
|
|
|
59
79
|
```bash
|
|
60
80
|
pull-request-fixer ORGANIZATION [OPTIONS]
|
|
61
81
|
```
|
|
62
82
|
|
|
63
|
-
|
|
83
|
+
**Fix a specific PR:**
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pull-request-fixer PR_URL [OPTIONS]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
You can specify the target as:
|
|
64
90
|
|
|
65
91
|
- Organization name: `myorg`
|
|
66
92
|
- GitHub URL: `https://github.com/myorg`
|
|
67
93
|
- GitHub URL with path: `https://github.com/myorg/`
|
|
94
|
+
- Specific PR URL: `https://github.com/owner/repo/pull/123`
|
|
68
95
|
|
|
69
96
|
### Fix Options
|
|
70
97
|
|
|
@@ -104,6 +131,94 @@ log in with special characters in passwords.
|
|
|
104
131
|
|
|
105
132
|
The `Signed-off-by:` trailer is automatically removed.
|
|
106
133
|
|
|
134
|
+
#### `--fix-files`
|
|
135
|
+
|
|
136
|
+
Fixes files in pull requests using regex-based search and replace. This feature:
|
|
137
|
+
|
|
138
|
+
1. Clones the PR branch
|
|
139
|
+
2. Finds files matching `--file-pattern` (regex)
|
|
140
|
+
3. Applies search/replace using `--search-pattern` and `--replacement`
|
|
141
|
+
4. Amends the last commit with the changes
|
|
142
|
+
5. Force-pushes the updated commit back to the PR
|
|
143
|
+
|
|
144
|
+
**Required options when using `--fix-files`:**
|
|
145
|
+
|
|
146
|
+
- `--file-pattern`: Regex to match file paths (e.g., `'./action.yaml'` or
|
|
147
|
+
`'.*\.yaml$'`)
|
|
148
|
+
- `--search-pattern`: Regex pattern to find in matched files
|
|
149
|
+
- Either `--replacement` (text to replace matches) or `--remove-lines` (to
|
|
150
|
+
delete matching lines)
|
|
151
|
+
|
|
152
|
+
**Optional context options (for line removal):**
|
|
153
|
+
|
|
154
|
+
- `--context-start`: Regex to define where the removal context begins (e.g., `'inputs:'`)
|
|
155
|
+
- `--context-end`: Regex to define where the removal context ends (e.g., `'runs:'`)
|
|
156
|
+
|
|
157
|
+
**Optional display options:**
|
|
158
|
+
|
|
159
|
+
- `--show-diff`: Show unified diff output for file changes
|
|
160
|
+
|
|
161
|
+
#### Update Methods (for `--fix-files` only)
|
|
162
|
+
|
|
163
|
+
The tool supports two methods for applying file fixes:
|
|
164
|
+
|
|
165
|
+
**API Method (default)** - Uses GitHub API to create new commits:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
pull-request-fixer https://github.com/owner/repo/pull/123 \
|
|
169
|
+
--fix-files \
|
|
170
|
+
--file-pattern './action.yaml' \
|
|
171
|
+
--search-pattern 'pattern'
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
- Creates new commits via GitHub API
|
|
175
|
+
- Shows as "Verified" by GitHub
|
|
176
|
+
- No Git operations required
|
|
177
|
+
- Faster and simpler
|
|
178
|
+
- Default method for ease of use
|
|
179
|
+
|
|
180
|
+
**Git Method** - Clones repo, amends commit, force-pushes:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
pull-request-fixer https://github.com/owner/repo/pull/123 \
|
|
184
|
+
--fix-files \
|
|
185
|
+
--update-method git \
|
|
186
|
+
--file-pattern './action.yaml' \
|
|
187
|
+
--search-pattern 'pattern'
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
- Respects your local Git signing configuration
|
|
191
|
+
- Amends the existing commit (preserves commit history)
|
|
192
|
+
- Requires Git operations (clone, amend, push)
|
|
193
|
+
- Use when you need to amend commits or use your own signature
|
|
194
|
+
|
|
195
|
+
**Example - Remove type definitions from GitHub Actions:**
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
pull-request-fixer https://github.com/owner/repo/pull/123 \
|
|
199
|
+
--fix-files \
|
|
200
|
+
--file-pattern './action.yaml' \
|
|
201
|
+
--search-pattern '^\s+type:\s+\S' \
|
|
202
|
+
--remove-lines \
|
|
203
|
+
--context-start 'inputs:' \
|
|
204
|
+
--context-end 'runs:' \
|
|
205
|
+
--dry-run \
|
|
206
|
+
--show-diff
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
This will remove lines containing `type:` that appear between `inputs:` and `runs:`
|
|
210
|
+
sections in `action.yaml` files.
|
|
211
|
+
|
|
212
|
+
**Example - Replace text with regex:**
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
pull-request-fixer https://github.com/owner/repo/pull/456 \
|
|
216
|
+
--fix-files \
|
|
217
|
+
--file-pattern '.*\.py$' \
|
|
218
|
+
--search-pattern 'old_function_name' \
|
|
219
|
+
--replacement 'new_function_name'
|
|
220
|
+
```
|
|
221
|
+
|
|
107
222
|
### Common Usage Patterns
|
|
108
223
|
|
|
109
224
|
**Fix titles:**
|
|
@@ -142,6 +257,38 @@ pull-request-fixer myorg --fix-title --workers 16
|
|
|
142
257
|
pull-request-fixer myorg --fix-title --quiet
|
|
143
258
|
```
|
|
144
259
|
|
|
260
|
+
**Verbose mode for debugging:**
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
pull-request-fixer myorg --fix-files --file-pattern '*.yaml' \
|
|
264
|
+
--search-pattern '^\s+type:\s+\S' --remove-lines \
|
|
265
|
+
--verbose # Shows detailed DEBUG logs including file operations
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Process blocked PRs:**
|
|
269
|
+
|
|
270
|
+
<!-- write-good-disable -->
|
|
271
|
+
```bash
|
|
272
|
+
pull-request-fixer myorg --fix-title --blocked-only
|
|
273
|
+
```
|
|
274
|
+
<!-- write-good-enable -->
|
|
275
|
+
|
|
276
|
+
**Fix files across PRs:**
|
|
277
|
+
|
|
278
|
+
<!-- write-good-disable -->
|
|
279
|
+
```bash
|
|
280
|
+
pull-request-fixer myorg \
|
|
281
|
+
--fix-files \
|
|
282
|
+
--file-pattern './action.yaml' \
|
|
283
|
+
--search-pattern '^\s+type:\s+\S' \
|
|
284
|
+
--remove-lines \
|
|
285
|
+
--context-start 'inputs:' \
|
|
286
|
+
--context-end 'runs:' \
|
|
287
|
+
--blocked-only \
|
|
288
|
+
--dry-run
|
|
289
|
+
```
|
|
290
|
+
<!-- write-good-enable -->
|
|
291
|
+
|
|
145
292
|
## PR Comments
|
|
146
293
|
|
|
147
294
|
When the tool applies fixes (not in dry-run mode), it automatically adds a
|
|
@@ -167,19 +314,34 @@ comment.
|
|
|
167
314
|
|
|
168
315
|
## Options
|
|
169
316
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
|
174
|
-
|
|
|
175
|
-
| `--
|
|
176
|
-
| `--
|
|
177
|
-
| `--
|
|
178
|
-
| `--
|
|
179
|
-
| `--
|
|
180
|
-
| `--
|
|
181
|
-
| `--
|
|
182
|
-
| `--
|
|
317
|
+
<!-- markdownlint-disable MD013 -->
|
|
318
|
+
<!-- write-good-disable -->
|
|
319
|
+
|
|
320
|
+
| Flag | Short | Default | Description |
|
|
321
|
+
| ------------------ | ----- | --------------- | ----------------------------------------------------- |
|
|
322
|
+
| `--help` | `-h` | | Show help message and exit (displays version) |
|
|
323
|
+
| `--token` | `-t` | `$GITHUB_TOKEN` | GitHub personal access token |
|
|
324
|
+
| `--fix-title` | | `false` | Fix PR title to match first commit subject |
|
|
325
|
+
| `--fix-body` | | `false` | Fix PR body to match commit message body |
|
|
326
|
+
| `--fix-files` | | `false` | Fix files in PR using regex search/replace |
|
|
327
|
+
| `--file-pattern` | | | Regex to match file paths (required w/ `--fix-files`) |
|
|
328
|
+
| `--search-pattern` | | | Regex to search in files (required w/ `--fix-files`) |
|
|
329
|
+
| `--replacement` | | | Replacement string for matched patterns |
|
|
330
|
+
| `--remove-lines` | | `false` | Remove matching lines instead of replacing |
|
|
331
|
+
| `--context-start` | | | Regex pattern for context start (for line removal) |
|
|
332
|
+
| `--context-end` | | | Regex pattern for context end (for line removal) |
|
|
333
|
+
| `--show-diff` | | `false` | Show unified diff output for file changes |
|
|
334
|
+
| `--include-drafts` | | `false` | Include draft PRs in scan |
|
|
335
|
+
| `--blocked-only` | | `false` | Process PRs that cannot merge |
|
|
336
|
+
| `--dry-run` | | `false` | Preview changes without applying them |
|
|
337
|
+
| `--workers` | `-j` | `4` | Number of parallel workers (1-32) |
|
|
338
|
+
| `--verbose` | `-v` | `false` | Enable verbose output (DEBUG logs) |
|
|
339
|
+
| `--quiet` | `-q` | `false` | Suppress output except errors |
|
|
340
|
+
| `--log-level` | | `INFO` | Set logging level |
|
|
341
|
+
| `--version` | | | Show version and exit |
|
|
342
|
+
|
|
343
|
+
<!-- write-good-enable -->
|
|
344
|
+
<!-- markdownlint-enable MD013 -->
|
|
183
345
|
|
|
184
346
|
## How It Works
|
|
185
347
|
|
|
@@ -303,6 +465,77 @@ Example timing for 100 repositories with 50 blocked PRs using 8 workers:
|
|
|
303
465
|
- PR processing: ~20-30 seconds
|
|
304
466
|
- **Total: ~50-90 seconds**
|
|
305
467
|
|
|
468
|
+
### Example 4: Fix Files in a Blocked PR
|
|
469
|
+
|
|
470
|
+
This example removes invalid `type:` definitions from a GitHub composite action:
|
|
471
|
+
|
|
472
|
+
```bash
|
|
473
|
+
pull-request-fixer https://github.com/lfreleng-actions/make-action/pull/40 \
|
|
474
|
+
--fix-files \
|
|
475
|
+
--file-pattern './action.yaml' \
|
|
476
|
+
--search-pattern '^\s+type:\s+\S' \
|
|
477
|
+
--remove-lines \
|
|
478
|
+
--context-start 'inputs:' \
|
|
479
|
+
--context-end 'runs:' \
|
|
480
|
+
--dry-run \
|
|
481
|
+
--show-diff
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
Output:
|
|
485
|
+
|
|
486
|
+
```text
|
|
487
|
+
🔍 Processing PR: https://github.com/lfreleng-actions/make-action/pull/40
|
|
488
|
+
🔧 Will fix: files
|
|
489
|
+
🏃 Dry run mode: the tool will not apply changes
|
|
490
|
+
|
|
491
|
+
📝 Fixing files in PR...
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
✅ Would fix 1 file
|
|
495
|
+
📂 action.yaml
|
|
496
|
+
--- action.yaml
|
|
497
|
+
+++ action.yaml
|
|
498
|
+
@@ -10,7 +10,6 @@
|
|
499
|
+
repository:
|
|
500
|
+
description: 'Remote Git repository URL'
|
|
501
|
+
required: false
|
|
502
|
+
|
|
503
|
+
- type: 'string'
|
|
504
|
+
debug:
|
|
505
|
+
description: 'Enable debug mode'
|
|
506
|
+
required: false
|
|
507
|
+
- type: 'boolean'
|
|
508
|
+
|
|
509
|
+
Dry-run completed!
|
|
510
|
+
|
|
511
|
+
```text
|
|
512
|
+
|
|
513
|
+
Without `--dry-run`, the output would show:
|
|
514
|
+
|
|
515
|
+
```text
|
|
516
|
+
✅ Updated 1 file
|
|
517
|
+
🔀 action.yaml
|
|
518
|
+
--- action.yaml
|
|
519
|
+
+++ action.yaml
|
|
520
|
+
@@ -10,7 +10,6 @@
|
|
521
|
+
repository:
|
|
522
|
+
description: 'Remote Git repository URL'
|
|
523
|
+
required: false
|
|
524
|
+
- type: 'string'
|
|
525
|
+
debug:
|
|
526
|
+
description: 'Enable debug mode'
|
|
527
|
+
required: false
|
|
528
|
+
- type: 'boolean'
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
This would:
|
|
532
|
+
|
|
533
|
+
1. Clone the PR branch
|
|
534
|
+
2. Remove all lines containing `type:` from the `inputs:` section of `action.yaml`
|
|
535
|
+
3. Amend the last commit with the changes
|
|
536
|
+
4. Force-push the updated commit
|
|
537
|
+
5. Add a comment to the PR explaining the fix
|
|
538
|
+
|
|
306
539
|
## Troubleshooting
|
|
307
540
|
|
|
308
541
|
### No PRs Found
|