Skip to content

fix(ci): fix lint, build types path, and iOS grep #4

fix(ci): fix lint, build types path, and iOS grep

fix(ci): fix lint, build types path, and iOS grep #4

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
# ─────────────────────────────────────────────────────────────────────────────
# Job 1: Typecheck & Lint
# ─────────────────────────────────────────────────────────────────────────────
jobs:
typecheck-lint:
name: Typecheck & Lint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
# --ignore-scripts prevents `prepare` (bob build) from running during install.
# The build is validated separately in the Build job.
run: npm install --ignore-scripts --legacy-peer-deps
- name: Typecheck
run: npm run typecheck
- name: Lint
run: npm run lint
# ─────────────────────────────────────────────────────────────────────────────
# Job 2: Build — verifies bob compiles src/ to all three output targets
# ─────────────────────────────────────────────────────────────────────────────
build:
name: Build Package
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm install --ignore-scripts --legacy-peer-deps
- name: Build
run: npm run build
- name: Verify outputs
run: |
echo "=== CommonJS ==="
ls lib/commonjs/
echo "=== ESM ==="
ls lib/module/
echo "=== Types ==="
ls lib/typescript/src/
# ─────────────────────────────────────────────────────────────────────────────
# Job 3: Android — structure & manifest validation
# Full Kotlin compile requires a host app; we validate files & manifest instead.
# ─────────────────────────────────────────────────────────────────────────────
android-validate:
name: Android Validate
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Validate required Kotlin files exist
run: |
required=(
"android/build.gradle"
"android/src/main/AndroidManifest.xml"
"android/src/main/java/com/rick427/backgroundtimer/BackgroundTimerModule.kt"
"android/src/main/java/com/rick427/backgroundtimer/BackgroundTimerPackage.kt"
"android/src/main/java/com/rick427/backgroundtimer/BackgroundTimerService.kt"
"android/src/main/java/com/rick427/backgroundtimer/AlarmReceiver.kt"
"android/src/main/java/com/rick427/backgroundtimer/BootReceiver.kt"
"android/src/main/java/com/rick427/backgroundtimer/TimerStore.kt"
"android/src/main/java/com/rick427/backgroundtimer/TimerData.kt"
)
failed=0
for f in "${required[@]}"; do
if [ -f "$f" ]; then
echo " ✅ $f"
else
echo " ❌ MISSING: $f"
failed=1
fi
done
exit $failed
- name: Validate AndroidManifest permissions & components
run: |
manifest="android/src/main/AndroidManifest.xml"
check() {
local label="$1"; local pattern="$2"
if grep -q "$pattern" "$manifest"; then
echo "✅ $label"
else
echo "❌ MISSING: $label"
exit 1
fi
}
check "FOREGROUND_SERVICE permission" "FOREGROUND_SERVICE"
check "WAKE_LOCK permission" "WAKE_LOCK"
check "SCHEDULE_EXACT_ALARM permission" "SCHEDULE_EXACT_ALARM"
check "RECEIVE_BOOT_COMPLETED permission" "RECEIVE_BOOT_COMPLETED"
check "BackgroundTimerService declared" "BackgroundTimerService"
check "AlarmReceiver declared" "AlarmReceiver"
check "BootReceiver declared" "BootReceiver"
- name: Validate AGP 8 namespace in build.gradle
run: |
if grep -q 'namespace "com.rick427.backgroundtimer"' android/build.gradle; then
echo "✅ namespace declared (AGP 8+ requirement)"
else
echo "❌ namespace missing from build.gradle"
exit 1
fi
- name: Validate minSdk is 26 (Android 8+)
run: |
if grep -q 'minSdk 26' android/build.gradle; then
echo "✅ minSdk 26 declared"
else
echo "❌ minSdk 26 not found — required for Foreground Services"
exit 1
fi
# ─────────────────────────────────────────────────────────────────────────────
# Job 4: iOS — Swift source & podspec validation
# Full pod compile requires Xcode + RN; we validate structure & key APIs.
# ─────────────────────────────────────────────────────────────────────────────
ios-validate:
name: iOS Validate
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Validate required Swift and ObjC files exist
run: |
required=(
"ios/RNBackgroundTimer.swift"
"ios/RNBackgroundTimer.m"
"ios/RNBackgroundTimer-Bridging-Header.h"
"ios/BGTaskManager.swift"
"ios/TimerData.swift"
"ios/TimerStore.swift"
"ios/background-timer.podspec"
)
failed=0
for f in "${required[@]}"; do
if [ -f "$f" ]; then
echo " ✅ $f"
else
echo " ❌ MISSING: $f"
failed=1
fi
done
exit $failed
- name: Validate podspec required fields
run: |
podspec="ios/background-timer.podspec"
check_field() {
local label="$1"; local pattern="$2"
if grep -q "$pattern" "$podspec"; then
echo "✅ $label"
else
echo "❌ MISSING: $label"
exit 1
fi
}
check_field "name" "s.name"
check_field "version" "s.version"
check_field "iOS 13 min" "ios.*13"
check_field "Swift version" "SWIFT_VERSION"
check_field "React-Core dep" "React-Core"
- name: Validate BGTaskScheduler is used
run: |
if grep -q "BGTaskScheduler" ios/BGTaskManager.swift; then
echo "✅ BGTaskScheduler used in BGTaskManager.swift"
else
echo "❌ BGTaskScheduler not found in BGTaskManager.swift"
exit 1
fi
- name: Validate UIBackgroundTask is used
run: |
# beginBackgroundTask is called inside BGTaskManager (the dedicated task manager),
# not in RNBackgroundTimer directly which delegates to BGTaskManager.
if grep -q "beginBackgroundTask" ios/BGTaskManager.swift; then
echo "✅ UIBackgroundTask (beginBackgroundTask) used in BGTaskManager.swift"
else
echo "❌ beginBackgroundTask not found in BGTaskManager.swift"
exit 1
fi
- name: Validate Turbo Module ObjC bridge declarations
run: |
bridge="ios/RNBackgroundTimer.m"
if grep -q "RCT_EXTERN_MODULE" "$bridge"; then
echo "✅ RCT_EXTERN_MODULE declared"
else
echo "❌ RCT_EXTERN_MODULE not found in $bridge"
exit 1
fi