Feature/ai code reviewer - #79
Conversation
…publish permissions
* feat: add AI code reviewer using Gemini API * fix: change secret name to GEMINI_KEY * feat: upgrade AI code reviewer to Gemini 3.5 Flash using official SDK * fix: use snake_case for thinking_level parameter * feat: switch AI reviewer from Gemini to Mistral Agent * fix: add missing bun install step to AI reviewer workflow * fix: resolve AI review duplication and GenAI config issues * fix: require all CI jobs in branch protection and fix NPM provenance publish permissions * fix(ci): correct unresolved job dependency perf -> performance * fix(lint): resolve typescript strict typing errors and unused variables * fix(perf): respect SKIP_REDIS_CHECK and run baseline on built server * fix(health): ensure storage directory exists before checking access * test: fix health route unit test mock for fs.mkdir * fix(health): use proper getDatabase to fix 503 error on health endpoint * ci: add server warmup curls before running perf tests * ci: disable rate limiter during perf baseline check
UI/UX: - GitHub-style settings layout with clean sidebar navigation - Responsive design across all pages (mobile-first) - Profile page redesigned to match GitHub's layout - Header navbar cleaned up with proper active states - Settings pages (profile, account, security) rewritten - API documentation page with 100+ endpoint categories - Trending repos section responsive on mobile - Hero section stats stack on small screens Documentation: - Complete docs-site sidebar with 70+ pages - Configuration reference with all 165 env vars - Architecture page updated with accurate system design - Installation guide with correct ports and secrets - AI review docs updated with 10+ providers - Quick start and first-repo guides rewritten - Local dev setup with all scripts - Database schema docs for 38 tables - Contributing guide with project structure Security (Critical Fixes): - Git HTTP routes now require authentication - RCE via new Function() replaced with safe evaluator - CSRF bypass via fake Bearer header fixed - PR number race condition fixed with atomic SQL - PR title/body input validation added - Password strength enforced on registration - process.env leak to workflows prevented - Docker stream parsing fixed for multi-frame - require() in ESM modules converted to import - Command injection via execSync fixed (execFileSync) - Path traversal in git-storage rejected - SSH rate limiter memory leak fixed (max 10K entries) SSH/Git: - SSH server reads GIT_SSH_PORT, GIT_REPOS_PATH, GIT_SSH_HOST_KEY - Admin permissions passed via SSH - Docker Compose SSH service added - Pkt-line length calculation fixed Deployment: - render.yaml Blueprint for Render (Singapore region) - Dockerfile.worker for background jobs - FREE-DEPLOYMENT.md guide (Oracle, Fly.io, etc.) - RENDER-DEPLOYMENT.md step-by-step guide - Upstash Redis + Render PostgreSQL free tier setup
# Conflicts: # package.json
- Fix count() usage in index.astro with proper type cast - Fix schema.activity -> schema.activities in profile page - Fix HTMLElement.disabled cast in security settings - Add missing docs to docs-site for parity check - All CI checks should now pass
* feat: add AI code reviewer using Gemini API * fix: change secret name to GEMINI_KEY * feat: upgrade AI code reviewer to Gemini 3.5 Flash using official SDK * fix: use snake_case for thinking_level parameter * feat: switch AI reviewer from Gemini to Mistral Agent * fix: add missing bun install step to AI reviewer workflow * fix: resolve AI review duplication and GenAI config issues * fix: require all CI jobs in branch protection and fix NPM provenance publish permissions * fix(ci): correct unresolved job dependency perf -> performance * fix(lint): resolve typescript strict typing errors and unused variables * fix(perf): respect SKIP_REDIS_CHECK and run baseline on built server * fix(health): ensure storage directory exists before checking access * test: fix health route unit test mock for fs.mkdir * fix(health): use proper getDatabase to fix 503 error on health endpoint * ci: add server warmup curls before running perf tests * ci: disable rate limiter during perf baseline check * fix: comprehensive UI, docs, security, and deployment improvements UI/UX: - GitHub-style settings layout with clean sidebar navigation - Responsive design across all pages (mobile-first) - Profile page redesigned to match GitHub's layout - Header navbar cleaned up with proper active states - Settings pages (profile, account, security) rewritten - API documentation page with 100+ endpoint categories - Trending repos section responsive on mobile - Hero section stats stack on small screens Documentation: - Complete docs-site sidebar with 70+ pages - Configuration reference with all 165 env vars - Architecture page updated with accurate system design - Installation guide with correct ports and secrets - AI review docs updated with 10+ providers - Quick start and first-repo guides rewritten - Local dev setup with all scripts - Database schema docs for 38 tables - Contributing guide with project structure Security (Critical Fixes): - Git HTTP routes now require authentication - RCE via new Function() replaced with safe evaluator - CSRF bypass via fake Bearer header fixed - PR number race condition fixed with atomic SQL - PR title/body input validation added - Password strength enforced on registration - process.env leak to workflows prevented - Docker stream parsing fixed for multi-frame - require() in ESM modules converted to import - Command injection via execSync fixed (execFileSync) - Path traversal in git-storage rejected - SSH rate limiter memory leak fixed (max 10K entries) SSH/Git: - SSH server reads GIT_SSH_PORT, GIT_REPOS_PATH, GIT_SSH_HOST_KEY - Admin permissions passed via SSH - Docker Compose SSH service added - Pkt-line length calculation fixed Deployment: - render.yaml Blueprint for Render (Singapore region) - Dockerfile.worker for background jobs - FREE-DEPLOYMENT.md guide (Oracle, Fly.io, etc.) - RENDER-DEPLOYMENT.md step-by-step guide - Upstash Redis + Render PostgreSQL free tier setup * docs: rewrite README to be concise and professional * fix: resolve CI failures - lint errors, docs parity, type casts - Fix count() usage in index.astro with proper type cast - Fix schema.activity -> schema.activities in profile page - Fix HTMLElement.disabled cast in security settings - Add missing docs to docs-site for parity check - All CI checks should now pass --------- Co-authored-by: JustAPI Bot <bot@justapi.dev>
- Regenerate bun.lock to sync with package.json (fixes frozen lockfile CI error) - Fix ThemeToggle.tsx type narrowing error (activeTheme: string)
- Fix markdown test to account for syntax highlighting spans - Mock validatePasswordStrength in auth register test - Add pipelineRunners to admin-stats test schema mock
- Darken docs accent color (#2dd4bf -> #0d9488) for WCAG AA contrast - Fix theme toggle test to click menu item instead of just button - Fix full-flow test password to meet strength requirements - Add missing frontmatter to deployment docs
- Darken docs accent color (#2dd4bf -> #0d9488) for WCAG AA contrast - Fix theme toggle test to click menu item instead of just button - Fix full-flow test password to meet strength requirements
Feature/ai code reviewer
Fixes Container Security (Trivy) CI failure where bun install --frozen-lockfile --production crashed with 'FileNotFound: failed copying files from cache for node-gyp' when compiling better-sqlite3. Clears Bun's install cache before and between retries to avoid stale/corrupt native module cache entries across Docker layers.
Adds docker/setup-buildx-action and switches to docker/build-push-action with GitHub Actions cache to avoid cold Docker builds and speed up the Trivy container security scan job.
…rics) - Remove .env.backup-2026-02-20 that contained real JWT/SESSION/INTERNAL_HOOK secrets - Harden docker-compose stacks: no hardcoded secrets (all required via .env), add ssh-git + worker services with PROCESS_TYPE branching, NAS variant using OCH_DATA_DIR bind mounts, optional cloudflare/tailscale profiles - Commit Drizzle migration baseline (drizzle/) + scripts/migrate.ts so containers apply schema deterministically at runtime (drizzle-kit is dev-only) - Require Bearer METRICS_TOKEN on /api/metrics (timing-safe compare) - Fix npm start to run the built server (was astro dev); add start:ssh/start:worker/migrate - Copy full src tree into the image so raw-TS ssh/worker entrypoints resolve @/ aliases; add wget for HEALTHCHECK - Canonicalize storage env vars to local + S3 only; update docs, docs-site, AGENTS.md, prometheus config, .env.example, and Docker/vercel guides accordingly
- Remove hardcoded default MinIO password (minioadmin) from docker-compose.yml and docker-compose.production.yml; use required variable syntax (?:) instead - Fix npm publish CI step: --provenance requires package to exist on registry, so fall back to standard publish for initial seed (fixes 404 on first publish)
- Remove 'override: true' from dotenv.config() in src/db/index.ts and scripts/migrate.ts so .env values never clobber CI env vars - Make loadConfig() in config.ts only set DATABASE_URL/DRIVER/REDIS_URL when they are NOT already present in process.env, preventing a stale data/config.json from overwriting CI-injected connection strings Fixes E2E 'FATAL: role root does not exist' where pg fell back to the OS username because the CI DATABASE_URL was silently overridden.
Co-authored-by: swadhinbiswas <107450069+swadhinbiswas@users.noreply.github.com>
The deps stage only installs node_modules and never copies source files. Add a 'source' stage that does COPY . . so the runner stage can COPY --from=source the files it needs (tsconfig.json, src/lib, src/db, scripts/worker.ts).
Found by full-stack E2E proof (real git push against Postgres+Redis stack):
- post-receive hook input lacked a trailing newline: bash 'while read'
skipped the loop body on EOF-without-newline, silently killing hooks
- capability suffix leaked into ref names ('refs/heads/main\0report-
status-v2...') breaking branch filters in workflow triggers
- sideband status was sent on band 2; git expects report-status on
band 1 (progress is band 2)
- the band-1 status report must itself be pkt-line framed AND terminated
with an inner flush-pkt; without it git read EOF after 'ok ref' and
reported 'remote end hung up' despite a successful push
- post-receive route now strips the capability suffix defensively
A real 'git push' now completes cleanly ('main -> main') and the hook
chain (post-receive -> workflows -> webhooks) fires end-to-end.
- workflowRuns/workflowJobs rows pre-created with engine IDs so push-triggered runs are visible in the Actions UI, logs land on real FKs, and merge-queue CI gating reads native runs - matrix strategy expansion (cartesian + exclude/include), per-instance context/env, per-combination job rows - cron scheduler consuming schedule: triggers (cron-parser, tracked in scheduledWorkflows) wired into the worker loop - server-side action resolver: polling runners now execute composite actions and actions/checkout natively; unsupported types fail fast instead of hanging in 'queued' - Docker image ensureImage (createContainer does not auto-pull — jobs previously died with 'no such image') - repo secrets decrypted at dispatch and injected into job containers - speculative-build branches now trigger real CI runs - executor NETWORK_MODE default bridge (checkout/deps work out of box)
dotenv config({ override: true }) forced .env values over real env vars,
so deployments with a committed .env could never override DATABASE_URL
etc. from the environment. The E2E proof caught the app silently using
the production database while tests targeted a local one.
… repo transfer - OAuth provider mode: app registration, consent page, authorization- code grant, bearer userinfo (oauth_apps + oauth_authorization_codes) - fine-grained PAT scopes (repo:read/write, admin, notifications) enforced through canWriteRepo/canAdminRepo across 70+ call sites - GitHub consumer OAuth routes + login buttons - org CRUD API + pages (profile, settings, list/create) - org member invites (email/username, token, accept flow, revoke) - first-party teams CRUD + members API + settings UI - org SAML config API + settings section (SP metadata + sign-in URL) - repo transfer to org (repo-admin + org-owner gated) - org-aware repo owner resolution (getRepoAndUser + resolveOwnerRepo) — org-owned repos previously 404'd everywhere - migrations 0001-0004 (PAT scopes, oauth tables, org invites, drop owner FK so org-owned repos are possible) + journal entries
- issue assignees, milestone assignment, custom field values, and workflow state transitions (schema/lib existed, nothing wrote them) - issue templates (.github/ISSUE_TEMPLATE) + chooser on new-issue page - @mention parsing + notifications on issues/PRs/comments - PR labels + assignees + requested-reviewers APIs (dead junction tables now live) with PR-page UI - draft PR toggle (create + PATCH + UI), merge-method selector (merge/squash/rebase actually implemented in mergeBranch) - review-thread resolve/unresolve on comments - watch/unwatch API + live header button - real contribution graph from activity data (seeded random data deleted)
- GraphQL: issue/organization queries, createIssue/updateIssue/ updatePullRequest/addLabels mutations, Issue nested resolvers wired to real data (were stubs) - OpenAPI coverage tooling (scripts/openapi-coverage.ts) + deterministic generator (scripts/openapi-generate.ts): 25.7% -> 100% (275 routes), idempotent, CI-gated at 60% - OAuth app management page, release asset upload/download UI, tags page, Releases/Packages/Branches repo tabs, wiki delete button - token creation with fine-grained scopes UI
…ioning - CI lanes: contract + smoke jobs, ruleset aligned to real job names, OpenAPI coverage + wiring-audit jobs, quality-gate aggregation - tests/contract (pkt-line, HMAC vectors, workflow triggers, OpenAPI shape, action resolver, matrix, GraphQL schema) + tests/smoke (boot) - disaster-recovery drills implemented (backup-restore, redis outage, postgres reconnect) — weekly-drills CI was calling nonexistent scripts - wiring-audit gate: zero-caller/dead-column/orphan detection, allowlist - coverage now emits coverage-summary.json + lcov (threshold is real) - multi-instance chaos suite (lock exclusivity, fencing, optimistic claims) - webhook delivery retries with exponential backoff - a11y axe coverage expanded to authenticated pages - version unified to 1.1.2, changelog for all batches
Systematic tokenScopes propagation into canWriteRepo/canAdminRepo across ~70 route call sites (fine-grained PAT enforcement), org-aware checks route, watch/subscription API, and the production-parity plan doc.
- jobs run in dependency-order waves: independent jobs and matrix combos execute concurrently (verified: 6-job workflow with needs ordering completes as one wave) - GITHUB_OUTPUT file readback -> step outputs (alongside legacy ::set-output); GITHUB_ENV file readback -> env for subsequent steps - fail-fast marks unlaunched tasks skipped
Data-driven suite: 9 identities x 4 repo types x org roles x 5 PAT scope states. Caught a real gap: hasPatScope lacked write->read implication (GitHub fine-grained semantics) — now implemented.
…ndpoints - AsyncLocalStorage request context: X-Request-Id (or generated) bound onto every log line; dynamic node:async_hooks init keeps the Vite browser build clean - /api/repos crashed on org-owned repos (null owner relation) — batched org lookup; /explore slimmed owner projection (was pulling full user rows incl. password_hash) and made org-aware: p95 1436ms -> 232ms, /api/repos p95 809ms -> 34ms under 20-concurrency load
…ages
- replace require('ioredis') with static imports (Vite's require shim
made Redis silently fall back to in-memory under astro dev — rate
limiting and distributed locks were per-instance); 'Distributed rate
limiting enabled (Redis)' now confirmed at boot
- global pages (home, actions, issues, pulls, stars, stacks,
merge-queue) crashed with 'Cannot read properties of null' on
org-owned repos (owner relation is null when ownerType=organization)
— shared resolveOrgOwners() batched fix + slimmer owner projections
Reproducible 20-step E2E against a real stack (Postgres + Redis + app + real git): login, PAT, repo, push -> workflow -> CI success, PR squash merge, OAuth provider flow, org invites + transfer, org-owned repo checks. Run: bash scripts/e2e-proof.sh with PSQL_URL/GIT_REPOS_PATH set.
- action resolver handles uses: docker://image and docker-type actions: pull + docker run with INPUT_* env and workspace mount (was fail-fast) - repo settings Danger Zone: transfer-to-organization UI (org picker filtered to owner/admin memberships, confirm dialog, redirect)
- refresh_token grant: exchange a valid refresh token (30d JWT) for a new access token + rotated refresh token, with client credential verification - authorization_code grant now returns refresh_token alongside access_token
…h auth) - CouchDB-style login endpoint (npm adduser/login): validates password or PAT, returns an npm token usable as Bearer - GET /-/whoami with Bearer token - publish auth via Basic (PAT) or Bearer (PAT/token) — legacy x-user-id header (spoofable) removed - org scoping: 'default' now maps to NULL org (packages.organization_id FK) so registries work without an organization row - tarball download bridges DB-stored tarballs (packages/npm/<name>/<ver>) - metadata tarball URLs use SITE_URL (was undefined APP_URL) Verified end-to-end: login -> whoami -> publish -> metadata -> tarball download. npm CLI 11 refuses token auth over plain HTTP by policy; TLS-terminated deployments work.
- root + CLI version unified at 1.2.0; changelog documents the full production-readiness batch (E2E proof, git protocol fixes, parallel CI, OAuth provider, orgs, registry, observability, quality gates) - CLI 1.2.0 publish to npmjs requires browser OTP (npm OAuth token)
|
Too many files changed for review (180 files, 100 file limit). Bypass the limit by tagging |
|
Important Review skippedToo many files! This PR contains 179 files, which is 79 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (179)
You can disable this status message by setting the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 27968088 | Triggered | Generic Password | 6254919 | docker-compose.yml | View secret |
| 36137771 | Triggered | Generic Password | 0d9ceff | scripts/e2e-proof.sh | View secret |
| 36137771 | Triggered | Generic Password | 0d9ceff | scripts/e2e-proof.sh | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secrets safely. Learn here the best practices.
- Revoke and rotate these secrets.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
OpenCodeHub v1.2.0 — Production Readiness Release
Self-hosted GitHub/Gitea alternative with Git hosting (HTTP+SSH),
stacked PRs, merge queue with speculative builds, GitHub Actions-
compatible CI/CD, OAuth provider, orgs/teams, and package registries.
Highlights:
end-to-end (push -> workflow -> webhooks)
secrets injection, docker actions on self-hosted runners
PATs with scope implication, GitHub/Google login, SAML config
fixed across the platform
baseline green, OpenAPI 100% coverage, wiring-audit gate