Skip to content

Add CodeRabbit review, split CI into per-app workflows - #255

Merged
vernu merged 3 commits into
devfrom
chore/coderabbit-setup
Aug 3, 2026
Merged

Add CodeRabbit review, split CI into per-app workflows#255
vernu merged 3 commits into
devfrom
chore/coderabbit-setup

Conversation

@vernu

@vernu vernu commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Two changes to how PRs get checked: an AI review layer, and a CI restructure so that review has something useful to read and lands faster.

1. CodeRabbit review (.coderabbit.yaml)

textbee is a public repo, so it qualifies for CodeRabbit's Open Source plan: the Pro+ feature set at no cost, activated automatically on install.

Reviews are comment only on the chill profile. request_changes_workflow stays false, so nothing gates a merge.

Two settings are doing real work:

base_branches: [dev]. The default branch is always reviewed and cannot be excluded, so main is covered implicitly. dev has to be listed explicitly. Without it, every feature PR would go unreviewed, since they all target dev.

labels: ['!skip-ai-review']. Because main cannot be dropped from base_branches, this label is the only lever for skipping the dev to main roll-up PRs, which would otherwise re-review code already seen on the way into dev. The label exists on the repo.

CodeRabbit auto-reads CLAUDE.md from the repo root as review guidelines, but this repo's CLAUDE.md sits one directory above the git root and .cursor/rules is not on its auto-read list. The no-em-dash and pnpm-only rules are encoded directly in tone_instructions and a global path instruction instead.

path_filters exclude build output, lockfiles, and Android artifacts. path_instructions are scoped per app: tenant scoping and secret leakage for api/src, client/server boundaries for web, permissions and main-thread work for android, plus a note that web/components/ui is vendored shadcn.

2. CI on pull requests, split per app

build-and-test.yaml fired on push only, so PRs carried no checks of their own. CodeRabbit's github-checks tool waits on GitHub Checks and comments on failures, which gave it nothing to read, and outside contributors got no CI signal before merge.

It also ran everything in one workflow, with web and api sharing a single job. Measured on the last green run:

Step Time
E2e (already continue-on-error) 2m52s
Build web 21s
Unit test web 19s
Lint + typecheck web 20s
Build and test API 40s
Total critical path 5m23s

So e2e was 53% of the wall clock while gating nothing, and an api-only change still paid for all of it plus both android builds.

Now three workflows, api.yaml / web.yaml / android.yaml, each with its own paths filter. Separate workflows get per-app filtering natively, with no third-party change-detection action. Web e2e is its own job, so blocking feedback lands in roughly 90 seconds. It needs no build step because playwright's webServer already runs pnpm build && pnpm start.

Also folded in, since the files were being rewritten anyway:

  • permissions: contents: read. Nothing was declared, so the token got default write scope on every run.
  • concurrency with cancel-in-progress, and timeout-minutes. A hung job previously burned the 6 hour default.
  • Action versions. actionlint rejected setup-node@v3, cache@v3 and setup-java@v3 as too old for current runners, and gradle-build-action is deprecated in favour of gradle/actions/setup-gradle.
  • setup-node's built-in pnpm cache replaces the manual store-path and actions/cache block. pnpm is installed first so the cache has a package manager to query.
  • The android job is guarded with github.event.pull_request.head.repo.full_name == github.repository. It writes google-services.json from repository secrets, and GitHub withholds secrets from fork PRs, so without the guard every outside contribution would fail.
  • google-services.json is written through an env var instead of shell interpolation, so the secret never lands on a command line and JSON containing quotes cannot break the redirect.
  • fail-fast: false on the android matrix, so a dev failure no longer cancels the prod build.
  • Dropped the android_variant dispatch input. It was declared but never referenced; the matrix always built both variants.

Verification

  • .coderabbit.yaml validated against schema.v2.json with ajv: passes.
  • path_filters checked with minimatch against all 516 tracked files: excludes 3, no source files beyond the generated web/next-env.d.ts.
  • actionlint: clean across all three workflows. It previously flagged four stale actions in build-and-test.yaml; those are now gone.
  • The pull_request trigger was validated live on this PR before the split, with the old workflow green.
  • CodeRabbit is installed and already reviewing this PR.

Note on required checks

