feat: Add mobile CI workflow for change detection, compilation, and linting
This commit is contained in:
237
.github/workflows/mobile-ci.yml
vendored
Normal file
237
.github/workflows/mobile-ci.yml
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
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 with base branch
|
||||
BASE_REF="${{ github.event.pull_request.base.ref }}"
|
||||
HEAD_REF="${{ github.event.pull_request.head.ref }}"
|
||||
CHANGED_FILES=$(git diff --name-only origin/$BASE_REF..origin/$HEAD_REF 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.19.x'
|
||||
channel: 'stable'
|
||||
cache: true
|
||||
|
||||
- name: 📦 Get Flutter dependencies
|
||||
run: |
|
||||
cd apps/mobile
|
||||
flutter pub get
|
||||
|
||||
- name: 🔨 Run compilation check
|
||||
run: |
|
||||
cd apps/mobile
|
||||
echo "⚙️ Running build_runner..."
|
||||
flutter pub run build_runner build --delete-conflicting-outputs 2>&1 || true
|
||||
|
||||
echo ""
|
||||
echo "🔬 Running flutter analyze on all files..."
|
||||
flutter analyze lib/ --no-fatal-infos 2>&1 | tee analyze_output.txt || true
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
# Check for actual errors (not just warnings)
|
||||
if grep -E "^\s*(error|SEVERE):" analyze_output.txt > /dev/null; then
|
||||
echo "❌ COMPILATION ERRORS FOUND:"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
grep -B 2 -A 1 -E "^\s*(error|SEVERE):" analyze_output.txt | sed 's/^/ /'
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
exit 1
|
||||
else
|
||||
echo "✅ Compilation check PASSED - No errors found"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
fi
|
||||
|
||||
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.19.x'
|
||||
channel: 'stable'
|
||||
cache: true
|
||||
|
||||
- name: 📦 Get Flutter dependencies
|
||||
run: |
|
||||
cd apps/mobile
|
||||
flutter pub get
|
||||
|
||||
- name: 🔍 Lint changed Dart files
|
||||
run: |
|
||||
cd apps/mobile
|
||||
|
||||
# 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 ! flutter analyze "$file" --no-fatal-infos 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
|
||||
|
||||
Reference in New Issue
Block a user