From 31a35414cba977a0d3b3b80332cdc9f2b50d8848 Mon Sep 17 00:00:00 2001 From: Penguin Date: Fri, 23 Oct 2026 18:24:03 +0900 Subject: [PATCH 1/3] =?UTF-8?q?ci:=20=EC=A7=80=EC=9B=90=20=ED=95=98?= =?UTF-8?q?=ED=95=9C=20Bun=201.4.0=EC=9C=BC=EB=A1=9C=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=99=80=20=EB=B0=B0=ED=8F=AC=20=EB=B2=88=EB=93=A4=20?= =?UTF-8?q?=EC=8A=A4=EB=AA=A8=ED=81=AC=EB=A5=BC=20=EB=8F=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 다른 잡은 .bun-version(1.4.4)으로만 돌아, 1.4.3 이후에 생긴 API를 쓰면 타입 검사와 CI를 통과한 채 1.4.0~1.4.2 사용자에게서만 깨진다. bun-floor 잡이 고정 Bun으로 설치·빌드한 뒤 BUN_FLOOR(1.4.0)로 bun test와 scripts/smoke-cli.sh를 돈다. 스모크는 빌드된 dist/cli.js를 임시 레포지토리에서 띄워 ping·summary·diff·페이지·main.js·worker.js가 답하는지 본다. 판별력: cli.ts에 1.4.4 전용 Bun.FetchSession 호출을 넣으면 1.4.0 스모크가 exit 1로 실패하고 1.4.4에서는 통과한다. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01LnGBvUYgubedmy6AXgRzce --- .claude/rules/ci-release.md | 6 +++-- .github/workflows/pr-check.yml | 27 +++++++++++++++++++ CLAUDE.md | 4 +-- scripts/smoke-cli.sh | 49 ++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 4 deletions(-) create mode 100755 scripts/smoke-cli.sh diff --git a/.claude/rules/ci-release.md b/.claude/rules/ci-release.md index 060b5e1..dfb01b4 100644 --- a/.claude/rules/ci-release.md +++ b/.claude/rules/ci-release.md @@ -2,6 +2,7 @@ paths: - ".github/**" - ".bun-version" + - "scripts/smoke-cli.sh" - "release-please-config.json" - ".release-please-manifest.json" - "CHANGELOG.md" @@ -17,9 +18,10 @@ paths: ## PR 체크 (`.github/workflows/pr-check.yml`) -- 잡 5개(lint — format:check 스텝 포함 · typecheck · test · coverage · e2e)가 `main` 룰셋의 필수 체크다. 잡 이름을 바꾸거나 지우면 룰셋도 같이 고친다 — 룰셋은 이름으로 기다려서, 없어진 이름 때문에 모든 PR이 막힌다. 룰셋: `gh api repos/say8425/diffdeck/rulesets/18998573`. +- 잡 6개(lint — format:check 스텝 포함 · typecheck · test · bun-floor · coverage · e2e)가 `main` 룰셋의 필수 체크다. 잡 이름을 바꾸거나 지우면 룰셋도 같이 고친다 — 룰셋은 이름으로 기다려서, 없어진 이름 때문에 모든 PR이 막힌다. 룰셋: `gh api repos/say8425/diffdeck/rulesets/18998573`. - 우회자(`bypass_actors`)가 없어 관리자도 빨간 CI로 머지하지 못한다. `strict`(최신 `main` 포함 요구)는 끈다 — 켜면 머지마다 열린 PR의 e2e를 다시 돌려야 한다. flake는 `gh run rerun --failed`로 다시 돌린다. -- 모든 setup-bun 스텝은 `bun-version-file: .bun-version`으로 같은 Bun을 쓴다. 고정하지 않으면 새 Bun이 나올 때마다 PR과 무관하게 결과가 바뀐다 — Bun의 line coverage 집계가 버전마다 달라 coverage 게이트가 갑자기 실패할 수 있다. 올릴 때는 `.bun-version`과 devDep `@types/bun`을 같이 바꾸고, 그 버전으로 `bun run test:coverage`를 로컬에서 먼저 돌린다. 지원 하한은 Bun 1.4다. +- setup-bun 스텝은 `bun-version-file: .bun-version`으로 같은 Bun을 쓴다(`bun-floor`의 두 번째 스텝만 예외). 고정하지 않으면 새 Bun이 나올 때마다 PR과 무관하게 결과가 바뀐다 — Bun의 line coverage 집계가 버전마다 달라 coverage 게이트가 갑자기 실패할 수 있다. 올릴 때는 `.bun-version`과 devDep `@types/bun`을 같이 바꾸고, 그 버전으로 `bun run test:coverage`를 로컬에서 먼저 돌린다. +- 지원 하한은 Bun 1.4.0이다(README와 번역 4종의 요구 사항 줄). `.bun-version`을 올리면 `@types/bun`도 올라가 하한에 없는 API가 타입 검사와 다른 잡을 통과한다. 그래서 `bun-floor` 잡이 고정 Bun으로 설치·빌드한 뒤 `BUN_FLOOR` Bun으로 `bun test`와 `scripts/smoke-cli.sh`(빌드된 `dist/cli.js`를 띄워 첫 화면 API를 부른다)를 돈다. 설치를 하한 Bun으로 하지 않는 것은, 잠금 파일 포맷이 하한을 앞서는 날 하한과 무관하게 빨개지지 않게 하려는 것이다. 하한을 올리면 `BUN_FLOOR`, README 다섯 곳, 이 줄을 같은 PR에서 바꾼다. - 모든 잡은 `bun install --frozen-lockfile`로 설치한다. e2e 잡은 Node를 고정하고 `playwright install --with-deps chrome`으로 실제 Chrome을 깐다(`channel: "chrome"`). 실패하면 `apps/viewer/test-results/`를 아티팩트로 올린다. - e2e는 골라 돌리지 않고 전부 돈다 — 어느 계약이 깨질지 미리 알 수 없다. diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index 9cf3a41..6ea2784 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -43,6 +43,33 @@ jobs: - run: bun install --frozen-lockfile - run: bun test + # 다른 잡은 .bun-version으로 돈다. 사용자는 지원 하한까지의 어느 Bun으로든 배포물을 + # 돌리므로, 릴리스와 같은 Bun으로 빌드한 dist/cli.js와 테스트 스위트를 하한 Bun에서 + # 돌린다(ci-release.md). + bun-floor: + runs-on: ubuntu-latest + timeout-minutes: 10 + env: + BUN_FLOOR: 1.4.0 + steps: + - uses: actions/checkout@v7 + - uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version + # 설치와 빌드는 고정 Bun으로 한다. 잠금 파일 포맷이 하한 Bun을 앞서도 이 잡이 + # 하한과 무관하게 빨개지지 않는다. + - run: bun install --frozen-lockfile + - run: bun run build + working-directory: apps/viewer + - uses: oven-sh/setup-bun@v2 + with: + bun-version: ${{ env.BUN_FLOOR }} + - name: Check the floor Bun is on PATH + run: test "$(bun --version)" = "$BUN_FLOOR" + - run: bun test + - name: Smoke the release bundle + run: scripts/smoke-cli.sh + coverage: runs-on: ubuntu-latest steps: diff --git a/CLAUDE.md b/CLAUDE.md index a31dcfc..34e2238 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,7 @@ - `apps/viewer/` — 배포되는 유일한 패키지 `@say8425/diffdeck`: `server/`(데이터 API) · `browser/`(뷰어, `main.ts`가 배선) · `index.html` · `cli.ts` + `cli/` · `build.ts` · `fonts/` · `__tests__/` · `e2e/` - `apps/preview/` — PR 프리뷰 Cloudflare Worker와 녹화기. 배포 패키지가 아니다. - `skills/diffdeck/SKILL.md` — 배포되는 에이전트 스킬. `build.ts`가 `dist/skills/`로 복사한다. 플러그인 매니페스트는 `.claude-plugin/`·`.codex-plugin/`·`.agents/plugins/`에 있다. -- `scripts/` — 소스맵 복원 도구, css-inline Bun 플러그인, 렌더 패리티 하니스(`scripts/parity/`) +- `scripts/` — 소스맵 복원 도구, css-inline Bun 플러그인, 렌더 패리티 하니스(`scripts/parity/`), 배포 번들 스모크(`smoke-cli.sh`) - `docs/` — README 번역 4종과 스크린샷. `docs/superpowers/`는 gitignore된 로컬 계획 문서다. ## 명령 @@ -26,7 +26,7 @@ cd apps/viewer && bun run build && bun run start # 뷰어를 직접 띄워 본 ## 작업 규칙 -- `main`에 직접 push하지 않는다. 브랜치 → PR → 사람이 리뷰·머지한다. 필수 체크 5개(lint·typecheck·test·coverage·e2e)가 초록이어야 머지된다. +- `main`에 직접 push하지 않는다. 브랜치 → PR → 사람이 리뷰·머지한다. 필수 체크 6개(lint·typecheck·test·bun-floor·coverage·e2e)가 초록이어야 머지된다. - 커밋 메시지는 Conventional Commits다. release-please가 이것으로 버전·CHANGELOG·릴리스를 만든다(`feat`→minor, `fix`→patch, `!`·`BREAKING CHANGE`→major, `docs`·`chore`·`test`·`ci` 등은 릴리스 없음). - `packages/*`에서는 import 경로와 재구성 타입만 고친다. 렌더·로직 변경은 합의된 예외일 때만 한다(`vendored-packages.md`). CodeView 엔진은 재작성하지 않는다. - 외부 의존성은 정확한 버전으로 핀한다(`^`·`~` 금지). diff --git a/scripts/smoke-cli.sh b/scripts/smoke-cli.sh new file mode 100755 index 0000000..9ab22a7 --- /dev/null +++ b/scripts/smoke-cli.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# 빌드된 dist/cli.js를 PATH의 bun으로 띄워 첫 화면 API가 답하는지 본다. CI는 지원 하한 +# Bun으로 이것을 돈다(ci-release.md). +set -euo pipefail + +cli="$(cd "$(dirname "$0")/.." && pwd)/apps/viewer/dist/cli.js" +[ -f "$cli" ] || { echo "missing $cli (run: cd apps/viewer && bun run build)" >&2; exit 1; } + +work="$(mktemp -d)" +pid="" +trap '[ -n "$pid" ] && kill "$pid" 2>/dev/null; rm -rf "$work"' EXIT + +# 원격을 두지 않는다. 원격이 있으면 base 해석이 `gh pr view`로 GitHub를 찾는다(e2e.md). +repo="$work/repo" +git init -q "$repo" +printf 'one\n' >"$repo/a.txt" +git -C "$repo" add a.txt +git -C "$repo" -c user.email=smoke@example.com -c user.name=smoke commit -q -m init +printf 'two\n' >"$repo/a.txt" + +echo "bun $(bun --version)" +bun "$cli" --version + +(cd "$repo" && XDG_CACHE_HOME="$work/cache" exec bun "$cli" --no-open --port 0) \ + >"$work/out" 2>"$work/err" & +pid=$! + +url="" +for _ in $(seq 1 100); do + url="$(grep -oE 'http://127\.0\.0\.1:[0-9]+/\?[^[:space:]]+' "$work/out" | head -n 1 || true)" + [ -n "$url" ] && break + kill -0 "$pid" 2>/dev/null || break + sleep 0.2 +done +if [ -z "$url" ]; then + echo "CLI did not print a viewer URL" >&2 + cat "$work/out" "$work/err" >&2 + exit 1 +fi + +origin="${url%%/\?*}" +query="${url#*\?}" +curl -fsS -o /dev/null "$origin/api/ping?$query" +curl -fsS -o /dev/null "$origin/api/summary?$query" +curl -fsS "$origin/api/diff?$query" | grep -q '"a.txt"' +curl -fsS -o /dev/null "$url" +curl -fsS -o /dev/null "$origin/main.js" +curl -fsS -o /dev/null "$origin/worker.js" +echo "smoke ok" From 18d53098288e486b88a16ed688a4f5e69ce70cd8 Mon Sep 17 00:00:00 2001 From: Penguin Date: Fri, 23 Oct 2026 18:24:03 +0900 Subject: [PATCH 2/3] =?UTF-8?q?docs:=20README=EC=97=90=20=EC=A7=80?= =?UTF-8?q?=EC=9B=90=20=ED=95=98=ED=95=9C=20Bun=201.4=EB=A5=BC=20=EC=A0=81?= =?UTF-8?q?=EB=8A=94=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01LnGBvUYgubedmy6AXgRzce --- README.md | 2 +- docs/README.es.md | 2 +- docs/README.ja.md | 2 +- docs/README.ko.md | 2 +- docs/README.zh.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6798d75..45d0927 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Or install it globally to get the `diffdeck` command: bun install -g @say8425/diffdeck ``` -Requires [Bun](https://bun.sh) and `git` on your `PATH`. [`gh`](https://cli.github.com) is optional: with it, diffdeck uses your pull requests to pick the comparison base and to show PR badges. +Requires [Bun](https://bun.sh) 1.4 or later and `git` on your `PATH`. [`gh`](https://cli.github.com) is optional: with it, diffdeck uses your pull requests to pick the comparison base and to show PR badges. ## CLI diff --git a/docs/README.es.md b/docs/README.es.md index 96627e8..7e986b9 100644 --- a/docs/README.es.md +++ b/docs/README.es.md @@ -80,7 +80,7 @@ O instálalo globalmente para obtener el comando `diffdeck`: bun install -g @say8425/diffdeck ``` -Requiere [Bun](https://bun.sh) y `git` en tu `PATH`. [`gh`](https://cli.github.com) es opcional: con él, diffdeck usa tus pull requests para elegir la base de comparación y mostrar insignias de PR. +Requiere [Bun](https://bun.sh) 1.4 o posterior y `git` en tu `PATH`. [`gh`](https://cli.github.com) es opcional: con él, diffdeck usa tus pull requests para elegir la base de comparación y mostrar insignias de PR. ## CLI diff --git a/docs/README.ja.md b/docs/README.ja.md index 1ab1564..a8f5e91 100644 --- a/docs/README.ja.md +++ b/docs/README.ja.md @@ -80,7 +80,7 @@ bunx @say8425/diffdeck bun install -g @say8425/diffdeck ``` -[Bun](https://bun.sh) と、`PATH` 上の `git` が必要です。[`gh`](https://cli.github.com) は任意です — あればプルリクエストをもとに比較ベースを選び、PR バッジを表示します。 +[Bun](https://bun.sh) 1.4 以降と、`PATH` 上の `git` が必要です。[`gh`](https://cli.github.com) は任意です — あればプルリクエストをもとに比較ベースを選び、PR バッジを表示します。 ## CLI diff --git a/docs/README.ko.md b/docs/README.ko.md index 2f602fb..1b02f78 100644 --- a/docs/README.ko.md +++ b/docs/README.ko.md @@ -80,7 +80,7 @@ bunx @say8425/diffdeck bun install -g @say8425/diffdeck ``` -[Bun](https://bun.sh)과, `PATH`에 `git`이 있어야 합니다. [`gh`](https://cli.github.com)는 선택 사항입니다 — 있으면 풀 리퀘스트를 보고 비교 기준을 고르고 PR 배지를 보여줍니다. +[Bun](https://bun.sh) 1.4 이상과, `PATH`에 `git`이 있어야 합니다. [`gh`](https://cli.github.com)는 선택 사항입니다 — 있으면 풀 리퀘스트를 보고 비교 기준을 고르고 PR 배지를 보여줍니다. ## CLI diff --git a/docs/README.zh.md b/docs/README.zh.md index e1124e9..d8e9005 100644 --- a/docs/README.zh.md +++ b/docs/README.zh.md @@ -80,7 +80,7 @@ bunx @say8425/diffdeck bun install -g @say8425/diffdeck ``` -需要 [Bun](https://bun.sh),且 `PATH` 中需包含 `git`。[`gh`](https://cli.github.com) 为可选项:有了它,diffdeck 会根据拉取请求选择对比基准,并显示 PR 徽章。 +需要 [Bun](https://bun.sh) 1.4 或更高版本,且 `PATH` 中需包含 `git`。[`gh`](https://cli.github.com) 为可选项:有了它,diffdeck 会根据拉取请求选择对比基准,并显示 PR 徽章。 ## CLI From 3074c35defae226c5fb5a22f409d453dd665a73a Mon Sep 17 00:00:00 2001 From: Penguin Date: Fri, 23 Oct 2026 18:29:19 +0900 Subject: [PATCH 3/3] =?UTF-8?q?ci:=20=ED=95=98=ED=95=9C=20=EC=9E=A1?= =?UTF-8?q?=EC=9D=B4=20=EB=A6=B4=EB=A6=AC=EC=8A=A4=20Bun=EC=9C=BC=EB=A1=9C?= =?UTF-8?q?=20=EB=B9=8C=EB=93=9C=ED=95=9C=20=EB=B2=88=EB=93=A4=EC=9D=84=20?= =?UTF-8?q?=EC=8A=A4=EB=AA=A8=ED=81=AC=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=9C=EC=84=9C=EB=A5=BC=20=EB=B0=94=EA=BE=BC=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cli-smoke.test.ts가 PATH의 bun으로 dist를 다시 빌드하므로, bun test 뒤에 돌던 스모크는 하한 Bun이 빌드한 번들을 보고 있었다. 스모크를 bun test 앞으로 옮긴다. 리뷰 지적도 함께 반영한다. - 첫 setup-bun에 no-cache: 두 스텝이 같은 경로에 깔려 post가 하한 바이너리를 고정 버전 키로 저장할 수 있다. - 스모크: curl에 --max-time 30, diff 본문을 변수로 받아 grep(pipefail SIGPIPE 회피), 커밋에 commit.gpgsign=false. - ci-release.md: 스모크 순서의 이유, 테스트 코드에서만 빨개질 때의 처리. - apps/viewer/README.md(npm 페이지)에도 Bun 1.4 이상을 적는다. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01LnGBvUYgubedmy6AXgRzce --- .claude/rules/ci-release.md | 4 +++- .github/workflows/pr-check.yml | 8 +++++--- apps/viewer/README.md | 2 ++ scripts/smoke-cli.sh | 17 ++++++++++------- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/.claude/rules/ci-release.md b/.claude/rules/ci-release.md index dfb01b4..244d3f5 100644 --- a/.claude/rules/ci-release.md +++ b/.claude/rules/ci-release.md @@ -21,7 +21,9 @@ paths: - 잡 6개(lint — format:check 스텝 포함 · typecheck · test · bun-floor · coverage · e2e)가 `main` 룰셋의 필수 체크다. 잡 이름을 바꾸거나 지우면 룰셋도 같이 고친다 — 룰셋은 이름으로 기다려서, 없어진 이름 때문에 모든 PR이 막힌다. 룰셋: `gh api repos/say8425/diffdeck/rulesets/18998573`. - 우회자(`bypass_actors`)가 없어 관리자도 빨간 CI로 머지하지 못한다. `strict`(최신 `main` 포함 요구)는 끈다 — 켜면 머지마다 열린 PR의 e2e를 다시 돌려야 한다. flake는 `gh run rerun --failed`로 다시 돌린다. - setup-bun 스텝은 `bun-version-file: .bun-version`으로 같은 Bun을 쓴다(`bun-floor`의 두 번째 스텝만 예외). 고정하지 않으면 새 Bun이 나올 때마다 PR과 무관하게 결과가 바뀐다 — Bun의 line coverage 집계가 버전마다 달라 coverage 게이트가 갑자기 실패할 수 있다. 올릴 때는 `.bun-version`과 devDep `@types/bun`을 같이 바꾸고, 그 버전으로 `bun run test:coverage`를 로컬에서 먼저 돌린다. -- 지원 하한은 Bun 1.4.0이다(README와 번역 4종의 요구 사항 줄). `.bun-version`을 올리면 `@types/bun`도 올라가 하한에 없는 API가 타입 검사와 다른 잡을 통과한다. 그래서 `bun-floor` 잡이 고정 Bun으로 설치·빌드한 뒤 `BUN_FLOOR` Bun으로 `bun test`와 `scripts/smoke-cli.sh`(빌드된 `dist/cli.js`를 띄워 첫 화면 API를 부른다)를 돈다. 설치를 하한 Bun으로 하지 않는 것은, 잠금 파일 포맷이 하한을 앞서는 날 하한과 무관하게 빨개지지 않게 하려는 것이다. 하한을 올리면 `BUN_FLOOR`, README 다섯 곳, 이 줄을 같은 PR에서 바꾼다. +- 지원 하한은 Bun 1.4.0이다(README·번역 4종·`apps/viewer/README.md`의 요구 사항 줄). `.bun-version`을 올리면 `@types/bun`도 올라가 하한에 없는 API가 타입 검사와 다른 잡을 통과한다. 그래서 `bun-floor` 잡이 고정 Bun으로 설치·빌드한 뒤 `BUN_FLOOR` Bun으로 `scripts/smoke-cli.sh`(빌드된 `dist/cli.js`를 띄워 첫 화면 API를 부른다)와 `bun test`를 돈다. 설치를 하한 Bun으로 하지 않는 것은, 잠금 파일 포맷이 하한을 앞서는 날 하한과 무관하게 빨개지지 않게 하려는 것이다. +- 스모크는 `bun test`보다 먼저 돈다. `cli-smoke.test.ts`가 PATH의 bun(하한)으로 `dist`를 다시 빌드하므로, 순서를 바꾸면 릴리스 번들 대신 하한 Bun이 빌드한 번들을 스모크한다. 같은 이유로 `build.ts`도 하한 Bun에서 돌아야 한다. +- `bun-floor`가 테스트 코드에서만 빨개지면(새 `bun:test` 매처, `bunfig.toml` 키 등) 테스트를 고친다. 사용자는 테스트를 돌리지 않으므로 그 때문에 하한을 올리지 않는다. 하한을 올리면 `BUN_FLOOR`, README 여섯 곳(`apps/viewer/README.md` 포함), 이 줄을 같은 PR에서 바꾼다. - 모든 잡은 `bun install --frozen-lockfile`로 설치한다. e2e 잡은 Node를 고정하고 `playwright install --with-deps chrome`으로 실제 Chrome을 깐다(`channel: "chrome"`). 실패하면 `apps/viewer/test-results/`를 아티팩트로 올린다. - e2e는 골라 돌리지 않고 전부 돈다 — 어느 계약이 깨질지 미리 알 수 없다. diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index 6ea2784..caf59b4 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -53,11 +53,12 @@ jobs: BUN_FLOOR: 1.4.0 steps: - uses: actions/checkout@v7 + # 두 setup-bun이 같은 경로에 깔린다. 캐시를 켜면 이 스텝의 post가 하한 바이너리를 + # 고정 버전 키로 저장할 수 있다. - uses: oven-sh/setup-bun@v2 with: bun-version-file: .bun-version - # 설치와 빌드는 고정 Bun으로 한다. 잠금 파일 포맷이 하한 Bun을 앞서도 이 잡이 - # 하한과 무관하게 빨개지지 않는다. + no-cache: true - run: bun install --frozen-lockfile - run: bun run build working-directory: apps/viewer @@ -66,9 +67,10 @@ jobs: bun-version: ${{ env.BUN_FLOOR }} - name: Check the floor Bun is on PATH run: test "$(bun --version)" = "$BUN_FLOOR" - - run: bun test + # bun test보다 먼저 돈다. cli-smoke.test.ts가 PATH의 bun으로 dist를 다시 빌드한다. - name: Smoke the release bundle run: scripts/smoke-cli.sh + - run: bun test coverage: runs-on: ubuntu-latest diff --git a/apps/viewer/README.md b/apps/viewer/README.md index 623efd9..64a3a5d 100644 --- a/apps/viewer/README.md +++ b/apps/viewer/README.md @@ -10,6 +10,8 @@ with syntax highlighting, a file tree, and inline image diffs. bunx @say8425/diffdeck ``` +Requires [Bun](https://bun.sh) 1.4 or later and `git`. + Run it from inside a git repository. It starts a local server on `127.0.0.1:49573` (override with `--port`) and opens the viewer in your default browser. diff --git a/scripts/smoke-cli.sh b/scripts/smoke-cli.sh index 9ab22a7..9e2addd 100755 --- a/scripts/smoke-cli.sh +++ b/scripts/smoke-cli.sh @@ -15,7 +15,8 @@ repo="$work/repo" git init -q "$repo" printf 'one\n' >"$repo/a.txt" git -C "$repo" add a.txt -git -C "$repo" -c user.email=smoke@example.com -c user.name=smoke commit -q -m init +git -C "$repo" -c user.email=smoke@example.com -c user.name=smoke -c commit.gpgsign=false \ + commit -q -m init printf 'two\n' >"$repo/a.txt" echo "bun $(bun --version)" @@ -40,10 +41,12 @@ fi origin="${url%%/\?*}" query="${url#*\?}" -curl -fsS -o /dev/null "$origin/api/ping?$query" -curl -fsS -o /dev/null "$origin/api/summary?$query" -curl -fsS "$origin/api/diff?$query" | grep -q '"a.txt"' -curl -fsS -o /dev/null "$url" -curl -fsS -o /dev/null "$origin/main.js" -curl -fsS -o /dev/null "$origin/worker.js" +get() { curl -fsS --max-time 30 "$@"; } +get -o /dev/null "$origin/api/ping?$query" +get -o /dev/null "$origin/api/summary?$query" +diff="$(get "$origin/api/diff?$query")" +grep -q '"a.txt"' <<<"$diff" || { echo "/api/diff has no a.txt: $diff" >&2; exit 1; } +get -o /dev/null "$url" +get -o /dev/null "$origin/main.js" +get -o /dev/null "$origin/worker.js" echo "smoke ok"