ci(mobile): add lint, format & typecheck pre-commit hooks (#11849)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
SubashMohanandClaude Opus 4.8 authored and GitHub committed 2026-06-09 15:52:05 +00:00
1 parent 7e3f1d7cda
commit d14f0867d5
9 files changed
+617 -24

No files matched your search

+45
View File
@@ -233,3 +233,48 @@ repos:
language: system
pass_filenames: false
files: ^web/lib/shared/(.*\.(ts|tsx)|package\.json|tsconfig.*\.json)$
# mobile/ is a standalone Expo (SDK 56) app with its own bun.lock — it is NOT
# part of the root bun workspace, so it gets its own install + lockfile-check
# hooks. Lint/format use the Expo-native toolchain (ESLint flat config +
# Prettier) rather than web's oxlint/oxfmt: eslint-config-expo gives RN-aware
# rules and prettier-plugin-tailwindcss sorts NativeWind classes.
- id: mobile-bun-install
name: mobile bun install
description: "Automatically run 'bun install' in mobile/ after a checkout, pull or rebase"
language: system
entry: bash -c 'cd mobile && bun install'
pass_filenames: false
files: ^mobile/(package\.json|bun\.lock)$
stages: [post-checkout, post-merge, post-rewrite]
- id: mobile-bun-install-check
name: mobile bun install check
description: "Check the 'mobile/bun.lock' is updated"
language: system
entry: bash -c 'cd mobile && bun install'
pass_filenames: false
files: ^mobile/(package\.json|bun\.lock)$
# Uses tsc (not tsgo) because mobile is standalone and types against Expo/RN
# (tsconfig extends expo/tsconfig.base); the native-preview compiler isn't
# wired in here.
- id: mobile-typescript-check
name: mobile TypeScript type check
entry: bash -c 'cd mobile && bunx tsc --noEmit'
language: system
pass_filenames: false
files: ^mobile/(.*\.(ts|tsx)|package\.json|tsconfig\.json|bun\.lock)$
- id: mobile-lint
name: mobile lint
entry: bash -c 'cd mobile && bunx expo lint'
language: system
pass_filenames: false
files: ^mobile/.*\.(ts|tsx|js|jsx)$
- id: mobile-format
name: mobile format
entry: bash -c 'cd mobile && bunx prettier --write "${@#mobile/}"' _
language: system
files: ^mobile/
types_or: [javascript, jsx, ts, tsx, json, css]
+6
View File
@@ -0,0 +1,6 @@
node_modules
.expo
dist
android
ios
bun.lock
+4
View File
@@ -0,0 +1,4 @@
{
"plugins": ["prettier-plugin-tailwindcss"],
"tailwindConfig": "./tailwind.config.js"
}
+8 -7
View File
@@ -39,13 +39,14 @@ bun run run:ios # or: bunx expo run:ios --port 8082
## Scripts
| Command | What it does |
| --- | --- |
| `bun run start` / `ios` / `android` / `web` | Metro / dev menu (port 8082). |
| `bun run run:ios` / `run:android` | Build + launch the native dev build. |
| `bun run prebuild` | Regenerate the native `ios/` + `android/` projects (CNG). |
| `bun run typecheck` | `tsc --noEmit`. |
| `bun run lint` | `expo lint`. |
| Command | What it does |
| ------------------------------------------- | --------------------------------------------------------- |
| `bun run start` / `ios` / `android` / `web` | Metro / dev menu (port 8082). |
| `bun run run:ios` / `run:android` | Build + launch the native dev build. |
| `bun run prebuild` | Regenerate the native `ios/` + `android/` projects (CNG). |
| `bun run typecheck` | `tsc --noEmit`. |
| `bun run lint` | `expo lint` (ESLint flat config + `eslint-config-expo`). |
| `bun run format` / `format:check` | Prettier write / check (sorts NativeWind classes). |
## Project layout
+527 -8
View File
File diff suppressed because it is too large. Load diff
+13
View File
@@ -0,0 +1,13 @@
// https://docs.expo.dev/guides/using-eslint/
const { defineConfig } = require("eslint/config");
const expoConfig = require("eslint-config-expo/flat");
const eslintConfigPrettier = require("eslint-config-prettier");
module.exports = defineConfig([
expoConfig,
// Disable ESLint rules that conflict with Prettier; keep this last so it wins.
eslintConfigPrettier,
{
ignores: ["dist/*", ".expo/*", "node_modules/*", "android/*", "ios/*"],
},
]);
+8 -1
View File
@@ -32,6 +32,11 @@
},
"devDependencies": {
"@types/react": "~19.2.2",
"eslint": "^9.39.4",
"eslint-config-expo": "^56.0.4",
"eslint-config-prettier": "^10.1.8",
"prettier": "^3.8.4",
"prettier-plugin-tailwindcss": "^0.8.0",
"tailwindcss": "3.4.17",
"typescript": "~6.0.3"
},
@@ -44,7 +49,9 @@
"run:android": "expo run:android --port 8082",
"prebuild": "expo prebuild --clean",
"typecheck": "tsc --noEmit",
"lint": "expo lint"
"lint": "expo lint",
"format": "prettier --write .",
"format:check": "prettier --check ."
},
"private": true
}
+3 -1
View File
@@ -6,7 +6,9 @@ export default function Home() {
return (
<SafeAreaView className="flex-1 bg-white">
<View className="flex-1 items-center justify-center gap-2 px-6">
<Text className="text-2xl font-semibold text-neutral-900">Onyx Mobile</Text>
<Text className="text-2xl font-semibold text-neutral-900">
Onyx Mobile
</Text>
<Text className="text-center text-base text-neutral-500">
Scaffold ready — Expo SDK 56 · Expo Router · NativeWind v4.
</Text>
+3 -7
View File
@@ -3,12 +3,8 @@
"compilerOptions": {
"strict": true,
"paths": {
"@/*": [
"./src/*"
],
"@/assets/*": [
"./assets/*"
]
"@/*": ["./src/*"],
"@/assets/*": ["./assets/*"]
}
},
"include": [
@@ -18,4 +14,4 @@
"expo-env.d.ts",
"nativewind-env.d.ts"
]
}
}