From 25087942813447e1cf7e29f2f8e3902b99adfe0a Mon Sep 17 00:00:00 2001 From: Krzysztof Liszankowski <39725441+Torgh@users.noreply.github.com> Date: Sun, 25 Oct 2026 16:28:39 +0100 Subject: [PATCH] CI: shared Bun workflow, package cache, dependency review The checks move to bun-app.yml, a reusable workflow that AI Diving Monitor calls too, so the two apps' CI stays the same. Bun's package cache is kept between runs, and pull requests get a dependency review that fails on a new dependency with a known high or critical vulnerability. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/bun-app.yml | 80 +++++++++++++++++++++++++++++++++++ .github/workflows/ci.yml | 48 +++------------------ README.md | 2 +- 3 files changed, 87 insertions(+), 43 deletions(-) create mode 100644 .github/workflows/bun-app.yml diff --git a/.github/workflows/bun-app.yml b/.github/workflows/bun-app.yml new file mode 100644 index 0000000..95f9852 --- /dev/null +++ b/.github/workflows/bun-app.yml @@ -0,0 +1,80 @@ +name: Bun app + +# The checks shared by TripDeck and AI Diving Monitor (it calls this file from Torgh/tripdeck@main), +# so the two apps' CI can't drift apart. Each repo's ci.yml decides when it runs. +on: + workflow_call: + inputs: + mobile: + description: Also build the phone app the way the APK gets it. + type: boolean + default: false + +permissions: + contents: read + +# Actions are pinned to a commit (the version tag can be moved); Dependabot keeps them up to date. +jobs: + check: + name: Typecheck, lint, tests with coverage, build + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 + with: + node-version: 24 + - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ~/.bun/install/cache + key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }} + restore-keys: bun-${{ runner.os }}- + - run: bun install --frozen-lockfile + - run: bun run typecheck + - run: bun run lint + - run: bun run test:coverage + - name: Coverage summary + if: always() && hashFiles('coverage/coverage-summary.json') != '' + run: | + bun -e ' + const { total } = JSON.parse(await Bun.file("coverage/coverage-summary.json").text()); + const row = (k) => `| ${k} | ${total[k].pct}% | ${total[k].covered}/${total[k].total} |`; + console.log(["### Test coverage", "| | % | covered |", "|---|---|---|", + ...["statements", "branches", "functions", "lines"].map(row)].join("\n")); + ' >> "$GITHUB_STEP_SUMMARY" + - run: bun run build + env: + NEXT_TELEMETRY_DISABLED: "1" + # The phone app is only type-checked above; this builds it the way the APK gets it (no keys in CI). + - if: inputs.mobile + run: bun run build:mobile + + windows: + name: Tests on Windows + runs-on: windows-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 + with: + node-version: 24 + - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ~/.bun/install/cache + key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }} + restore-keys: bun-${{ runner.os }}- + - run: bun install --frozen-lockfile + - run: bun run test + + # A pull request that adds a dependency with a known high or critical vulnerability fails here. + dependencies: + name: Dependency review + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0 + with: + fail-on-severity: high diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 62a4cac..ad9107c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,46 +14,10 @@ concurrency: group: ci-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} -# Actions are pinned to a commit (the version tag can be moved); Dependabot keeps them up to date. +# The checks themselves are in bun-app.yml, shared with AI Diving Monitor. jobs: - check: - name: Typecheck, lint, tests with coverage, build - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 - - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 - with: - node-version: 24 - - run: bun install --frozen-lockfile - - run: bun run typecheck - - run: bun run lint - - run: bun run test:coverage - - name: Coverage summary - if: always() && hashFiles('coverage/coverage-summary.json') != '' - run: | - bun -e ' - const { total } = JSON.parse(await Bun.file("coverage/coverage-summary.json").text()); - const row = (k) => `| ${k} | ${total[k].pct}% | ${total[k].covered}/${total[k].total} |`; - console.log(["### Test coverage", "| | % | covered |", "|---|---|---|", - ...["statements", "branches", "functions", "lines"].map(row)].join("\n")); - ' >> "$GITHUB_STEP_SUMMARY" - - run: bun run build - env: - NEXT_TELEMETRY_DISABLED: "1" - # The phone app is only type-checked above; this builds it the way the APK gets it (no keys in CI). - - run: bun run build:mobile - - windows: - name: Tests on Windows - runs-on: windows-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 - - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 - with: - node-version: 24 - - run: bun install --frozen-lockfile - - run: bun run test + app: + name: App + uses: ./.github/workflows/bun-app.yml + with: + mobile: true diff --git a/README.md b/README.md index ba1568c..7ad44ee 100644 --- a/README.md +++ b/README.md @@ -193,7 +193,7 @@ bun run check # everything CI runs on a pull request: typecheck, lint, test `bun run typecheck` uses TypeScript 7 (the `@typescript/native` package, with the `tsc` command). ESLint and `next build` still need the TypeScript API, which 7.0 doesn't have, so the `typescript` package is the TypeScript 6 compatibility release (`@typescript/typescript6`), as Microsoft recommends until typescript-eslint supports 7. -CI runs the same steps as `bun run check` on every pull request and on every commit to `main`, plus the tests on Windows; a pull request can only be merged when both pass. It fails when coverage drops below the thresholds in `vitest.config.mts`. CodeQL scans the code on every pull request, on `main` and weekly (`.github/workflows/codeql.yml`); it builds the phone app first, so its Java is analysed with Android and Capacitor in view. Dependabot opens grouped update pull requests every Monday, and security fixes as soon as they are published. Tests never touch your real trips: each suite uses its own temporary `TRIPDECK_HOME`, and the OneDrive folder is replaced with a temporary one. +CI runs the same steps as `bun run check` on every pull request and on every commit to `main`, plus the tests on Windows, and on a pull request a dependency review that fails when a new dependency has a known high or critical vulnerability; a pull request can only be merged when they pass. The jobs live in `.github/workflows/bun-app.yml`, which [AI Diving Monitor](https://github.com/Torgh/ai-diving-monitor) calls too, so a change there applies to both apps; Bun's package cache is kept between runs. It fails when coverage drops below the thresholds in `vitest.config.mts`. CodeQL scans the code on every pull request, on `main` and weekly (`.github/workflows/codeql.yml`); it builds the phone app first, so its Java is analysed with Android and Capacitor in view. Dependabot opens grouped update pull requests every Monday, and security fixes as soon as they are published. Tests never touch your real trips: each suite uses its own temporary `TRIPDECK_HOME`, and the OneDrive folder is replaced with a temporary one. `bun install` points git at the hooks in `.githooks/`: they refuse a commit or push that contains the value of any key, secret, token or password from your `.env.local`.