@webpieces/pr-gate 0.3.288 → 0.3.290
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpieces/pr-gate",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.290",
|
|
4
4
|
"description": "Gated PR system: 3-point squash-merge, merge validation gate, and red/yellow/green PR dashboard. Standalone scripts, no Nx dependency required.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"directory": "packages/tooling/pr-gate"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@webpieces/rules-config": "0.3.
|
|
26
|
+
"@webpieces/rules-config": "0.3.290"
|
|
27
27
|
},
|
|
28
28
|
"publishConfig": {
|
|
29
29
|
"access": "public"
|
|
@@ -2,13 +2,30 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.openPrForBranch = openPrForBranch;
|
|
4
4
|
const child_process_1 = require("child_process");
|
|
5
|
+
const rules_config_1 = require("@webpieces/rules-config");
|
|
5
6
|
const branch_naming_1 = require("./branch-naming");
|
|
7
|
+
const SEP = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n';
|
|
6
8
|
// The open PR (if any) tracking a feature branch, looked up by its STABLE base name (the PR always
|
|
7
|
-
// lives on `base`, never on the numbered generation basewp2/basewp3/…).
|
|
8
|
-
//
|
|
9
|
-
//
|
|
9
|
+
// lives on `base`, never on the numbered generation basewp2/basewp3/…). Returns '' ONLY when GitHub
|
|
10
|
+
// answered and there is genuinely no open PR.
|
|
11
|
+
//
|
|
12
|
+
// This is a HARD GATE, not an advisory hint: it FAILS FAST if `gh` cannot answer (not installed, not
|
|
13
|
+
// authenticated, offline). We must NOT degrade "couldn't ask GitHub" into "no PR" — a 3-point update
|
|
14
|
+
// makes a new branch generation and the existing PR would be left pointing at the OLD branch (stale),
|
|
15
|
+
// so running wp-update-start blind when a PR might exist is exactly the disaster we are guarding
|
|
16
|
+
// against. Refuse rather than guess.
|
|
10
17
|
function openPrForBranch(repoRoot, currentBranch) {
|
|
11
|
-
const
|
|
12
|
-
|
|
18
|
+
const base = (0, branch_naming_1.baseBranchName)(currentBranch);
|
|
19
|
+
const result = (0, child_process_1.spawnSync)('gh', ['pr', 'list', '--head', base, '--state', 'open', '--json', 'number', '--jq', '.[0].number'], { cwd: repoRoot, encoding: 'utf8' });
|
|
20
|
+
if (result.status !== 0) {
|
|
21
|
+
const detail = (result.stderr ?? '').trim() || (result.error ? result.error.message : 'gh exited non-zero');
|
|
22
|
+
throw new rules_config_1.CliExitError(2, '\n' + SEP + '❌ Could not ask GitHub whether an open PR exists for this branch\n' + SEP + '\n' +
|
|
23
|
+
`gh failed for base branch "${base}": ${detail}\n\n` +
|
|
24
|
+
'This check must NOT be skipped: a 3-point update creates a NEW branch generation, so if a\n' +
|
|
25
|
+
'PR already exists, wp-update-start would leave it pointing at the OLD branch. Fix gh first\n' +
|
|
26
|
+
'(install / `gh auth login` / restore network), then re-run — or, if a PR does exist, use\n' +
|
|
27
|
+
'the PR flow: pnpm wp-start-upsert-pr → /wp-merge → pnpm wp-finish-upsert-pr\n');
|
|
28
|
+
}
|
|
29
|
+
return (result.stdout ?? '').trim();
|
|
13
30
|
}
|
|
14
31
|
//# sourceMappingURL=open-pr-check.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open-pr-check.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/pr-gate/src/scripts/workflow/open-pr-check.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"open-pr-check.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/pr-gate/src/scripts/workflow/open-pr-check.ts"],"names":[],"mappings":";;AAeA,0CAkBC;AAjCD,iDAA0C;AAC1C,0DAAuD;AACvD,mDAAiD;AAEjD,MAAM,GAAG,GAAG,0DAA0D,CAAC;AAEvE,mGAAmG;AACnG,oGAAoG;AACpG,8CAA8C;AAC9C,EAAE;AACF,qGAAqG;AACrG,qGAAqG;AACrG,sGAAsG;AACtG,iGAAiG;AACjG,qCAAqC;AACrC,SAAgB,eAAe,CAAC,QAAgB,EAAE,aAAqB;IACnE,MAAM,IAAI,GAAG,IAAA,8BAAc,EAAC,aAAa,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAA,yBAAS,EACpB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,EAClG,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CACtC,CAAC;IACF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;QAC5G,MAAM,IAAI,2BAAY,CAAC,CAAC,EACpB,IAAI,GAAG,GAAG,GAAG,oEAAoE,GAAG,GAAG,GAAG,IAAI;YAC9F,8BAA8B,IAAI,MAAM,MAAM,MAAM;YACpD,6FAA6F;YAC7F,8FAA8F;YAC9F,4FAA4F;YAC5F,+EAA+E,CAClF,CAAC;IACN,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AACxC,CAAC","sourcesContent":["import { spawnSync } from 'child_process';\nimport { CliExitError } from '@webpieces/rules-config';\nimport { baseBranchName } from './branch-naming';\n\nconst SEP = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n';\n\n// The open PR (if any) tracking a feature branch, looked up by its STABLE base name (the PR always\n// lives on `base`, never on the numbered generation basewp2/basewp3/…). Returns '' ONLY when GitHub\n// answered and there is genuinely no open PR.\n//\n// This is a HARD GATE, not an advisory hint: it FAILS FAST if `gh` cannot answer (not installed, not\n// authenticated, offline). We must NOT degrade \"couldn't ask GitHub\" into \"no PR\" — a 3-point update\n// makes a new branch generation and the existing PR would be left pointing at the OLD branch (stale),\n// so running wp-update-start blind when a PR might exist is exactly the disaster we are guarding\n// against. Refuse rather than guess.\nexport function openPrForBranch(repoRoot: string, currentBranch: string): string {\n const base = baseBranchName(currentBranch);\n const result = spawnSync(\n 'gh', ['pr', 'list', '--head', base, '--state', 'open', '--json', 'number', '--jq', '.[0].number'],\n { cwd: repoRoot, encoding: 'utf8' },\n );\n if (result.status !== 0) {\n const detail = (result.stderr ?? '').trim() || (result.error ? result.error.message : 'gh exited non-zero');\n throw new CliExitError(2,\n '\\n' + SEP + '❌ Could not ask GitHub whether an open PR exists for this branch\\n' + SEP + '\\n' +\n `gh failed for base branch \"${base}\": ${detail}\\n\\n` +\n 'This check must NOT be skipped: a 3-point update creates a NEW branch generation, so if a\\n' +\n 'PR already exists, wp-update-start would leave it pointing at the OLD branch. Fix gh first\\n' +\n '(install / `gh auth login` / restore network), then re-run — or, if a PR does exist, use\\n' +\n 'the PR flow: pnpm wp-start-upsert-pr → /wp-merge → pnpm wp-finish-upsert-pr\\n',\n );\n }\n return (result.stdout ?? '').trim();\n}\n"]}
|
|
@@ -13,18 +13,21 @@ const run_update_1 = require("./workflow/run-update");
|
|
|
13
13
|
// on CONFLICT it writes the 3-point context + merge process doc and hands back — you resolve, then
|
|
14
14
|
// run `wp-update-end` to finalize. It NEVER creates a PR (that is the wp-*-upsert-pr flow).
|
|
15
15
|
const SEP = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n';
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
16
|
+
// If a PR is already OPEN for this branch, wp-update-start must refuse. The 3-point update squash-
|
|
17
|
+
// merges onto a NEW branch generation (base → basewp2), and the existing PR stays pinned to the old
|
|
18
|
+
// branch — so running the update-only flow would leave the PR pointing at stale, pre-merge code. The
|
|
19
|
+
// PR flow (wp-start-upsert-pr → wp-finish-upsert-pr) is the ONLY correct path once a PR exists: it
|
|
20
|
+
// re-merges main AND updates the PR. Fail fast and steer there. (openPrForBranch itself fails fast if
|
|
21
|
+
// GitHub can't be reached — we never assume "no PR" when we simply couldn't ask.)
|
|
19
22
|
function assertNoOpenPr(repoRoot) {
|
|
20
23
|
const branch = (0, child_process_1.execSync)('git rev-parse --abbrev-ref HEAD', { cwd: repoRoot, encoding: 'utf8' }).trim();
|
|
21
24
|
const openPr = (0, open_pr_check_1.openPrForBranch)(repoRoot, branch);
|
|
22
25
|
if (openPr === '')
|
|
23
26
|
return;
|
|
24
27
|
throw new rules_config_1.CliExitError(2, '\n' + SEP + `⛔ An open PR (#${openPr}) already tracks this branch\n` + SEP + '\n' +
|
|
25
|
-
'wp-update-start
|
|
26
|
-
`
|
|
27
|
-
'Use the PR flow instead — it merges main AND
|
|
28
|
+
'wp-update-start does a 3-point squash-merge onto a NEW branch generation (base → basewp2),\n' +
|
|
29
|
+
`but PR #${openPr} is pinned to the current branch — so it would be left pointing at stale,\n` +
|
|
30
|
+
'pre-merge code. Use the PR flow instead — it re-merges main AND updates the PR:\n' +
|
|
28
31
|
' 1. pnpm wp-start-upsert-pr\n' +
|
|
29
32
|
' 2. /wp-merge (only if conflicts)\n' +
|
|
30
33
|
' 3. pnpm wp-finish-upsert-pr\n');
|
|
@@ -33,7 +36,8 @@ async function main() {
|
|
|
33
36
|
const repoRoot = (0, child_process_1.execSync)('git rev-parse --show-toplevel', { encoding: 'utf8' }).trim();
|
|
34
37
|
// Refresh the AI-facing workflow doc so it's present + current for any failure message to cite.
|
|
35
38
|
(0, rules_config_1.writeTemplate)(repoRoot, 'webpieces.git-workflow.md');
|
|
36
|
-
// An open PR means the PR flow
|
|
39
|
+
// An open PR means the PR flow must be used — a 3-point update would strand the PR on the old
|
|
40
|
+
// branch generation. Fails fast if GitHub can't be reached (never guesses "no PR").
|
|
37
41
|
assertNoOpenPr(repoRoot);
|
|
38
42
|
const outcome = await (0, run_update_1.runUpdateFromMain)(repoRoot, 'wp-update-start', 'wp-update-end');
|
|
39
43
|
if (outcome === 'conflict') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wp-update-start.js","sourceRoot":"","sources":["../../../../../../packages/tooling/pr-gate/src/scripts/wp-update-start.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"wp-update-start.js","sourceRoot":"","sources":["../../../../../../packages/tooling/pr-gate/src/scripts/wp-update-start.ts"],"names":[],"mappings":";;;AAoBA,wCAaC;AAED,oBAsBC;AAxDD,iDAAyC;AACzC,0DAA+E;AAC/E,4DAA2D;AAC3D,sDAA0D;AAE1D,oGAAoG;AACpG,2FAA2F;AAC3F,sGAAsG;AACtG,mGAAmG;AACnG,4FAA4F;AAE5F,MAAM,GAAG,GAAG,0DAA0D,CAAC;AAEvE,mGAAmG;AACnG,oGAAoG;AACpG,qGAAqG;AACrG,mGAAmG;AACnG,sGAAsG;AACtG,kFAAkF;AAClF,SAAgB,cAAc,CAAC,QAAgB;IAC3C,MAAM,MAAM,GAAG,IAAA,wBAAQ,EAAC,iCAAiC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACvG,MAAM,MAAM,GAAG,IAAA,+BAAe,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjD,IAAI,MAAM,KAAK,EAAE;QAAE,OAAO;IAC1B,MAAM,IAAI,2BAAY,CAAC,CAAC,EACpB,IAAI,GAAG,GAAG,GAAG,kBAAkB,MAAM,gCAAgC,GAAG,GAAG,GAAG,IAAI;QAClF,8FAA8F;QAC9F,WAAW,MAAM,6EAA6E;QAC9F,mFAAmF;QACnF,gCAAgC;QAChC,wCAAwC;QACxC,iCAAiC,CACpC,CAAC;AACN,CAAC;AAEM,KAAK,UAAU,IAAI;IACtB,MAAM,QAAQ,GAAG,IAAA,wBAAQ,EAAC,+BAA+B,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACxF,gGAAgG;IAChG,IAAA,4BAAa,EAAC,QAAQ,EAAE,2BAA2B,CAAC,CAAC;IAErD,8FAA8F;IAC9F,oFAAoF;IACpF,cAAc,CAAC,QAAQ,CAAC,CAAC;IAEzB,MAAM,OAAO,GAAG,MAAM,IAAA,8BAAiB,EAAC,QAAQ,EAAE,iBAAiB,EAAE,eAAe,CAAC,CAAC;IACtF,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QACzB,4FAA4F;QAC5F,MAAM,IAAI,2BAAY,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;IACD,IAAI,OAAO,KAAK,mBAAmB,EAAE,CAAC;QAClC,MAAM,IAAI,2BAAY,CAAC,CAAC,EACpB,IAAI,GAAG,GAAG,GAAG,6CAA6C,GAAG,GAAG,GAAG,IAAI;YACvE,kEAAkE;YAClE,wBAAwB,CAC3B,CAAC;IACN,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;AAC5F,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM;IAAE,IAAA,sBAAO,EAAC,IAAI,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { execSync } from 'child_process';\nimport { writeTemplate, CliExitError, runMain } from '@webpieces/rules-config';\nimport { openPrForBranch } from './workflow/open-pr-check';\nimport { runUpdateFromMain } from './workflow/run-update';\n\n// wp-update-start: the \"sync this feature branch from main\" entry point (the redirect target of the\n// redirect-how-to-merge-main guard). It runs the FULL 3-point squash-update via the shared\n// runUpdateFromMain engine: on a CLEAN merge it finalizes everything (no need to call wp-update-end);\n// on CONFLICT it writes the 3-point context + merge process doc and hands back — you resolve, then\n// run `wp-update-end` to finalize. It NEVER creates a PR (that is the wp-*-upsert-pr flow).\n\nconst SEP = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n';\n\n// If a PR is already OPEN for this branch, wp-update-start must refuse. The 3-point update squash-\n// merges onto a NEW branch generation (base → basewp2), and the existing PR stays pinned to the old\n// branch — so running the update-only flow would leave the PR pointing at stale, pre-merge code. The\n// PR flow (wp-start-upsert-pr → wp-finish-upsert-pr) is the ONLY correct path once a PR exists: it\n// re-merges main AND updates the PR. Fail fast and steer there. (openPrForBranch itself fails fast if\n// GitHub can't be reached — we never assume \"no PR\" when we simply couldn't ask.)\nexport function assertNoOpenPr(repoRoot: string): void {\n const branch = execSync('git rev-parse --abbrev-ref HEAD', { cwd: repoRoot, encoding: 'utf8' }).trim();\n const openPr = openPrForBranch(repoRoot, branch);\n if (openPr === '') return;\n throw new CliExitError(2,\n '\\n' + SEP + `⛔ An open PR (#${openPr}) already tracks this branch\\n` + SEP + '\\n' +\n 'wp-update-start does a 3-point squash-merge onto a NEW branch generation (base → basewp2),\\n' +\n `but PR #${openPr} is pinned to the current branch — so it would be left pointing at stale,\\n` +\n 'pre-merge code. Use the PR flow instead — it re-merges main AND updates the PR:\\n' +\n ' 1. pnpm wp-start-upsert-pr\\n' +\n ' 2. /wp-merge (only if conflicts)\\n' +\n ' 3. pnpm wp-finish-upsert-pr\\n',\n );\n}\n\nexport async function main(): Promise<void> {\n const repoRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf8' }).trim();\n // Refresh the AI-facing workflow doc so it's present + current for any failure message to cite.\n writeTemplate(repoRoot, 'webpieces.git-workflow.md');\n\n // An open PR means the PR flow must be used — a 3-point update would strand the PR on the old\n // branch generation. Fails fast if GitHub can't be reached (never guesses \"no PR\").\n assertNoOpenPr(repoRoot);\n\n const outcome = await runUpdateFromMain(repoRoot, 'wp-update-start', 'wp-update-end');\n if (outcome === 'conflict') {\n // Context + marker + merge process doc already written by merge-start; hand back to the AI.\n throw new CliExitError(2, '');\n }\n if (outcome === 'unvalidatedResume') {\n throw new CliExitError(1,\n '\\n' + SEP + '⏸️ Merge in progress — not yet validated\\n' + SEP + '\\n' +\n 'Resolve the remaining conflicts in the working tree, then run:\\n' +\n ' pnpm wp-update-end\\n',\n );\n }\n process.stdout.write('\\n✅ Updated from main — clean. No need to call wp-update-end.\\n');\n}\n\nif (require.main === module) runMain(main);\n"]}
|