split-by-codeowners 1.0.4 → 1.1.0
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.
- package/README.md +55 -30
- package/action.yml +6 -1
- package/dist/index.js +161 -151
- package/dist/index.js.map +1 -1
- package/dist-cli/index.js +158 -157
- package/dist-cli/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,7 +32,6 @@ steps:
|
|
|
32
32
|
- name: Split into CODEOWNERS PRs
|
|
33
33
|
uses: anatoliisf/split-by-codeowners@v1
|
|
34
34
|
with:
|
|
35
|
-
create_prs: "true"
|
|
36
35
|
github_token: ${{ github.token }}
|
|
37
36
|
```
|
|
38
37
|
|
|
@@ -55,34 +54,35 @@ npx split-by-codeowners --create-prs --base-branch main
|
|
|
55
54
|
|
|
56
55
|
### Inputs
|
|
57
56
|
|
|
58
|
-
| Name
|
|
59
|
-
|
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
65
|
-
| `
|
|
66
|
-
| `
|
|
67
|
-
| `
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
70
|
-
| `
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
73
|
-
| `
|
|
74
|
-
| `
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
57
|
+
| Name | Required | Default | Description |
|
|
58
|
+
| -------------------- | -------- | ------------------------------------- | ----------------------------------------------------------------------------- |
|
|
59
|
+
| `repo_path` | no | `.` | Repo root path relative to `GITHUB_WORKSPACE` |
|
|
60
|
+
| `codeowners_path` | no | `CODEOWNERS` | Path to CODEOWNERS file |
|
|
61
|
+
| `base_ref` | no | `""` | Base ref for changed-files discovery (currently workspace-focused; see notes) |
|
|
62
|
+
| `include_unowned` | no | `"true"` | Include files with no owners in a special bucket |
|
|
63
|
+
| `unowned_bucket_key` | no | `__UNOWNED__` | Bucket key for unowned files |
|
|
64
|
+
| `max_buckets` | no | `"30"` | Fail if buckets exceed this number |
|
|
65
|
+
| `exclude_patterns` | no | `""` | Newline-separated glob patterns to exclude (minimatch) |
|
|
66
|
+
| `patch_dir` | no | `bucket-patches` | Directory to write per-bucket patch files |
|
|
67
|
+
| `bucket_prefix` | no | `bucket` | Patch file prefix |
|
|
68
|
+
| `dry_run` | no | `"false"` | Compute buckets but don’t write patches |
|
|
69
|
+
| `cleanup_patches` | no | `"false"` | Delete `patch_dir` after a successful run |
|
|
70
|
+
| `create_prs` | no | `"true"` | Create/update one PR per bucket |
|
|
71
|
+
| `github_token` | no | `""` | Token used for pushing branches + GitHub API (defaults to env `GITHUB_TOKEN`) |
|
|
72
|
+
| `base_branch` | no | `""` | Base branch for PRs (defaults to repo default branch) |
|
|
73
|
+
| `branch_prefix` | no | `codemods/` | Prefix for created branches |
|
|
74
|
+
| `commit_message` | no | `chore: automated changes` | Commit message for bucket PRs |
|
|
75
|
+
| `pr_title` | no | `chore: automated changes ({owners})` | PR title template (`{owners}`, `{bucket_key}`) |
|
|
76
|
+
| `pr_body` | no | *(see `action.yml`)* | PR body template (`{owners}`, `{bucket_key}`, `{files}`) |
|
|
77
|
+
| `draft` | no | `"false"` | Create PRs as drafts |
|
|
78
78
|
|
|
79
79
|
### Outputs
|
|
80
80
|
|
|
81
|
-
| Name
|
|
82
|
-
|
|
|
83
|
-
| `matrix_json`
|
|
81
|
+
| Name | Description |
|
|
82
|
+
| -------------- | ------------------------------------------------- |
|
|
83
|
+
| `matrix_json` | JSON for `strategy.matrix` (`{ include: [...] }`) |
|
|
84
84
|
| `buckets_json` | Full buckets JSON (owners + files + matched rule) |
|
|
85
|
-
| `prs_json`
|
|
85
|
+
| `prs_json` | If `create_prs=true`, list of created/updated PRs |
|
|
86
86
|
|
|
87
87
|
### Example: bucketize only (matrix + patches)
|
|
88
88
|
|
|
@@ -91,7 +91,7 @@ npx split-by-codeowners --create-prs --base-branch main
|
|
|
91
91
|
id: split
|
|
92
92
|
uses: anatoliisf/split-by-codeowners@v1
|
|
93
93
|
with:
|
|
94
|
-
|
|
94
|
+
draft: "true"
|
|
95
95
|
|
|
96
96
|
- name: Use matrix
|
|
97
97
|
run: echo '${{ steps.split.outputs.matrix_json }}'
|
|
@@ -117,6 +117,33 @@ The CLI operates on your **current working tree** (modified + untracked files) a
|
|
|
117
117
|
npx split-by-codeowners --help
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
+
### Options
|
|
121
|
+
|
|
122
|
+
#### Common
|
|
123
|
+
|
|
124
|
+
- **`--repo-path <path>`**: Repo root path (relative to current working directory)
|
|
125
|
+
- **`--codeowners <path>`**: Path to CODEOWNERS file (default: `CODEOWNERS`)
|
|
126
|
+
- **`--exclude <file|->`**: File containing newline-separated glob patterns to exclude, or `-` to read from stdin
|
|
127
|
+
- **`--include-unowned <true|false>`**: Include files with no owners in an `__UNOWNED__` bucket (default: `true`)
|
|
128
|
+
- **`--unowned-bucket-key <key>`**: Bucket key for unowned files (default: `__UNOWNED__`)
|
|
129
|
+
- **`--max-buckets <n>`**: Fail if number of buckets exceeds `n` (default: `30`)
|
|
130
|
+
- **`--patch-dir <dir>`**: Directory to write patch files (default: `bucket-patches`)
|
|
131
|
+
- **`--bucket-prefix <prefix>`**: Patch file prefix (default: `bucket`)
|
|
132
|
+
- **`--dry-run`**: Compute buckets but don’t write patches
|
|
133
|
+
- **`--cleanup-patches`**: Delete `patch_dir` after a successful run (default in this repo: enabled)
|
|
134
|
+
|
|
135
|
+
#### PR creation
|
|
136
|
+
|
|
137
|
+
- **`--create-prs`**: Create/update one PR per bucket (local: uses `gh` auth)
|
|
138
|
+
- **`--base-branch <branch>`**: Base branch for PRs (default: repo default branch)
|
|
139
|
+
- **`--branch-prefix <prefix>`**: Branch prefix for bucket branches (default: `codemods/`)
|
|
140
|
+
- **`--commit-message <msg>`**: Commit message for bucket commits
|
|
141
|
+
- **`--pr-title <tpl>`**: Title template (supports `{owners}`, `{bucket_key}`)
|
|
142
|
+
- **`--pr-body <tpl>`**: Body template (supports `{owners}`, `{bucket_key}`, `{files}`)
|
|
143
|
+
- **`--pr-body-mode <mode>`**: `custom|template|template_with_bucket|none`
|
|
144
|
+
- **`--pr-template-path <path>`**: PR template file path (used when `pr_body_mode=template*`)
|
|
145
|
+
- **`--draft <true|false>`**: Create PRs as drafts (default: `false`)
|
|
146
|
+
|
|
120
147
|
### Common examples
|
|
121
148
|
|
|
122
149
|
Exclude some paths:
|
|
@@ -131,11 +158,10 @@ Create/update PRs:
|
|
|
131
158
|
npx split-by-codeowners --create-prs --base-branch main
|
|
132
159
|
```
|
|
133
160
|
|
|
134
|
-
|
|
161
|
+
Use the repo PR template for PR creation (recommended):
|
|
135
162
|
|
|
136
163
|
```bash
|
|
137
|
-
|
|
138
|
-
npx split-by-codeowners --create-prs --token "$GH_TOKEN" --base-branch main
|
|
164
|
+
npx split-by-codeowners --create-prs --pr-body-mode template_with_bucket
|
|
139
165
|
```
|
|
140
166
|
|
|
141
167
|
### Notes on local PR creation
|
|
@@ -176,6 +202,5 @@ npm run build
|
|
|
176
202
|
|
|
177
203
|
This repo includes a manual workflow: `.github/workflows/publish-npm.yml`.
|
|
178
204
|
|
|
179
|
-
- Create an npm token with publish rights and add it as repo secret **`NPM_TOKEN`**.
|
|
180
205
|
- Bump `package.json` version and ensure `dist/` and `dist-cli/` are up to date.
|
|
181
206
|
- Run the workflow from the GitHub Actions UI (`workflow_dispatch`).
|
package/action.yml
CHANGED
|
@@ -6,6 +6,11 @@ branding:
|
|
|
6
6
|
color: "blue"
|
|
7
7
|
|
|
8
8
|
inputs:
|
|
9
|
+
repo_path:
|
|
10
|
+
description: "Relative path under GITHUB_WORKSPACE to the repo root."
|
|
11
|
+
required: false
|
|
12
|
+
default: "."
|
|
13
|
+
|
|
9
14
|
codeowners_path:
|
|
10
15
|
description: "Path to CODEOWNERS. Defaults to CODEOWNERS at repo root."
|
|
11
16
|
required: false
|
|
@@ -59,7 +64,7 @@ inputs:
|
|
|
59
64
|
create_prs:
|
|
60
65
|
description: "If true, create/update one PR per bucket by pushing branches and calling GitHub API."
|
|
61
66
|
required: false
|
|
62
|
-
default: "
|
|
67
|
+
default: "true"
|
|
63
68
|
|
|
64
69
|
github_token:
|
|
65
70
|
description: "GitHub token used for API + pushing branches. Defaults to GITHUB_TOKEN."
|
package/dist/index.js
CHANGED
|
@@ -27482,134 +27482,140 @@ function ensureDirExists(dir) {
|
|
|
27482
27482
|
(0, buckets_1.ensureDir)(dir);
|
|
27483
27483
|
}
|
|
27484
27484
|
async function runSplit(config, logger) {
|
|
27485
|
-
|
|
27486
|
-
|
|
27487
|
-
|
|
27488
|
-
|
|
27489
|
-
|
|
27490
|
-
|
|
27491
|
-
logger.info(`Changed files: ${changed.length} (after excludes: ${filtered.length})`);
|
|
27492
|
-
if (!filtered.length) {
|
|
27493
|
-
return { buckets: [], matrix: { include: [] }, prs: [] };
|
|
27494
|
-
}
|
|
27495
|
-
// 2) parse CODEOWNERS + bucketize by owners-set
|
|
27496
|
-
const rules = (0, codeowners_1.parseCodeowners)(config.codeownersPath);
|
|
27497
|
-
const bucketsMap = new Map();
|
|
27498
|
-
for (const file of filtered) {
|
|
27499
|
-
const { owners, rule } = (0, codeowners_1.ownersForFile)(file, rules);
|
|
27500
|
-
const sortedOwners = (owners ?? []).slice().sort();
|
|
27501
|
-
const isUnowned = sortedOwners.length === 0;
|
|
27502
|
-
if (isUnowned && !config.includeUnowned)
|
|
27503
|
-
continue;
|
|
27504
|
-
const key = isUnowned
|
|
27505
|
-
? config.unownedBucketKey
|
|
27506
|
-
: sortedOwners.join("|").replaceAll("@", "").replaceAll("/", "-").replaceAll(" ", "");
|
|
27507
|
-
const existing = bucketsMap.get(key);
|
|
27508
|
-
if (!existing) {
|
|
27509
|
-
bucketsMap.set(key, {
|
|
27510
|
-
key,
|
|
27511
|
-
owners: sortedOwners,
|
|
27512
|
-
files: [{ file, owners: sortedOwners, rule }]
|
|
27513
|
-
});
|
|
27514
|
-
}
|
|
27515
|
-
else {
|
|
27516
|
-
existing.files.push({ file, owners: sortedOwners, rule });
|
|
27485
|
+
const originalCwd = process.cwd();
|
|
27486
|
+
let resolvedRepoPath;
|
|
27487
|
+
if (config.repoPath) {
|
|
27488
|
+
resolvedRepoPath = node_path_1.default.resolve(originalCwd, config.repoPath);
|
|
27489
|
+
if (!node_fs_1.default.existsSync(resolvedRepoPath)) {
|
|
27490
|
+
throw new Error(`repo_path does not exist: ${resolvedRepoPath}`);
|
|
27517
27491
|
}
|
|
27492
|
+
process.chdir(resolvedRepoPath);
|
|
27493
|
+
logger.info(`Using repo_path: ${resolvedRepoPath}`);
|
|
27518
27494
|
}
|
|
27519
|
-
|
|
27520
|
-
|
|
27521
|
-
|
|
27522
|
-
|
|
27523
|
-
|
|
27524
|
-
|
|
27525
|
-
|
|
27526
|
-
|
|
27527
|
-
|
|
27528
|
-
|
|
27529
|
-
|
|
27530
|
-
|
|
27531
|
-
|
|
27532
|
-
|
|
27533
|
-
|
|
27534
|
-
|
|
27535
|
-
|
|
27536
|
-
|
|
27537
|
-
|
|
27538
|
-
|
|
27539
|
-
|
|
27540
|
-
|
|
27541
|
-
|
|
27542
|
-
|
|
27543
|
-
|
|
27544
|
-
|
|
27545
|
-
|
|
27546
|
-
|
|
27547
|
-
|
|
27548
|
-
|
|
27549
|
-
let useGhCli = !isGitHubActions;
|
|
27550
|
-
let octokit = useGhCli ? null : (0, github_1.getOctokit)(token);
|
|
27551
|
-
let baseBranch;
|
|
27552
|
-
if (useGhCli) {
|
|
27553
|
-
try {
|
|
27554
|
-
const cwd = process.cwd();
|
|
27555
|
-
(0, ghcli_1.assertGhAuthenticated)(cwd);
|
|
27556
|
-
baseBranch = config.baseBranch || (0, ghcli_1.getDefaultBranchViaGh)(cwd);
|
|
27495
|
+
try {
|
|
27496
|
+
if (config.createPrs && config.dryRun) {
|
|
27497
|
+
throw new Error("create_prs=true requires dry_run=false (we need patch files to create bucket branches/PRs).");
|
|
27498
|
+
}
|
|
27499
|
+
// 1) discover + filter changed files
|
|
27500
|
+
const changed = (0, git_1.getChangedFiles)(config.baseRef);
|
|
27501
|
+
const filtered = (0, buckets_1.applyExcludes)(changed, config.excludePatterns);
|
|
27502
|
+
logger.info(`Changed files: ${changed.length} (after excludes: ${filtered.length})`);
|
|
27503
|
+
if (!filtered.length) {
|
|
27504
|
+
return { buckets: [], matrix: { include: [] }, prs: [] };
|
|
27505
|
+
}
|
|
27506
|
+
// 2) parse CODEOWNERS + bucketize by owners-set
|
|
27507
|
+
const rules = (0, codeowners_1.parseCodeowners)(config.codeownersPath);
|
|
27508
|
+
const bucketsMap = new Map();
|
|
27509
|
+
for (const file of filtered) {
|
|
27510
|
+
const { owners, rule } = (0, codeowners_1.ownersForFile)(file, rules);
|
|
27511
|
+
const sortedOwners = (owners ?? []).slice().sort();
|
|
27512
|
+
const isUnowned = sortedOwners.length === 0;
|
|
27513
|
+
if (isUnowned && !config.includeUnowned)
|
|
27514
|
+
continue;
|
|
27515
|
+
const key = isUnowned
|
|
27516
|
+
? config.unownedBucketKey
|
|
27517
|
+
: sortedOwners.join("|").replaceAll("@", "").replaceAll("/", "-").replaceAll(" ", "");
|
|
27518
|
+
const existing = bucketsMap.get(key);
|
|
27519
|
+
if (!existing) {
|
|
27520
|
+
bucketsMap.set(key, {
|
|
27521
|
+
key,
|
|
27522
|
+
owners: sortedOwners,
|
|
27523
|
+
files: [{ file, owners: sortedOwners, rule }]
|
|
27524
|
+
});
|
|
27557
27525
|
}
|
|
27558
|
-
|
|
27559
|
-
|
|
27560
|
-
logger.warn("gh is not authenticated; falling back to token auth.");
|
|
27561
|
-
useGhCli = false;
|
|
27562
|
-
octokit = (0, github_1.getOctokit)(token);
|
|
27563
|
-
baseBranch = config.baseBranch || (await (0, github_1.getDefaultBranch)(octokit, repo));
|
|
27564
|
-
}
|
|
27565
|
-
else {
|
|
27566
|
-
throw e;
|
|
27567
|
-
}
|
|
27526
|
+
else {
|
|
27527
|
+
existing.files.push({ file, owners: sortedOwners, rule });
|
|
27568
27528
|
}
|
|
27569
27529
|
}
|
|
27530
|
+
const buckets = [...bucketsMap.values()].sort((a, b) => a.key.localeCompare(b.key));
|
|
27531
|
+
if (buckets.length > config.maxBuckets) {
|
|
27532
|
+
throw new Error(`Too many buckets: ${buckets.length} > max_buckets=${config.maxBuckets}`);
|
|
27533
|
+
}
|
|
27534
|
+
// 3) write per-bucket patches
|
|
27535
|
+
if (!config.dryRun) {
|
|
27536
|
+
ensureDirExists(config.patchDir);
|
|
27537
|
+
buckets.forEach((b, idx) => {
|
|
27538
|
+
const patchPath = node_path_1.default.posix.join(config.patchDir.replaceAll("\\", "/"), `${config.bucketPrefix}-${idx + 1}.patch`);
|
|
27539
|
+
const paths = b.files.map((f) => f.file);
|
|
27540
|
+
logger.info(`Writing ${patchPath} (${paths.length} files) for bucket=${b.key}`);
|
|
27541
|
+
(0, git_1.writePatchForPaths)(patchPath, paths);
|
|
27542
|
+
});
|
|
27543
|
+
}
|
|
27570
27544
|
else {
|
|
27571
|
-
|
|
27572
|
-
}
|
|
27573
|
-
const
|
|
27574
|
-
|
|
27575
|
-
prs =
|
|
27576
|
-
|
|
27577
|
-
const
|
|
27578
|
-
const
|
|
27579
|
-
const
|
|
27580
|
-
|
|
27581
|
-
|
|
27582
|
-
|
|
27583
|
-
|
|
27584
|
-
(
|
|
27585
|
-
|
|
27586
|
-
if (!committed) {
|
|
27587
|
-
logger.warn(`No staged changes for bucket=${b.key}; skipping push/PR.`);
|
|
27588
|
-
continue;
|
|
27589
|
-
}
|
|
27590
|
-
(0, git_1.pushBranch)(config.remoteName, branch, worktreeDir);
|
|
27591
|
-
const ownersStr = b.owners.length ? b.owners.join(", ") : "(unowned)";
|
|
27592
|
-
const filesStr = b.files.map(f => `- ${f.file}`).join("\n");
|
|
27593
|
-
const bucketInfo = formatTemplate("Automated changes bucketed by CODEOWNERS.\n\nOwners: {owners}\nBucket key: {bucket_key}\n\nFiles:\n{files}\n", { owners: ownersStr, bucket_key: b.key, files: filesStr });
|
|
27594
|
-
const title = formatTemplate(config.prTitle, { owners: ownersStr, bucket_key: b.key });
|
|
27595
|
-
let body;
|
|
27596
|
-
if (config.prBodyMode === "none") {
|
|
27597
|
-
body = undefined;
|
|
27598
|
-
}
|
|
27599
|
-
else if (config.prBodyMode === "custom") {
|
|
27600
|
-
body = formatTemplate(config.prBody, { owners: ownersStr, bucket_key: b.key, files: filesStr });
|
|
27601
|
-
}
|
|
27602
|
-
else {
|
|
27603
|
-
const template = (0, pr_template_1.readPrTemplate)(worktreeDir, config.prTemplatePath) ?? "";
|
|
27604
|
-
body =
|
|
27605
|
-
config.prBodyMode === "template_with_bucket"
|
|
27606
|
-
? (template ? template.trimEnd() + "\n\n---\n\n" + bucketInfo : bucketInfo)
|
|
27607
|
-
: (template || bucketInfo);
|
|
27545
|
+
logger.info("dry_run=true; not generating patches.");
|
|
27546
|
+
}
|
|
27547
|
+
const matrix = (0, buckets_1.toMatrix)(buckets, config.patchDir, config.bucketPrefix);
|
|
27548
|
+
// 4) optionally create PRs (worktrees so we don't disturb the current working tree)
|
|
27549
|
+
let prs = undefined;
|
|
27550
|
+
if (config.createPrs) {
|
|
27551
|
+
const token = config.githubToken || process.env.GITHUB_TOKEN || process.env.GH_TOKEN || "";
|
|
27552
|
+
const repo = config.repo ?? (0, git_1.parseGitHubRemote)((0, git_1.getRemoteUrl)(config.remoteName));
|
|
27553
|
+
const isGitHubActions = process.env.GITHUB_ACTIONS === "true";
|
|
27554
|
+
// Auth mode selection:
|
|
27555
|
+
// - In GitHub Actions: ALWAYS use token-based API (gh may not be installed/auth'd).
|
|
27556
|
+
// - Locally: ALWAYS use gh CLI for best DevX (no token-based local mode).
|
|
27557
|
+
if (isGitHubActions) {
|
|
27558
|
+
if (!token) {
|
|
27559
|
+
throw new Error("Missing GitHub token (set github_token input or GITHUB_TOKEN / GH_TOKEN env var)");
|
|
27608
27560
|
}
|
|
27609
|
-
|
|
27610
|
-
|
|
27611
|
-
|
|
27612
|
-
|
|
27561
|
+
}
|
|
27562
|
+
else {
|
|
27563
|
+
(0, ghcli_1.assertGhAuthenticated)(process.cwd());
|
|
27564
|
+
}
|
|
27565
|
+
const useGhCli = !isGitHubActions;
|
|
27566
|
+
const octokit = useGhCli ? null : (0, github_1.getOctokit)(token);
|
|
27567
|
+
const baseBranch = config.baseBranch || (useGhCli ? (0, ghcli_1.getDefaultBranchViaGh)(process.cwd()) : await (0, github_1.getDefaultBranch)(octokit, repo));
|
|
27568
|
+
const baseRef = "HEAD";
|
|
27569
|
+
ensureDirExists((0, git_1.worktreeBaseDir)());
|
|
27570
|
+
prs = [];
|
|
27571
|
+
for (let i = 0; i < buckets.length; i++) {
|
|
27572
|
+
const b = buckets[i];
|
|
27573
|
+
const patchPath = node_path_1.default.posix.join(config.patchDir.replaceAll("\\", "/"), `${config.bucketPrefix}-${i + 1}.patch`);
|
|
27574
|
+
const branch = `${config.branchPrefix}${b.key}`.replaceAll(" ", "");
|
|
27575
|
+
const worktreeDir = (0, git_1.tempDirForBucket)(b.key);
|
|
27576
|
+
logger.info(`Creating PR for bucket=${b.key} on branch=${branch}`);
|
|
27577
|
+
(0, git_1.worktreeAdd)(branch, baseRef, worktreeDir);
|
|
27578
|
+
try {
|
|
27579
|
+
(0, git_1.applyPatch)(patchPath, worktreeDir);
|
|
27580
|
+
const committed = (0, git_1.commitAllStaged)(config.commitMessage, worktreeDir);
|
|
27581
|
+
if (!committed) {
|
|
27582
|
+
logger.warn(`No staged changes for bucket=${b.key}; skipping push/PR.`);
|
|
27583
|
+
continue;
|
|
27584
|
+
}
|
|
27585
|
+
(0, git_1.pushBranch)(config.remoteName, branch, worktreeDir);
|
|
27586
|
+
const ownersStr = b.owners.length ? b.owners.join(", ") : "(unowned)";
|
|
27587
|
+
const filesStr = b.files.map(f => `- ${f.file}`).join("\n");
|
|
27588
|
+
const bucketInfo = formatTemplate("Automated changes bucketed by CODEOWNERS.\n\nOwners: {owners}\nBucket key: {bucket_key}\n\nFiles:\n{files}\n", { owners: ownersStr, bucket_key: b.key, files: filesStr });
|
|
27589
|
+
const title = formatTemplate(config.prTitle, { owners: ownersStr, bucket_key: b.key });
|
|
27590
|
+
let body;
|
|
27591
|
+
if (config.prBodyMode === "none") {
|
|
27592
|
+
body = undefined;
|
|
27593
|
+
}
|
|
27594
|
+
else if (config.prBodyMode === "custom") {
|
|
27595
|
+
body = formatTemplate(config.prBody, { owners: ownersStr, bucket_key: b.key, files: filesStr });
|
|
27596
|
+
}
|
|
27597
|
+
else {
|
|
27598
|
+
const template = (0, pr_template_1.readPrTemplate)(worktreeDir, config.prTemplatePath) ?? "";
|
|
27599
|
+
body =
|
|
27600
|
+
config.prBodyMode === "template_with_bucket"
|
|
27601
|
+
? (template ? template.trimEnd() + "\n\n---\n\n" + bucketInfo : bucketInfo)
|
|
27602
|
+
: (template || bucketInfo);
|
|
27603
|
+
}
|
|
27604
|
+
const pr = useGhCli
|
|
27605
|
+
? (() => {
|
|
27606
|
+
return (0, ghcli_1.upsertPullRequestViaGh)({
|
|
27607
|
+
cwd: worktreeDir,
|
|
27608
|
+
base: baseBranch,
|
|
27609
|
+
head: branch,
|
|
27610
|
+
title,
|
|
27611
|
+
body: body ?? "",
|
|
27612
|
+
draft: config.draft,
|
|
27613
|
+
bucketKey: b.key
|
|
27614
|
+
});
|
|
27615
|
+
})()
|
|
27616
|
+
: await (0, github_1.upsertPullRequest)({
|
|
27617
|
+
octokit: octokit,
|
|
27618
|
+
repo,
|
|
27613
27619
|
base: baseBranch,
|
|
27614
27620
|
head: branch,
|
|
27615
27621
|
title,
|
|
@@ -27617,41 +27623,35 @@ async function runSplit(config, logger) {
|
|
|
27617
27623
|
draft: config.draft,
|
|
27618
27624
|
bucketKey: b.key
|
|
27619
27625
|
});
|
|
27620
|
-
|
|
27621
|
-
:
|
|
27622
|
-
|
|
27623
|
-
|
|
27624
|
-
|
|
27625
|
-
|
|
27626
|
-
|
|
27627
|
-
|
|
27628
|
-
|
|
27629
|
-
|
|
27630
|
-
|
|
27631
|
-
|
|
27632
|
-
|
|
27626
|
+
prs.push(pr);
|
|
27627
|
+
logger.info(`PR: ${pr.url}`);
|
|
27628
|
+
}
|
|
27629
|
+
finally {
|
|
27630
|
+
(0, git_1.worktreeRemove)(worktreeDir);
|
|
27631
|
+
}
|
|
27632
|
+
}
|
|
27633
|
+
}
|
|
27634
|
+
if (config.cleanupPatches && !config.dryRun) {
|
|
27635
|
+
const cwd = process.cwd();
|
|
27636
|
+
const abs = node_path_1.default.resolve(cwd, config.patchDir);
|
|
27637
|
+
const safePrefix = cwd.endsWith(node_path_1.default.sep) ? cwd : cwd + node_path_1.default.sep;
|
|
27638
|
+
if (!abs.startsWith(safePrefix)) {
|
|
27639
|
+
throw new Error(`Refusing to delete patch_dir outside repo: ${abs}`);
|
|
27640
|
+
}
|
|
27641
|
+
if (abs === cwd) {
|
|
27642
|
+
throw new Error("Refusing to delete patch_dir equal to repo root.");
|
|
27633
27643
|
}
|
|
27634
|
-
|
|
27635
|
-
(
|
|
27644
|
+
if (node_fs_1.default.existsSync(abs)) {
|
|
27645
|
+
logger.info(`Cleaning up patches dir: ${config.patchDir}`);
|
|
27646
|
+
node_fs_1.default.rmSync(abs, { recursive: true, force: true });
|
|
27636
27647
|
}
|
|
27637
27648
|
}
|
|
27649
|
+
return { buckets, matrix, prs };
|
|
27638
27650
|
}
|
|
27639
|
-
|
|
27640
|
-
|
|
27641
|
-
|
|
27642
|
-
const safePrefix = cwd.endsWith(node_path_1.default.sep) ? cwd : cwd + node_path_1.default.sep;
|
|
27643
|
-
if (!abs.startsWith(safePrefix)) {
|
|
27644
|
-
throw new Error(`Refusing to delete patch_dir outside repo: ${abs}`);
|
|
27645
|
-
}
|
|
27646
|
-
if (abs === cwd) {
|
|
27647
|
-
throw new Error("Refusing to delete patch_dir equal to repo root.");
|
|
27648
|
-
}
|
|
27649
|
-
if (node_fs_1.default.existsSync(abs)) {
|
|
27650
|
-
logger.info(`Cleaning up patches dir: ${config.patchDir}`);
|
|
27651
|
-
node_fs_1.default.rmSync(abs, { recursive: true, force: true });
|
|
27652
|
-
}
|
|
27651
|
+
finally {
|
|
27652
|
+
if (resolvedRepoPath)
|
|
27653
|
+
process.chdir(originalCwd);
|
|
27653
27654
|
}
|
|
27654
|
-
return { buckets, matrix, prs };
|
|
27655
27655
|
}
|
|
27656
27656
|
|
|
27657
27657
|
|
|
@@ -28172,13 +28172,23 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
28172
28172
|
return result;
|
|
28173
28173
|
};
|
|
28174
28174
|
})();
|
|
28175
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
28176
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
28177
|
+
};
|
|
28175
28178
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
28176
28179
|
const core = __importStar(__nccwpck_require__(7484));
|
|
28180
|
+
const node_path_1 = __importDefault(__nccwpck_require__(6760));
|
|
28177
28181
|
const buckets_1 = __nccwpck_require__(4140);
|
|
28178
28182
|
const app_1 = __nccwpck_require__(168);
|
|
28179
28183
|
async function run() {
|
|
28180
28184
|
try {
|
|
28185
|
+
const repoPathInput = core.getInput("repo_path") || ".";
|
|
28186
|
+
const workspace = process.env.GITHUB_WORKSPACE || "";
|
|
28187
|
+
const repoPath = repoPathInput
|
|
28188
|
+
? (node_path_1.default.isAbsolute(repoPathInput) ? repoPathInput : node_path_1.default.resolve(workspace || process.cwd(), repoPathInput))
|
|
28189
|
+
: undefined;
|
|
28181
28190
|
const cfg = {
|
|
28191
|
+
repoPath,
|
|
28182
28192
|
codeownersPath: core.getInput("codeowners_path") || "CODEOWNERS",
|
|
28183
28193
|
baseRef: core.getInput("base_ref") || "",
|
|
28184
28194
|
includeUnowned: (0, buckets_1.parseBool)(core.getInput("include_unowned")),
|