Files
Krow-workspace/.github/workflows/mobile-ci.yml

247 lines
9.7 KiB
YAML

name: Mobile CI
on:
pull_request:
paths:
- 'apps/mobile/**'
- '.github/workflows/mobile-ci.yml'
push:
branches:
- main
paths:
- 'apps/mobile/**'
- '.github/workflows/mobile-ci.yml'
jobs:
detect-changes:
name: 🔍 Detect Mobile Changes
runs-on: ubuntu-latest
outputs:
mobile-changed: ${{ steps.detect.outputs.mobile-changed }}
changed-files: ${{ steps.detect.outputs.changed-files }}
steps:
- name: 📥 Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 🔎 Detect changes in apps/mobile
id: detect
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
# For PR, compare all changes against base branch (not just latest commit)
# Using three-dot syntax (...) shows all files changed in the PR branch
BASE_REF="${{ github.event.pull_request.base.ref }}"
CHANGED_FILES=$(git diff --name-only origin/$BASE_REF...HEAD 2>/dev/null || echo "")
else
# For push, compare with previous commit
if [[ "${{ github.event.before }}" == "0000000000000000000000000000000000000000" ]]; then
# Initial commit, check all files
CHANGED_FILES=$(git ls-tree -r --name-only HEAD)
else
CHANGED_FILES=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }})
fi
fi
# Filter for files in apps/mobile
MOBILE_CHANGED=$(echo "$CHANGED_FILES" | grep -c "^apps/mobile/" || echo "0")
if [[ $MOBILE_CHANGED -gt 0 ]]; then
echo "mobile-changed=true" >> $GITHUB_OUTPUT
# Get list of changed Dart files in apps/mobile
MOBILE_FILES=$(echo "$CHANGED_FILES" | grep "^apps/mobile/" | grep "\.dart$" || echo "")
echo "changed-files<<EOF" >> $GITHUB_OUTPUT
echo "$MOBILE_FILES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "✅ Changes detected in apps/mobile/"
echo "📝 Changed files:"
echo "$MOBILE_FILES"
else
echo "mobile-changed=false" >> $GITHUB_OUTPUT
echo "changed-files=" >> $GITHUB_OUTPUT
echo "⏭️ No changes detected in apps/mobile/ - skipping checks"
fi
compile:
name: 🏗️ Compile Mobile App
runs-on: macos-latest
needs: detect-changes
if: needs.detect-changes.outputs.mobile-changed == 'true'
steps:
- name: 📥 Checkout repository
uses: actions/checkout@v4
- name: 🦋 Set up Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.38.x'
channel: 'stable'
cache: true
- name: 🔧 Install Firebase CLI
run: |
npm install -g firebase-tools
- name: 📦 Get Flutter dependencies
run: |
make mobile-install
- name: 🔨 Run compilation check
run: |
set -o pipefail
echo "🏗️ Building client app for Android (dev mode)..."
if ! make mobile-client-build PLATFORM=apk MODE=debug 2>&1 | tee client_build.txt; then
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "❌ CLIENT APP BUILD FAILED"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
exit 1
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🏗️ Building staff app for Android (dev mode)..."
if ! make mobile-staff-build PLATFORM=apk MODE=debug 2>&1 | tee staff_build.txt; then
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "❌ STAFF APP BUILD FAILED"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
exit 1
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ Build check PASSED - Both apps built successfully"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
lint:
name: 🧹 Lint Changed Files
runs-on: macos-latest
needs: detect-changes
if: needs.detect-changes.outputs.mobile-changed == 'true' && needs.detect-changes.outputs.changed-files != ''
steps:
- name: 📥 Checkout repository
uses: actions/checkout@v4
- name: 🦋 Set up Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.38.x'
channel: 'stable'
cache: true
- name: 🔧 Install Firebase CLI
run: |
npm install -g firebase-tools
- name: 📦 Get Flutter dependencies
run: |
make mobile-install
- name: 🔍 Lint changed Dart files
run: |
# Get the list of changed files
CHANGED_FILES="${{ needs.detect-changes.outputs.changed-files }}"
if [[ -z "$CHANGED_FILES" ]]; then
echo "⏭️ No Dart files changed, skipping lint"
exit 0
fi
echo "🎯 Running lint on changed files:"
echo "$CHANGED_FILES"
echo ""
# Run dart analyze on each changed file
HAS_ERRORS=false
FAILED_FILES=()
while IFS= read -r file; do
if [[ -n "$file" && "$file" == *.dart ]]; then
echo "📝 Analyzing: $file"
if ! dart analyze "$file" 2>&1 | tee -a lint_output.txt; then
HAS_ERRORS=true
FAILED_FILES+=("$file")
fi
echo ""
fi
done <<< "$CHANGED_FILES"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Check if there were any errors
if [[ "$HAS_ERRORS" == "true" ]]; then
echo "❌ LINT ERRORS FOUND IN ${#FAILED_FILES[@]} FILE(S):"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
for file in "${FAILED_FILES[@]}"; do
echo " ❌ $file"
done
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "See details above for each file"
exit 1
else
echo "✅ Lint check PASSED for all changed files"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
fi
status-check:
name: 📊 CI Status Check
runs-on: ubuntu-latest
needs: [detect-changes, compile, lint]
if: always()
steps:
- name: 🔍 Check mobile changes detected
run: |
if [[ "${{ needs.detect-changes.outputs.mobile-changed }}" == "true" ]]; then
echo "✅ Mobile changes detected - running full checks"
else
echo "⏭️ No mobile changes detected - skipping checks"
fi
- name: 🏗️ Report compilation status
if: needs.detect-changes.outputs.mobile-changed == 'true'
run: |
if [[ "${{ needs.compile.result }}" == "success" ]]; then
echo "✅ Compilation check: PASSED"
else
echo "❌ Compilation check: FAILED"
exit 1
fi
- name: 🧹 Report lint status
if: needs.detect-changes.outputs.mobile-changed == 'true' && needs.detect-changes.outputs.changed-files != ''
run: |
if [[ "${{ needs.lint.result }}" == "success" ]]; then
echo "✅ Lint check: PASSED"
else
echo "❌ Lint check: FAILED"
exit 1
fi
- name: 🎉 Final status
if: always()
run: |
echo ""
echo "╔════════════════════════════════════╗"
echo "║ 📊 Mobile CI Pipeline Summary ║"
echo "╚════════════════════════════════════╝"
echo ""
echo "🔍 Change Detection: ${{ needs.detect-changes.result }}"
echo "🏗️ Compilation: ${{ needs.compile.result }}"
echo "🧹 Lint Check: ${{ needs.lint.result }}"
echo ""
if [[ "${{ needs.detect-changes.result }}" != "success" || \
("${{ needs.detect-changes.outputs.mobile-changed }}" == "true" && \
("${{ needs.compile.result }}" != "success" || "${{ needs.lint.result }}" != "success")) ]]; then
echo "❌ Pipeline FAILED"
exit 1
else
echo "✅ Pipeline PASSED"
fi