@reneturcios/greenlight 0.13.0 → 0.14.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 CHANGED
@@ -153,6 +153,14 @@ npx @reneturcios/greenlight ci https://github.com/reticlehq/reticle/pull/1620
153
153
  # JSON output for scripting
154
154
  npx @reneturcios/greenlight ci <pr-url> --json
155
155
 
156
+ # CI pre-flight: run a repo's own PR checks locally before pushing (exit 1 on NO-GO)
157
+ npx @reneturcios/greenlight ci-prep ~/work/bruno
158
+
159
+ # [PASS] tests (workflow ci, job build)
160
+ # [SKIPPED] publish (workflow release, job release) - publishes a package
161
+ # [PASS] convention: DCO sign-off
162
+ # Verdict: GO
163
+
156
164
  # Review triage for a PR with review feedback: which comments need you?
157
165
  npx @reneturcios/greenlight review https://github.com/n8n-io/n8n/pull/41235
158
166
 
@@ -0,0 +1,109 @@
1
+ /**
2
+ * CI Pre-flight (`greenlight ci-prep` / MCP `ci_prep`).
3
+ *
4
+ * Answers one question with evidence, BEFORE a PR is pushed: would this
5
+ * repo's own pull_request workflows pass on the current tree?
6
+ *
7
+ * Pipeline:
8
+ * 1. DISCOVER: parse .github/workflows/*.yml for workflows triggered on
9
+ * pull_request / pull_request_target; extract jobs and steps.
10
+ * 2. MAP + RUN (native mode): translate each step into a local check.
11
+ * Steps that map to package scripts or common binaries (test, lint,
12
+ * typecheck, build) are EXECUTED with a per-step timeout. Steps that
13
+ * cannot run locally (deploys, secrets, external services, publishes)
14
+ * are SKIPPED with the reason named. A check is never reported PASS
15
+ * unless it actually ran.
16
+ * 3. CONVENTIONS: changeset requirement, conventional-commit subjects,
17
+ * and DCO sign-off are checked against git history when the repo
18
+ * signals that it requires them.
19
+ * 4. ACT MODE (--act): when `act` and a working docker daemon are both
20
+ * present, the discovered PR workflows run through `act` for real;
21
+ * otherwise the tool says so plainly and falls back to native mode.
22
+ *
23
+ * Honesty contract (same as verify.ts): this would rather say SKIPPED with
24
+ * a reason than report a verdict it cannot defend. Verdict is GO only
25
+ * when zero checks FAIL.
26
+ */
27
+ export type CiPrepStatus = "PASS" | "FAIL" | "SKIPPED";
28
+ export interface CiPrepCheck {
29
+ /** e.g. "test (workflow ci, job build)" or "convention: changesets". */
30
+ name: string;
31
+ kind: "workflow-step" | "convention" | "act";
32
+ status: CiPrepStatus;
33
+ /** One-line evidence: exit code, timing, or the skip reason. */
34
+ detail: string;
35
+ /** Last ~30 lines of captured output when the step was executed. */
36
+ outputTail?: string;
37
+ }
38
+ export interface CiPrepResult {
39
+ repoDir: string;
40
+ base: string | null;
41
+ verdict: "GO" | "NO-GO";
42
+ actMode: "used" | "unavailable" | "not-requested";
43
+ checks: CiPrepCheck[];
44
+ markdown: string;
45
+ }
46
+ export interface CiPrepOptions {
47
+ /** Base ref for convention checks (changesets/commits/DCO). */
48
+ base?: string;
49
+ /** Per-step execution timeout in seconds (default 300). */
50
+ timeoutSecs?: number;
51
+ /** Try act+docker; fall back to native mode when unavailable. */
52
+ useAct?: boolean;
53
+ /** Test seam: override the detected package manager. */
54
+ packageManager?: string;
55
+ /** Test seam: override act/docker detection. */
56
+ actAvailable?: boolean;
57
+ }
58
+ type YamlNode = string | number | boolean | null | YamlNode[] | {
59
+ [k: string]: YamlNode;
60
+ };
61
+ /** Parse a GitHub Actions workflow file into a plain object tree. Throws on structural problems. */
62
+ export declare function parseWorkflowYaml(text: string): Record<string, YamlNode>;
63
+ export interface WorkflowStep {
64
+ name: string;
65
+ uses?: string;
66
+ run?: string;
67
+ if?: string;
68
+ workingDirectory?: string;
69
+ }
70
+ export interface WorkflowJob {
71
+ id: string;
72
+ name: string;
73
+ steps: WorkflowStep[];
74
+ matrix?: string;
75
+ }
76
+ export interface DiscoveredWorkflow {
77
+ file: string;
78
+ jobs: WorkflowJob[];
79
+ /** Why this workflow was skipped entirely (unparseable, no PR trigger). */
80
+ skipReason?: string;
81
+ }
82
+ /** Does this workflow run on pull_request / pull_request_target? */
83
+ export declare function triggersOnPullRequest(doc: Record<string, YamlNode>): boolean;
84
+ export declare function discoverWorkflows(dir: string): DiscoveredWorkflow[];
85
+ export type StepMapping = {
86
+ kind: "execute";
87
+ script: string;
88
+ } | {
89
+ kind: "skip";
90
+ reason: string;
91
+ };
92
+ /**
93
+ * Decide what to do with a `run:` step. Conservative by design: anything
94
+ * that is not clearly a local test/lint/build invocation, or that touches
95
+ * secrets/publishes/deploys, becomes SKIPPED with a named reason.
96
+ */
97
+ export declare function mapRunStep(script: string): StepMapping;
98
+ export declare function mapUsesStep(uses: string): StepMapping;
99
+ /** Push-only / main-only `if:` conditions make a step irrelevant to PRs. */
100
+ export declare function isPushOnlyCondition(ifExpr: string): boolean;
101
+ export declare function detectPackageManager(dir: string, override?: string): string | null;
102
+ export declare function actAvailable(): boolean;
103
+ export declare function runCiPrep(targetDir: string, opts?: CiPrepOptions): Promise<CiPrepResult>;
104
+ export declare function renderCiPrepMarkdown(r: CiPrepResult): string;
105
+ /** Human-readable console rendering (the --json flag prints the raw result). */
106
+ export declare function formatCiPrepHuman(r: CiPrepResult): string;
107
+ /** Ensure the tmp fixture helper can create scratch dirs outside the repo. */
108
+ export declare function scratchDir(prefix: string): string;
109
+ export {};