fix(permission-gate): guard release-* branch and v* tag pushes (deploy convention)

Deploy convention at M.Video: a release-* branch push deploys to stage and a
v* tag push deploys to PROD. The old guard only matched release/* (slash) and
never caught tag pushes, so a prod deploy could run unconfirmed.

- permission-gate: match main/master, release-[-/], --tags/--follow-tags, and
  whitespace-preceded v<digit> tags; false-positive-safe (space discriminator)
- create-mr.sh: refuse source branch release-* (not just release/*)
- jira-workflow doc updated to release-*

Verified with a behavioral test suite (10 cases incl. v2, false-positive checks).
This commit is contained in:
dev
2026-07-16 13:13:35 +03:00
parent e98e4ca9ae
commit 6521d9c431
3 changed files with 9 additions and 7 deletions
+6 -4
View File
@@ -22,10 +22,12 @@ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
const DANGEROUS_PATTERNS: Array<{ re: RegExp; reason: string }> = [
{ re: /\brm\s+(-\w*r\w*f|-\w*f\w*r|--recursive)/i, reason: "recursive force delete (rm -rf)" },
{ re: /\bgit\s+push\b[^\n]*(--force\b|--force-with-lease\b|\s-f\b)/i, reason: "force push" },
{
re: /\bgit\s+push\b[^\n]*\b(main|master|release\/[^\s]+)\b/i,
reason: "push to a protected branch (main/master/release/*)",
},
{ re: /\bgit\s+push\b[^\n]*\b(main|master)\b/i, reason: "push to main/master" },
// Deploy convention: a `release-*` branch push deploys to STAGE, and a `v*`
// tag push deploys to PROD. Guard both the branch and the tag pushes.
{ re: /\bgit\s+push\b[^\n]*\brelease[-/]\S+/i, reason: "push to a release-* branch (deploys to stage)" },
{ re: /\bgit\s+push\b[^\n]*(--tags\b|--follow-tags\b)/i, reason: "push tags (a v* tag deploys to PROD)" },
{ re: /\bgit\s+push\b[^\n]*\sv\d[\w.-]*/i, reason: "push a v* version tag (deploys to PROD)" },
{
re: /\bkubectl\b[^\n]*(--context[=\s]?\S*prod|--namespace[=\s]?\S*prod|\bctx-prod\b)/i,
reason: "kubectl against a production context/namespace",