shipproof 0.1.0 → 0.2.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.es.md CHANGED
@@ -6,6 +6,13 @@
6
6
  Comprobaciones sin configuración para saber si un proyecto creado con ayuda de IA está listo para publicarse.
7
7
  </p>
8
8
 
9
+ <p align="center">
10
+ <a href="https://github.com/CalvaryBloom/shipproof/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/CalvaryBloom/shipproof/actions/workflows/ci.yml/badge.svg"></a>
11
+ <a href="https://www.npmjs.com/package/shipproof"><img alt="versión en npm" src="https://img.shields.io/npm/v/shipproof?logo=npm&color=cb3837"></a>
12
+ <a href="https://www.npmjs.com/package/shipproof"><img alt="descargas en npm" src="https://img.shields.io/npm/dm/shipproof?logo=npm"></a>
13
+ <a href="LICENSE"><img alt="Licencia MIT" src="https://img.shields.io/badge/license-MIT-22c55e"></a>
14
+ </p>
15
+
9
16
  <p align="center">
10
17
  <a href="README.md">English</a> · Español
11
18
  </p>
@@ -62,6 +69,29 @@ npx shipproof --no-fail
62
69
 
63
70
  Por defecto, ShipProof termina con código `1` si encuentra al menos un problema bloqueante y con código `2` cuando la entrada no es válida. Los avisos reducen la puntuación, pero no cambian el código de salida.
64
71
 
72
+ ## GitHub Action
73
+
74
+ Añade ShipProof a tus pull requests sin instalar ni configurar nada en el repositorio:
75
+
76
+ ```yaml
77
+ name: ShipProof
78
+
79
+ on: pull_request
80
+
81
+ permissions:
82
+ contents: read
83
+
84
+ jobs:
85
+ readiness:
86
+ runs-on: ubuntu-latest
87
+ steps:
88
+ - uses: actions/checkout@v7
89
+ - uses: CalvaryBloom/shipproof@v0.2.0
90
+ id: shipproof
91
+ ```
92
+
93
+ La acción añade al resumen del workflow la puntuación y los hallazgos que requieren atención. Por defecto falla si encuentra un problema bloqueante; usa `fail-on-issues: false` para obtener solo un informe. Los pasos posteriores pueden consultar los outputs `score`, `readiness`, `warnings` y `failed`.
94
+
65
95
  ## Puntuación
66
96
 
67
97
  Cada comprobación aplicable tiene un peso explícito. Un resultado correcto obtiene todo el peso, un aviso obtiene la mitad y un fallo no obtiene puntos.
@@ -89,10 +119,10 @@ ShipProof no tiene dependencias en tiempo de ejecución. TypeScript y las declar
89
119
 
90
120
  ## Próximos objetivos
91
121
 
92
- - Acción de GitHub con un resumen compacto para cada pull request.
93
122
  - Umbrales configurables mediante `shipproof.config.json`.
94
123
  - Comprobaciones más profundas para Python, Rust y Go.
95
124
  - Salida SARIF compatible con el análisis de código de GitHub.
125
+ - Comentarios opcionales en pull requests con la evolución de la puntuación.
96
126
  - Catálogo público de comprobaciones y falsos positivos conocidos.
97
127
  - Publicación automatizada y con procedencia verificable para las próximas versiones.
98
128
 
package/README.md CHANGED
@@ -8,6 +8,8 @@
8
8
 
9
9
  <p align="center">
10
10
  <a href="https://github.com/CalvaryBloom/shipproof/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/CalvaryBloom/shipproof/actions/workflows/ci.yml/badge.svg"></a>
11
+ <a href="https://www.npmjs.com/package/shipproof"><img alt="npm version" src="https://img.shields.io/npm/v/shipproof?logo=npm&color=cb3837"></a>
12
+ <a href="https://www.npmjs.com/package/shipproof"><img alt="npm downloads" src="https://img.shields.io/npm/dm/shipproof?logo=npm"></a>
11
13
  <a href="LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-22c55e"></a>
12
14
  <img alt="Node 22.13+" src="https://img.shields.io/badge/node-%3E%3D22.13-339933">
13
15
  </p>
@@ -81,6 +83,29 @@ shipproof [path] [options]
81
83
 
82
84
  By default, ShipProof exits with code `1` when at least one blocking issue is found and `2` for invalid input. This makes it useful in continuous integration. Warnings lower the score but do not change the exit code.
