@cleartrip/frontguard 0.2.5 → 0.2.7

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": "@cleartrip/frontguard",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "Org-wide frontend PR guardrails: linting, hygiene, any-delta, cycles, dead code, bundle/CWV hints, custom rules, optional LLM brief",
5
5
  "type": "module",
6
6
  "bin": {
@@ -26,6 +26,7 @@
26
26
  "build": "tsup",
27
27
  "dev": "tsup --watch",
28
28
  "typecheck": "tsc --noEmit",
29
+ "test": "npm run build && tsx --test src/lib/bitbucket-checks-image-md.test.ts src/runner/checks-snapshot-png.integration.test.ts",
29
30
  "format": "prettier --write .",
30
31
  "prepack": "npm run build"
31
32
  },
@@ -38,6 +39,7 @@
38
39
  ],
39
40
  "license": "MIT",
40
41
  "dependencies": {
42
+ "@resvg/resvg-js": "^2.6.2",
41
43
  "fast-glob": "^3.3.3",
42
44
  "typescript": "^5.8.2"
43
45
  },
@@ -48,6 +50,7 @@
48
50
  "picocolors": "^1.1.1",
49
51
  "prettier": "^3.5.3",
50
52
  "tinyexec": "^1.0.1",
51
- "tsup": "^8.4.0"
53
+ "tsup": "^8.4.0",
54
+ "tsx": "^4.21.0"
52
55
  }
53
56
  }
@@ -1,67 +1,54 @@
1
- # FrontGuard + Bitbucket PR comment: Checks table screenshot + FreeKit full HTML link
1
+ # FrontGuard PR comment: checks screenshot (inline) + FreeKit full report
2
2
  #
3
- # 1. Runs FrontGuard full HTML + minimal checks-only HTML (--checksSnapshotOut).
4
- # 2. Headless Chromium screenshots the checks page PNG.
5
- # 3. Uploads PNG to Repository Downloads (needs BITBUCKET_ACCESS_TOKEN with repository:write).
6
- # 4. Uploads full report HTML to FreeKit → public URL.
7
- # 5. PR comment = markdown image (hosted on bitbucket.org/.../downloads/...) + caption + FreeKit URL.
3
+ # The checks-table PNG is generated with @resvg/resvg-js (SVG → raster; no Playwright/Chromium).
4
+ # The PNG is embedded in the PR comment as a small base64 image (no Bitbucket Downloads / extra tokens).
5
+ # Full HTML report is uploaded to FreeKit; the comment links to that URL for details.
8
6
  #
9
- # Repo variable (secured): BITBUCKET_ACCESS_TOKEN — pullrequest:write + repository:write (for Downloads).
7
+ # Secured variable: BITBUCKET_ACCESS_TOKEN — must be allowed to post pull request comments.
10
8
  #
11
- # FreeKit: POST https://freekit.dev/api/v1/sites — see templates/freekit-ci-setup.md
12
- # Optional: FREEKIT_BASE_URL — override API host.
9
+ # Optional: FREEKIT_BASE_URL — override FreeKit API host (default https://freekit.dev).
13
10
  #
14
- # If Chromium fails on your runner image, switch the screenshot step to Playwright (see comments below).
11
+ # Deeper clone avoids shallow-git errors (e.g. merge-base / parent rev) for diff-based checks.
15
12
 
16
13
  image: node:20
17
14
 
15
+ clone:
16
+ depth: 50
17
+
18
18
  pipelines:
19
19
  pull-requests:
20
20
  '**':
21
21
  - step:
22
- name: FrontGuard checks image + FreeKit + PR comment
22
+ name: FrontGuard report + PR comment
23
23
  caches:
24
24
  - node
25
25
  artifacts:
26
26
  - frontguard-report.html
27
27
  - frontguard-report.md
28
28
  - frontguard-checks.html
29
- - frontguard-checks*.png
29
+ - frontguard-checks.png
30
30
  script:
31
- - apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends chromium
32
31
  - corepack enable
32
+ - apt-get update && apt-get install -y --no-install-recommends fonts-dejavu-core
33
33
  - yarn install --immutable || yarn install
34
- - export FG_CHECKS_PNG="frontguard-checks-b${BITBUCKET_BUILD_NUMBER}.png"
35
34
  - |
36
35
  yarn frontguard run --markdown \
37
36
  --htmlOut frontguard-report.html \
38
37
  --checksSnapshotOut frontguard-checks.html \
38
+ --checksPngOut frontguard-checks.png \
39
39
  > frontguard-report.md
40
- - |
41
- FILE_URL="file://$(pwd)/frontguard-checks.html"
42
- chromium --headless --no-sandbox --disable-dev-shm-usage --disable-gpu \
43
- --window-size=920,2600 \
44
- --hide-scrollbars \
45
- --screenshot="${FG_CHECKS_PNG}" \
46
- "${FILE_URL}"
47
- # Playwright alternative if Chromium is missing or crashes:
48
- # - npx -y playwright@1.49.1 install chromium
49
- # - npx -y playwright@1.49.1 screenshot "${FILE_URL}" "${FG_CHECKS_PNG}" --viewport-size=920,2600
50
40
  - |