If branch protection with required status checks is ever turned on, split workflows hit the classic "expected but never received" problem when a path filter skips one. At that point dorny/paths-filter in a single workflow is the better shape. There is no branch protection today.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Added automated workflows for web, API, and Android builds and tests.
    • Android development and production APKs are now built and made available as workflow artifacts.
    • Web validation now includes linting, type checks, unit tests, production builds, and end-to-end browser tests.
    • API changes are automatically built and tested.
    • Improved end-to-end test reliability for device guides, language switching, copying, dashboards, and authentication flows.
  • Documentation
    • Added repository review and automation guidance.

@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
textbee Ready Ready Preview Aug 3, 2026 6:13am

Request Review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Added CodeRabbit review settings, separate Android, API, and web workflows, and more stable web end-to-end tests. The previous combined build workflow was removed.

Changes

Repository automation

Layer / File(s) Summary
Configure CodeRabbit reviews
.coderabbit.yaml
Defines review triggers, exclusions, path filters, repository and technology-specific instructions, GitHub checks integration, chat auto-replies, and knowledge-base scopes.
Add platform CI workflows
.github/workflows/android.yaml, .github/workflows/api.yaml, .github/workflows/web.yaml
Adds Android matrix builds, API build and unit test execution, and web checks with Playwright reporting. Removes the combined build and test workflow.
Stabilize web end-to-end navigation
web/e2e/api-guide.spec.ts, web/e2e/dashboard.spec.ts
Adds hydration-aware navigation helpers. Clipboard checks now poll clipboard contents directly.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the two primary changes: adding CodeRabbit review configuration and splitting CI into per-app workflows.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/coderabbit-setup

Comment @coderabbitai help to get the list of available commands.

@vernu vernu changed the title chore: add CodeRabbit config for automated PR review chore: add CodeRabbit config, run CI on pull requests Aug 3, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/build-and-test.yaml:
- Around line 10-20: Pin every uses: reference in the workflow, including those
at the specified lines, to its full commit SHA while preserving the
corresponding release tag in a comment. Separate the web/API pull-request jobs
from secret-backed execution, and gate the Android job that writes
GOOGLE_SERVICES_JSON_DEV and GOOGLE_SERVICES_JSON_PROD and runs Gradle so it
executes only for trusted same-repository pull requests, not fork-originated
code.
- Around line 128-133: Restrict the secret-backed Android job condition to
trusted non-pull-request branch events, or otherwise route all pull requests to
a secret-free job; do not allow same-repository pull requests to execute the
workflow that writes GOOGLE_SERVICES_JSON_DEV or GOOGLE_SERVICES_JSON_PROD
before running Gradle code. Also replace all eight uses: references in this
workflow with their corresponding full commit SHAs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 13221f34-06ff-4f80-ade4-167ff059a247

📥 Commits

Reviewing files that changed from the base of the PR and between 0a9b014 and f2ffd18.

📒 Files selected for processing (1)
  • .github/workflows/build-and-test.yaml

Comment thread .github/workflows/build-and-test.yaml Outdated
Comment thread .github/workflows/build-and-test.yaml Outdated
@vernu vernu changed the title chore: add CodeRabbit config, run CI on pull requests chore: add CodeRabbit review, split CI into per-app workflows Aug 3, 2026
@vernu vernu changed the title chore: add CodeRabbit review, split CI into per-app workflows Add CodeRabbit review, split CI into per-app workflows Aug 3, 2026
vernu and others added 3 commits August 3, 2026 09:11
textbee is public, so it qualifies for CodeRabbit's Open Source plan (the
Pro+ feature set at no cost). Reviews are comment-only on the chill
profile, so nothing gates a merge.

Two settings are load-bearing and easy to get wrong:

base_branches always includes the default branch and cannot exclude it,
so main is reviewed implicitly and dev has to be listed explicitly.
Without it, every feature PR would go unreviewed since they all target
dev. The skip-ai-review label is the only lever left for skipping the
dev to main roll-ups, which would otherwise re-review code already seen.

CodeRabbit auto-reads CLAUDE.md from the repo root as review guidelines,
but this repo's CLAUDE.md sits one directory above the git root and
.cursor/rules is not on its auto-read list. The no-em-dash and pnpm-only
rules are therefore encoded directly in tone_instructions and a global
path instruction.

Validated against schema.v2.json.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The workflow fired on push only, so pull requests carried no checks of
their own. CodeRabbit's github-checks tool waits on GitHub Checks and
comments on failures, which gave it nothing to read, and outside
contributors got no CI signal before merge.

It also ran everything in one workflow, with web and api sharing a single
job. On the last green run that job was 5m23s, of which the e2e suite was
2m52s while already carrying continue-on-error, so it dominated wall clock
while gating nothing. An api-only change paid for all of it plus both
android builds, because a workflow-level paths filter is all or nothing.

