@cleartrip/frontguard 0.2.3 → 0.2.5

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.3",
3
+ "version": "0.2.5",
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": {
@@ -1,17 +1,17 @@
1
- # FrontGuard + PR comment (Bitbucket Cloud) FreeKit.dev report URL
1
+ # FrontGuard + Bitbucket PR comment: Checks table screenshot + FreeKit full HTML link
2
2
  #
3
- # HTML report is uploaded to https://freekit.dev via their public API (no API key for POST /sites).
4
- # Docs: https://freekit.dev/docs
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.
5
8
  #
6
- # Per-repo setup:
7
- # 1. Repository variable (secured): BITBUCKET_ACCESS_TOKEN — permission to comment on pull requests.
8
- # 2. Add @cleartrip/frontguard as a devDependency and use this file (or merge the step).
9
+ # Repo variable (secured): BITBUCKET_ACCESS_TOKEN — pullrequest:write + repository:write (for Downloads).
9
10
  #
10
- # API hostname for comments MUST be api.bitbucket.org (Bitbucket Cloud).
11
+ # FreeKit: POST https://freekit.dev/api/v1/sites see templates/freekit-ci-setup.md
12
+ # Optional: FREEKIT_BASE_URL — override API host.
11
13
  #
12
- # The PR comment body is the hosted https://freekit.dev/s/... URL (one line).
13
- #
14
- # Caveats (see templates/freekit-ci-setup.md): public URL, third-party service, size/rate limits.
14
+ # If Chromium fails on your runner image, switch the screenshot step to Playwright (see comments below).
15
15
 
16
16
  image: node:20
17
17
 
@@ -19,28 +19,51 @@ pipelines:
19
19
  pull-requests:
20
20
  '**':
21
21
  - step:
22
- name: FrontGuard – FreeKit report + PR comment
22
+ name: FrontGuard – checks image + FreeKit + PR comment
23
23
  caches:
24
24
  - node
25
25
  artifacts:
26
26
  - frontguard-report.html
27
27
  - frontguard-report.md
28
+ - frontguard-checks.html
29
+ - frontguard-checks*.png
28
30
  script:
31
+ - apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends chromium
29
32
  - corepack enable
30
33
  - yarn install --immutable || yarn install
34
+ - export FG_CHECKS_PNG="frontguard-checks-b${BITBUCKET_BUILD_NUMBER}.png"
31
35
  - |
32
36
  yarn frontguard run --markdown \
33
37
  --htmlOut frontguard-report.html \
38
+ --checksSnapshotOut frontguard-checks.html \
34
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
35
50
  - |
36
51
  python3 << 'PY'
37
52
  import json
38
53
  import os
54
+ import subprocess
55
+ import sys
39
56
  from urllib.error import HTTPError
57
+ from urllib.parse import quote
40
58
  from urllib.request import Request, urlopen
41
59
 
42
- base = os.environ.get("FREEKIT_BASE_URL", "https://freekit.dev").rstrip("/")
60
+ DETAILED = "For detailed check analysis, please open the full interactive report:"
43
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()
65
+
66
+ base = os.environ.get("FREEKIT_BASE_URL", "https://freekit.dev").rstrip("/")
44
67
  with open("frontguard-report.html", encoding="utf-8") as f:
45
68
  html = f.read()
46
69
 
@@ -62,15 +85,64 @@ pipelines:
62
85
  raise SystemExit(f"FreeKit error: {json.dumps(parsed)[:4000]}")
63
86
 
64
87
  data = parsed.get("data") or {}
65
- url = (data.get("url") or "").strip()
66
- if not url:
88
+ report_url = (data.get("url") or "").strip()
89
+ if not report_url:
67
90
  raise SystemExit(f"FreeKit: missing data.url in {json.dumps(parsed)[:2000]}")
68
91
 
69
- with open("frontguard-pr-comment.md", "w", encoding="utf-8") as out:
70
- out.write(url + "\n")
92
+ lines = []
93
+ img_url = None
71
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`._"
139
+ )
140
+
141
+ body = "\n".join(lines) + "\n"
142
+ with open("frontguard-pr-comment.md", "w", encoding="utf-8") as out:
143
+ out.write(body)
72
144
  with open("frontguard-payload.json", "w", encoding="utf-8") as out:
73
- json.dump({"content": {"raw": url}}, out, ensure_ascii=False)
145
+ json.dump({"content": {"raw": body}}, out, ensure_ascii=False)
74
146
  PY
75
147
  - |
76
148
  test -n "${BITBUCKET_ACCESS_TOKEN:-}" || { echo "Missing secured var BITBUCKET_ACCESS_TOKEN"; exit 1; }
@@ -0,0 +1,30 @@
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,10 +1,12 @@
1
1
  # FreeKit.dev + FrontGuard (Bitbucket Pipelines)
2
2
 
3
- The Bitbucket template uploads `frontguard-report.html` with **no signup or API key**, using FreeKit’s public API:
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.
4
+
5
+ It also uploads `frontguard-report.html` with **no signup or API key** to FreeKit’s public API:
4
6
 
5
7
  - **Docs:** [FreeKit API](https://freekit.dev/docs)
6
8
  - **Endpoint:** `POST https://freekit.dev/api/v1/sites` with JSON `{"html": "<full report html>"}`
7
- - **Response:** `data.url` like `https://freekit.dev/s/<siteId>` — this URL is posted as the PR comment.
9
+ - **Response:** `data.url` like `https://freekit.dev/s/<siteId>` — this URL is included in the PR comment below the checks screenshot caption.
8
10
 
9
11
  Optional env (advanced): **`FREEKIT_BASE_URL`** — override the API host (e.g. self‑hosted instance per FreeKit docs).
10
12
 
@@ -22,6 +24,27 @@ On **Bitbucket Pipelines** pull-request builds, FrontGuard reads **`BITBUCKET_PR
22
24
  - **Limits:** Per FreeKit docs — e.g. HTML payload size caps, **rate limits** (creates per minute per IP), possible `429`. Large reports or busy runners may need retries or another host.
23
25
  - **No delete token in CI:** Each run creates a **new** site URL. Old FreeKit URLs may still work until you delete them with the `deleteToken` returned in the API response (this template does not store it).
24
26
 
27
+ ## Checks table image in PR comments
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.
47
+
25
48
  ## Compared to Surge
26
49
 
27
50
  Surge credentials (`SURGE_LOGIN` / `SURGE_TOKEN`) are **not** required for FreeKit’s open POST flow. If you remove Surge, you can delete any old Surge-related secured variables from the repository.