51
41
  python3 << 'PY'
42
+ import base64
52
43
  import json
53
44
  import os
54
- import subprocess
55
- import sys
56
45
  from urllib.error import HTTPError
57
- from urllib.parse import quote
58
46
  from urllib.request import Request, urlopen
59
47
 
60
48
  DETAILED = "For detailed check analysis, please open the full interactive report:"
61
-
62
- repo_full = os.environ.get("BITBUCKET_REPO_FULL_NAME", "").strip()
63
- token = os.environ.get("BITBUCKET_ACCESS_TOKEN", "").strip()
64
- png_path = os.environ.get("FG_CHECKS_PNG", "frontguard-checks.png").strip()
49
+ # Keep in sync with src/lib/bitbucket-checks-image-md.ts (markdown line length cap).
50
+ MAX_IMAGE_LINE = 300_000
51
+ PNG_SIG = bytes([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])
65
52
 
66
53
  base = os.environ.get("FREEKIT_BASE_URL", "https://freekit.dev").rstrip("/")
67
54
  with open("frontguard-report.html", encoding="utf-8") as f:
@@ -89,56 +76,20 @@ pipelines:
89
76
  if not report_url:
90
77
  raise SystemExit(f"FreeKit: missing data.url in {json.dumps(parsed)[:2000]}")
91
78
 