Now api, web and android each have their own workflow and their own paths
filter, which needs no third-party change-detection action, and web e2e is
its own job so the blocking signal lands in about 90 seconds.

Also folded in, since the files were being rewritten anyway:

- permissions: contents: read. Nothing was declared, so the token got
  default write scope on every run.
- concurrency with cancel-in-progress, and timeout-minutes. A hung job
  previously burned the six hour default.
- Action versions. actionlint rejected setup-node@v3, cache@v3 and
  setup-java@v3 as too old for current runners, and gradle-build-action
  is deprecated in favour of gradle/actions/setup-gradle.
- setup-node's built-in pnpm cache replaces the manual store-path and
  actions/cache block. pnpm is installed first so the cache has a package
  manager to query.
- The android job is skipped on fork pull requests. It writes
  google-services.json from repository secrets, and GitHub withholds
  secrets from forks, so it would fail every outside contribution.
- google-services.json is written through an env var instead of shell
  interpolation, so the secret never lands on a command line and JSON
  containing quotes cannot break the redirect.
- fail-fast: false on the android matrix, so a dev failure no longer
  cancels the prod build.
- Dropped the android_variant dispatch input. It was declared but never
  referenced; the matrix always built both variants.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…specs

Four specs had been failing on main for as long as the run history goes
back. The old workflow set continue-on-error on the e2e step rather than
the job, and a step with continue-on-error reports its conclusion as
success even when the command exits non-zero, so the failures never
surfaced. Splitting e2e into its own job made them visible.

None of them were stale. Every string they assert on still exists in the
source. Three are hydration races of the shape ab96e73 fixed for the
messaging specs: the sections stream behind a loading.tsx boundary, so the
HTML paints before React attaches handlers, and a click landing in that
gap is silently dropped. The test then waits out its timeout on a dialog
that was never going to open.

Both specs now navigate through a helper that waits on a value only the
client render can produce: the gateway stats figure on the dashboard, and
the fetched device id in the guide. Prism tokens are not usable as that
signal, because react-syntax-highlighter renders its spans server side
too, so they are already in the SSR payload.

The clipboard spec had a second, unrelated cause. It asserted on the
button's "Copied" label, and code-block.tsx clears that label two seconds
after the click, so the assertion raced a window narrow enough to miss on
a loaded runner. It now polls the clipboard, which is the behaviour under
test and does not expire.

Verified with --repeat-each=4 --retries=0 --workers=2: 56 passed. Single
worker runs are why local looked green while CI failed; the specs' own
comments note that parallel workers background the page, which one worker
never reproduces.

No production code changed. These were test bugs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vernu

vernu commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@vernu

vernu commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/android.yaml:
- Around line 52-64: Pin every GitHub Action reference to its full immutable
commit SHA instead of a mutable version tag. Update the actions in
.github/workflows/android.yaml at lines 52-64 and 97-98,
.github/workflows/api.yaml at lines 46-60, and .github/workflows/web.yaml at
lines 45-59, 98-110, and 127-129; also pin all listed actions in
.github/workflows/docker-publish.yaml at lines 43, 48, 54, 60, 71, 87, 101, and
117.
- Around line 76-81: Update the “Create google-services.json” workflow step to
stop sourcing or writing repository secrets, and instead generate the variant
files from public, Firebase-restricted client configuration values. Preserve
separate dev and prod variant handling while ensuring server credentials remain
outside the APK.

In @.github/workflows/api.yaml:
- Around line 59-64: Update all three node-version entries in
.github/workflows/api.yaml:59-64, .github/workflows/web.yaml:58-63, and
.github/workflows/web.yaml:109-114 to the same supported Node.js runtime
compatible with the API and web packages. In these workflows, pin every
actions/checkout, pnpm/action-setup, actions/setup-node, and
actions/upload-artifact reference to its immutable commit SHA rather than a
mutable tag or branch.

In @.github/workflows/web.yaml:
- Around line 88-92: Remove continue-on-error: true from the e2e job
configuration so failures from pnpm test:e2e make the workflow fail and block
merging.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8a5af45d-3ce0-462c-a60b-7fe67a9dae68

📥 Commits

Reviewing files that changed from the base of the PR and between 7cfa0e0 and 4ab8c0c.

📒 Files selected for processing (7)
  • .coderabbit.yaml
  • .github/workflows/android.yaml
  • .github/workflows/api.yaml
  • .github/workflows/build-and-test.yaml
  • .github/workflows/web.yaml
  • web/e2e/api-guide.spec.ts
  • web/e2e/dashboard.spec.ts