83
85
 
86
+ ## GitHub Action
87
+
88
+ Add ShipProof to pull requests without installing or configuring anything in the repository:
89
+
90
+ ```yaml
91
+ name: ShipProof
92
+
93
+ on: pull_request
94
+
95
+ permissions:
96
+ contents: read
97
+
98
+ jobs:
99
+ readiness:
100
+ runs-on: ubuntu-latest
101
+ steps:
102
+ - uses: actions/checkout@v7
103
+ - uses: CalvaryBloom/shipproof@v0.2.0
104
+ id: shipproof
105
+ ```
106
+
107
+ The action writes a compact score and its actionable findings to the workflow summary. It fails the job when a blocking issue is found; set `fail-on-issues: false` to use it as an advisory check. The outputs `score`, `readiness`, `warnings`, and `failed` are available to later steps.
108
+
84
109
  ## Scoring
85
110
 
86
111
  Each applicable check has an explicit weight. Passing earns the full weight, a warning earns half, and a failure earns none.
@@ -108,10 +133,10 @@ ShipProof has no runtime dependencies. TypeScript and its Node.js declarations a
108
133
 
109
134
  ## Roadmap
110
135
 
111
- - GitHub Action with a compact pull-request summary.
112
136
  - Configurable thresholds through `shipproof.config.json`.
113
137
  - Deeper Python, Rust, and Go checks.
114
138
  - SARIF output for GitHub code scanning.
139
+ - Optional pull-request comments with score changes.
115
140
  - A public check catalog with evidence and false-positive guidance.
116
141
  - Automated trusted publishing with provenance for future releases.
117
142
 
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../src/action.ts"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ import { appendFileSync, statSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { analyzeProject } from "./analyze.js";
4
+ import { renderGitHubSummary } from "./reporters/github.js";
5
+ import { renderTerminal } from "./reporters/terminal.js";
6
+ function input(name, fallback) {
7
+ const value = process.env[`INPUT_${name.toUpperCase()}`]?.trim();
8
+ return value ? value : fallback;
9
+ }
10
+ function booleanInput(name, fallback) {
11
+ const value = input(name, String(fallback)).toLowerCase();
12
+ if (value !== "true" && value !== "false") {
13
+ throw new Error(`Input '${name}' must be either 'true' or 'false'.`);
14
+ }
15
+ return value === "true";
16
+ }
17
+ function appendEnvironmentFile(path, values) {
18
+ if (!path)
19
+ return;
20
+ const content = Object.entries(values)
21
+ .map(([name, value]) => `${name}=${value}`)
22
+ .join("\n");
23
+ appendFileSync(path, `${content}\n`, "utf8");
24
+ }
25
+ function main() {
26
+ const workspace = process.env.GITHUB_WORKSPACE ?? process.cwd();
27
+ const targetInput = input("PATH", ".");
28
+ const failOnIssues = booleanInput("FAIL-ON-ISSUES", true);
29
+ const target = resolve(workspace, targetInput);
30
+ if (!statSync(target).isDirectory()) {
31
+ throw new Error(`Cannot analyze '${targetInput}': the target is not a directory.`);
32
+ }
33
+ const result = analyzeProject(target);
34
+ process.stdout.write(renderTerminal(result, false));
35
+ const summaryPath = process.env.GITHUB_STEP_SUMMARY;
36
+ if (summaryPath)
37
+ appendFileSync(summaryPath, `${renderGitHubSummary(result)}\n`, "utf8");
38
+ appendEnvironmentFile(process.env.GITHUB_OUTPUT, {
39
+ score: result.score,
40
+ readiness: result.readiness,
41
+ warnings: result.summary.warnings,
42
+ failed: result.summary.failed,
43
+ });
44
+ if (failOnIssues && result.summary.failed > 0)
45
+ process.exitCode = 1;
46
+ }
47
+ try {
48
+ main();
49
+ }
50
+ catch (error) {
51
+ const message = error instanceof Error ? error.message : "Unexpected action failure.";
52
+ process.stderr.write(`ShipProof action: ${message}\n`);
53
+ process.exitCode = 2;
54
+ }
55
+ //# sourceMappingURL=action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.js","sourceRoot":"","sources":["../../src/action.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  import type { AnalysisResult } from "./types.js";
2
- export declare const SHIPPROOF_VERSION = "0.1.0";
2
+ export declare const SHIPPROOF_VERSION = "0.2.0";
3
3
  export declare function analyzeProject(target: string): AnalysisResult;