92
- lines = []
93
- img_url = None
94
-
95
- if not os.path.isfile(png_path):
96
- raise SystemExit(f"Missing screenshot {png_path}")
97
-
98
- if repo_full and token:
99
- try:
100
- proc = subprocess.run(
101
- [
102
- "curl",
103
- "--silent",
104
- "--show-error",
105
- "--fail",
106
- "-X",
107
- "POST",
108
- f"https://api.bitbucket.org/2.0/repositories/{repo_full}/downloads",
109
- "-H",
110
- f"Authorization: Bearer {token}",
111
- "-F",
112
- f"files=@{png_path}",
113
- ],
114
- capture_output=True,
115
- text=True,
116
- timeout=180,
117
- )
118
- if proc.returncode != 0:
119
- sys.stderr.write(
120
- f"Bitbucket Downloads upload failed (exit {proc.returncode}): {proc.stderr}\n"
121
- )
122
- else:
123
- up = json.loads(proc.stdout or "{}")
124
- name = (up.get("name") or os.path.basename(png_path)).strip()
125
- ws, slug = repo_full.split("/", 1)
126
- img_url = f"https://bitbucket.org/{ws}/{slug}/downloads/{quote(name, safe='')}"
127
- except Exception as e:
128
- sys.stderr.write(f"Bitbucket Downloads: {e}\n")
129
-
130
- if img_url:
131
- lines.append(f"![FrontGuard — checks summary]({img_url})")
132
- lines.append("")
133
- lines.append(DETAILED)
134
- lines.append(report_url)
135
- if not img_url:
136
- lines.append("")
137
- lines.append(
138
- "_Checks screenshot could not be uploaded. Grant `repository:write` and verify Downloads API, or host the PNG elsewhere and use FRONTGUARD_CHECKS_IMAGE_URL + `frontguard run --prCommentOut`._"
79
+ with open("frontguard-checks.png", "rb") as f:
80
+ raw = f.read()
81
+ if len(raw) < 8 or raw[:8] != PNG_SIG:
82
+ raise SystemExit("frontguard-checks.png is missing or not a valid PNG file.")
83
+ b64 = base64.standard_b64encode(raw).decode("ascii")
84
+ # ASCII alt text; standard Base64 — matches FrontGuard pngBufferToBitbucketImageMarkdownLine.
85
+ img_line = f"![FrontGuard checks summary](data:image/png;base64,{b64})"
86
+ if len(img_line) > MAX_IMAGE_LINE:
87
+ raise SystemExit(
88
+ f"Checks PNG too large for inline comment ({len(raw)} bytes, line {len(img_line)} chars). "
89
+ "Shrink the table or host the PNG and link it; see bitbucket-checks-image-md.ts limits."
139
90
  )
140
91
 
141
- body = "\n".join(lines) + "\n"
92
+ body = f"{img_line}\n\n{DETAILED}\n{report_url}\n"
142
93
  with open("frontguard-pr-comment.md", "w", encoding="utf-8") as out:
143
94
  out.write(body)
144
95
  with open("frontguard-payload.json", "w", encoding="utf-8") as out:
@@ -1,30 +1 @@
1
- # Optional fragment: PNG of the Checks table in the PR comment (Bitbucket Cloud)
2
- #
3
- # Merge into pull-requests after `frontguard run` produces:
4
- # - frontguard-checks.html (--checksSnapshotOut)
5
- # - frontguard-report.html (--htmlOut)
6
- #
7
- # Flow:
8
- # 1. Screenshot the minimal HTML with Playwright (Chromium).
9
- # 2. Upload the PNG somewhere HTTPS-public (examples below).
10
- # 3. export FRONTGUARD_CHECKS_IMAGE_URL='https://.../frontguard-checks.png'
11
- # 4. Run frontguard again with --prCommentOut (or only export + re-run snippet step) so the comment includes ![...](url).
12
- #
13
- # The PR body is Markdown: Bitbucket renders ![](https://...) images when the URL is reachable.
14
-
15
- # --- Example: screenshot + upload to Bitbucket Downloads (public file URL for repo viewers) ---
16
- # - npx playwright@1.49.0 install chromium
17
- # - |
18
- # FILE_URL="$(node --input-type=module -e "import { pathToFileURL } from 'node:url'; console.log(pathToFileURL('frontguard-checks.html').href)")"
19
- # npx playwright@1.49.0 screenshot "$FILE_URL" frontguard-checks.png --viewport-size=920,2000
20
- # - |
21
- # curl --silent --show-error --fail --request POST \
22
- # --url "https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_FULL_NAME}/downloads" \
23
- # --header "Authorization: Bearer ${BITBUCKET_ACCESS_TOKEN}" \
24
- # --form "files=@frontguard-checks.png"
25
- # # Then set FRONTGUARD_CHECKS_IMAGE_URL to the href Bitbucket returns for that file (see API response),
26
- # # or construct the known downloads URL pattern for your workspace.
27
- #
28
- # --- Example: same image hosted on your CDN / object storage ---
29
- # - aws s3 cp frontguard-checks.png s3://my-bucket/ci/frontguard-checks-${BITBUCKET_BUILD_NUMBER}.png --acl public-read
30
- # - export FRONTGUARD_CHECKS_IMAGE_URL="https://my-bucket.s3.amazonaws.com/ci/frontguard-checks-${BITBUCKET_BUILD_NUMBER}.png"
1
+ # Deprecated: use `templates/bitbucket-pipelines.yml` it now uses `--checksPngOut` + inline PNG.
@@ -1,8 +1,8 @@
1
1
  # FreeKit.dev + FrontGuard (Bitbucket Pipelines)
2
2
 
3
- The Bitbucket template (`templates/bitbucket-pipelines.yml`) uploads the **full** HTML report to FreeKit, **screenshots** the checks-only page, uploads that PNG to **Repository → Downloads**, and posts a PR comment with `![](bitbucket.org/.../downloads/...)` plus the FreeKit link. Your pipeline token needs **`repository:write`** (Downloads) and pull request comment permission.
3
+ The Bitbucket template (`templates/bitbucket-pipelines.yml`) runs FrontGuard with **`--checksPngOut`** (SVG PNG via **`@resvg/resvg-js`**, no headless browser), uploads the full HTML to **FreeKit**, and posts a PR comment that **inlines** the checks PNG as `data:image/png;base64,...` plus the FreeKit URL. You only need **`BITBUCKET_ACCESS_TOKEN`** with permission to **comment on pull requests** no Repository Downloads or `repository:write`.
4
4
 
5
- It also uploads `frontguard-report.html` with **no signup or API key** to FreeKit’s public API:
5
+ The same step uploads `frontguard-report.html` to FreeKit’s public API:
6
6
 
7
7
  - **Docs:** [FreeKit API](https://freekit.dev/docs)
8
8
  - **Endpoint:** `POST https://freekit.dev/api/v1/sites` with JSON `{"html": "<full report html>"}`
@@ -26,24 +26,7 @@ On **Bitbucket Pipelines** pull-request builds, FrontGuard reads **`BITBUCKET_PR
26
26
 
27
27
  ## Checks table image in PR comments
28
28
 
29
- Bitbucket renders **`![](https://.../checks.png)`** in PR comments when the URL is public HTTPS. FrontGuard can emit a **minimal HTML** file that contains only the Checks table (same styling as the full report):
30
-
31
- ```bash
32
- yarn frontguard run --markdown \
33
- --htmlOut frontguard-report.html \
34
- --checksSnapshotOut frontguard-checks.html \
35
- > frontguard-report.md
36
- ```
37
-
38
- Then:
39
-
40
- 1. **Screenshot** `frontguard-checks.html` with headless Chromium (e.g. `npx playwright screenshot "<file://...>" frontguard-checks.png`).
41
- 2. **Upload** the PNG to a reachable URL (Bitbucket Downloads API, S3, CDN, etc.).
42
- 3. Set **`FRONTGUARD_CHECKS_IMAGE_URL`** to that URL **before** writing the PR comment (e.g. before `formatBitbucketPrSnippet` / `--prCommentOut`).
43
-
44
- The snippet places the image at the **top** of the comment and keeps the **full interactive report** link below (with a short line explaining that details are in the HTML).
45
-
46
- See **`templates/checks-snapshot-bitbucket-snippet.yml`** for merge-ready pipeline examples.
29
+ The default pipeline uses **`--checksPngOut`** so FrontGuard writes **`frontguard-checks.png`** (raster from the checks table). A short Python step base64-embeds that image in the PR comment (no extra hosting). If the PNG is too large for Bitbucket, raise the limit in the pipeline script cautiously or host the image and set **`FRONTGUARD_CHECKS_IMAGE_URL`** with **`--prCommentOut`** instead.
47
30
 
48
31
  ## Compared to Surge
49
32