💤 Files with no reviewable changes (1)
  • .github/workflows/build-and-test.yaml

Comment on lines +52 to +64
- name: Checkout repository
uses: actions/checkout@v7
with:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.branch || github.ref }}

- name: Set up JDK 17
uses: actions/setup-java@v5
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v6

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

if rg -nP '^\s*uses:\s+\S+@v[0-9]+(?:\.[0-9]+){0,2}\s*$' .github/workflows; then
  echo "Replace each mutable tag with a verified full commit SHA."
  exit 1
fi

Repository: vernu/textbee

Length of output: 1859


Pin every GitHub Action to a full commit SHA.

Major-version tags are mutable. Apply this to all listed actions, including .github/workflows/docker-publish.yaml at lines 43, 48, 54, 60, 71, 87, 101, and 117.

🧰 Tools
🪛 zizmor (1.28.0)

[warning] 52-55: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

📍 Affects 3 files
  • .github/workflows/android.yaml#L52-L64 (this comment)
  • .github/workflows/android.yaml#L97-L98
  • .github/workflows/api.yaml#L46-L60
  • .github/workflows/web.yaml#L45-L59
  • .github/workflows/web.yaml#L98-L110
  • .github/workflows/web.yaml#L127-L129
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/android.yaml around lines 52 - 64, Pin every GitHub Action
reference to its full immutable commit SHA instead of a mutable version tag.
Update the actions in .github/workflows/android.yaml at lines 52-64 and 97-98,
.github/workflows/api.yaml at lines 46-60, and .github/workflows/web.yaml at
lines 45-59, 98-110, and 127-129; also pin all listed actions in
.github/workflows/docker-publish.yaml at lines 43, 48, 54, 60, 71, 87, 101, and
117.

Source: Path instructions

Comment on lines +76 to +81
- name: Create google-services.json
env:
GOOGLE_SERVICES_JSON: ${{ matrix.variant == 'dev' && secrets.GOOGLE_SERVICES_JSON_DEV || secrets.GOOGLE_SERVICES_JSON_PROD }}
run: |
mkdir -p android/app/src/${{ matrix.variant }}
printf '%s' "$GOOGLE_SERVICES_JSON" > android/app/src/${{ matrix.variant }}/google-services.json

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- workflow excerpt ---'
sed -n '1,130p' .github/workflows/android.yaml
printf '%s\n' '--- Android configuration references ---'
rg -n -C 4 'google-services|GOOGLE_SERVICES_JSON|productFlavors|variant|assemble|upload-artifact' .github/workflows android/app/build.gradle android 2>/dev/null | head -240

Repository: vernu/textbee

Length of output: 15872


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- tracked and present Firebase configuration files ---'
git ls-files 'android/app/src/*/google-services.json' 'android/app/google-services.json' || true
find android/app -type f -name 'google-services.json' -print
printf '%s\n' '--- Android build configuration ---'
sed -n '1,95p' android/app/build.gradle
printf '%s\n' '--- workflow data-flow verifier ---'
python3 - <<'PY'
from pathlib import Path
import re

workflow = Path(".github/workflows/android.yaml").read_text()
build = Path("android/app/build.gradle").read_text()

assert "GOOGLE_SERVICES_JSON:" in workflow
assert "secrets.GOOGLE_SERVICES_JSON_DEV" in workflow
assert "secrets.GOOGLE_SERVICES_JSON_PROD" in workflow
assert 'printf \'%s\' "$GOOGLE_SERVICES_JSON" > android/app/src/${{ matrix.variant }}/google-services.json' in workflow

variants = re.findall(r"^\s+(dev|prod)\s*\{", build, re.MULTILINE)
assert set(variants) == {"dev", "prod"}
assert "id 'com.google.gms.google-services'" in build
assert "assemble${{ matrix.variant }}Debug" in workflow
assert "path: android/app/build/outputs/apk/${{ matrix.variant }}/debug/app-${{ matrix.variant }}-debug.apk" in workflow

print("The workflow maps repository secrets to variant google-services.json files.")
print("The workflow builds both corresponding debug variants.")
print("The workflow uploads each corresponding APK.")
PY

Repository: vernu/textbee

Length of output: 3151


Do not write repository secrets to google-services.json.