4
4
  //# sourceMappingURL=analyze.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import { resolve } from "node:path";
2
2
  import { runReadinessChecks } from "./checks/readiness.js";
3
- export const SHIPPROOF_VERSION = "0.1.0";
3
+ export const SHIPPROOF_VERSION = "0.2.0";
4
4
  const scoreFactors = {
5
5
  pass: 1,
6
6
  warn: 0.5,
@@ -0,0 +1,3 @@
1
+ import type { AnalysisResult } from "../types.js";
2
+ export declare function renderGitHubSummary(result: AnalysisResult): string;
3
+ //# sourceMappingURL=github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../src/reporters/github.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAA0B,MAAM,aAAa,CAAC;AAoB1E,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAuBlE"}
@@ -0,0 +1,35 @@
1
+ const statusLabels = {
2
+ pass: "Pass",
3
+ warn: "Warning",
4
+ fail: "Failed",
5
+ info: "Info",
6
+ };
7
+ const readinessLabels = {
8
+ ready: "Ready to ship",
9
+ close: "Almost ready",
10
+ "work-needed": "Needs work",
11
+ "not-ready": "Not ready",
12
+ };
13
+ function markdownCell(value) {
14
+ return value.replaceAll("\\", "\\\\").replaceAll("|", "\\|").replace(/\r?\n/g, " ");
15
+ }
16
+ export function renderGitHubSummary(result) {
17
+ const findings = result.checks.filter((check) => check.status === "warn" || check.status === "fail");
18
+ const lines = [
19
+ `## ShipProof: ${result.score}/100`,
20
+ "",
21
+ `**${readinessLabels[result.readiness]}** · ${result.summary.passed} passed · ${result.summary.warnings} warnings · ${result.summary.failed} failed`,
22
+ "",
23
+ ];
24
+ if (findings.length === 0) {
25
+ lines.push("No blocking issues or warnings were found.");
26
+ return lines.join("\n");
27
+ }
28
+ lines.push("| Status | Check | Finding |", "| --- | --- | --- |");
29
+ for (const check of findings) {
30
+ const finding = check.suggestion ? `${check.message} Suggested fix: ${check.suggestion}` : check.message;
31
+ lines.push(`| ${statusLabels[check.status]} | ${markdownCell(check.title)} | ${markdownCell(finding)} |`);
32
+ }
33
+ return lines.join("\n");
34
+ }
35
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["../../../src/reporters/github.ts"],"names":[],"mappings":"AAEA,MAAM,YAAY,GAAgC;IAChD,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,MAAM;CACb,CAAC;AAEF,MAAM,eAAe,GAA8B;IACjD,KAAK,EAAE,eAAe;IACtB,KAAK,EAAE,cAAc;IACrB,aAAa,EAAE,YAAY;IAC3B,WAAW,EAAE,WAAW;CACzB,CAAC;AAEF,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAsB;IACxD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IACrG,MAAM,KAAK,GAAG;QACZ,iBAAiB,MAAM,CAAC,KAAK,MAAM;QACnC,EAAE;QACF,KAAK,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,MAAM,CAAC,OAAO,CAAC,MAAM,aAAa,MAAM,CAAC,OAAO,CAAC,QAAQ,eAAe,MAAM,CAAC,OAAO,CAAC,MAAM,SAAS;QACpJ,EAAE;KACH,CAAC;IAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QACzD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,8BAA8B,EAAE,qBAAqB,CAAC,CAAC;IAClE,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,mBAAmB,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;QACzG,KAAK,CAAC,IAAI,CACR,KAAK,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,YAAY,CAAC,OAAO,CAAC,IAAI,CAC9F,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shipproof",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Zero-config release readiness checks for AI-assisted projects.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -45,7 +45,7 @@
45
45
  "build": "tsc -p tsconfig.json",
46
46
  "check": "tsc -p tsconfig.json --noEmit",
47
47
  "lint": "tsc -p tsconfig.json --noEmit",
48
- "test": "pnpm build && node --test dist/test/analyze.test.js",
48
+ "test": "pnpm build && node --test dist/test/analyze.test.js dist/test/github-action.test.js",
49
49
  "start": "node dist/src/cli.js"
50
50
  }
51
51
  }