This step writes GOOGLE_SERVICES_JSON to files used by both APK builds. Use public, restricted Firebase client configuration. Keep server credentials outside the APK.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/android.yaml around lines 76 - 81, Update the “Create
google-services.json” workflow step to stop sourcing or writing repository
secrets, and instead generate the variant files from public, Firebase-restricted
client configuration values. Preserve separate dev and prod variant handling
while ensuring server credentials remain outside the APK.

Source: Path instructions

Comment on lines +59 to +64
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: '20'
cache: pnpm
cache-dependency-path: api/pnpm-lock.yaml

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

for package in api/package.json web/package.json; do
  printf '%s\n' "$package"
  jq '{engines, packageManager}' "$package"
done

rg -n -C 2 "node-version: '20'" .github/workflows

Repository: vernu/textbee

Length of output: 1226


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' 'Project runtime declarations:'
for package in api/package.json web/package.json; do
  printf '\n%s\n' "$package"
  jq '{name,engines,packageManager}' "$package"
done

printf '\nRepository runtime files:\n'
git ls-files | rg '(^|/)(\.nvmrc|\.node-version|package\.json|pnpm-workspace\.yaml|pnpm-lock\.yaml|volta|tool-versions)$' || true

printf '\nRelevant workflow sections:\n'
sed -n '45,72p' .github/workflows/api.yaml
sed -n '45,70p' .github/workflows/web.yaml
sed -n '96,121p' .github/workflows/web.yaml

printf '\nAll Node runtime declarations:\n'
rg -n -C 2 'node-version|NODE_VERSION|node\":|node:|\\.nvmrc|\\.node-version' .github api web package.json pnpm-workspace.yaml 2>/dev/null || true

Repository: vernu/textbee

Length of output: 50370


🌐 Web query:

Node.js official previous releases Node.js 20 end of life date

💡 Result:

The official end-of-life (EOL) date for Node.js 20 was April 30, 2026 [1][2]. As of August 3, 2026, this version is no longer maintained by the Node.js project [3][4].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' 'Project manifests:'
jq '{name,engines,packageManager,scripts}' api/package.json
jq '{name,engines,packageManager,scripts}' web/package.json

printf '\n%s\n' 'Direct dependency engine constraints from web lockfile:'
awk '
  /^  (dependencies|devDependencies):$/ {section=$0}
  section && /^    [^ ]+:/ {name=$0}
  section && /engines: \{node:/ {print name "\n" $0}
' web/pnpm-lock.yaml | head -n 80

printf '\n%s\n' 'Workflow action references:'
rg -n '^[[:space:]]*uses:' .github/workflows/api.yaml .github/workflows/web.yaml

Repository: vernu/textbee

Length of output: 2046


Move CI from Node.js 20 to a supported runtime.

Node.js 20 reached end of life on April 30, 2026. Select a supported runtime that satisfies the API and web packages, then update all three node-version entries.

Pin all workflow actions to commit SHAs.

The workflows use mutable references for actions/checkout, pnpm/action-setup, actions/setup-node, and actions/upload-artifact.

📍 Affects 2 files
  • .github/workflows/api.yaml#L59-L64 (this comment)
  • .github/workflows/web.yaml#L58-L63
  • .github/workflows/web.yaml#L109-L114
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/api.yaml around lines 59 - 64, Update all three
node-version entries in .github/workflows/api.yaml:59-64,
.github/workflows/web.yaml:58-63, and .github/workflows/web.yaml:109-114 to the
same supported Node.js runtime compatible with the API and web packages. In
these workflows, pin every actions/checkout, pnpm/action-setup,
actions/setup-node, and actions/upload-artifact reference to its immutable
commit SHA rather than a mutable tag or branch.

Comment on lines +88 to +92
e2e:
name: e2e
runs-on: ubuntu-latest
timeout-minutes: 30
continue-on-error: true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make the e2e job blocking.

continue-on-error: true permits the workflow to pass when pnpm test:e2e fails. A browser regression can merge without a failing workflow result. Remove this setting before release. (docs.github.com)

Proposed fix
-    continue-on-error: true
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
e2e:
name: e2e
runs-on: ubuntu-latest
timeout-minutes: 30
continue-on-error: true
e2e:
name: e2e
runs-on: ubuntu-latest
timeout-minutes: 30
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/web.yaml around lines 88 - 92, Remove continue-on-error:
true from the e2e job configuration so failures from pnpm test:e2e make the
workflow fail and block merging.

@vernu
vernu merged commit b85908c into dev Aug 3, 2026
8 checks passed
@vernu
vernu deleted the chore/coderabbit-setup branch August 3, 2026 06:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant