diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..9b9a27ea --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,115 @@ +name: CI - Sanity Checks + +on: + push: + branches: + - main + pull_request: + branches: + - main + workflow_dispatch: + +jobs: + analyze: + name: Code Analysis + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Flutter + uses: subosito/flutter-action@v2 + with: + channel: "stable" + cache: true + + - name: Cache Pub dependencies + uses: actions/cache@v4 + with: + path: | + ~/.pub-cache + key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }} + restore-keys: | + ${{ runner.os }}-pub- + + - name: Install dependencies + run: flutter pub get + + - name: Verify formatting + run: | + # Find all Dart files excluding generated files + FILES=$(find lib $([ -d test ] && echo test) -name "*.dart" ! -name "*.g.dart" ! -name "*.freezed.dart" -type f 2>/dev/null || true) + if [ -z "$FILES" ]; then + echo "No Dart files found to format" + exit 0 + fi + echo "$FILES" | xargs dart format --output=none --set-exit-if-changed + + - name: Analyze code + run: flutter analyze + + test: + name: Unit Tests + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Flutter + uses: subosito/flutter-action@v2 + with: + channel: "stable" + cache: true + + - name: Cache Pub dependencies + uses: actions/cache@v4 + with: + path: | + ~/.pub-cache + key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }} + restore-keys: | + ${{ runner.os }}-pub- + + - name: Install dependencies + run: flutter pub get + + - name: Run tests + run: | + if [ -d "test" ] && [ "$(find test -name '*_test.dart' | wc -l)" -gt 0 ]; then + flutter test + else + echo "No tests found, skipping test execution" + fi + + dependency-check: + name: Dependency Validation + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Flutter + uses: subosito/flutter-action@v2 + with: + channel: "stable" + cache: true + + - name: Cache Pub dependencies + uses: actions/cache@v4 + with: + path: | + ~/.pub-cache + key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }} + restore-keys: | + ${{ runner.os }}-pub- + + - name: Verify dependencies + run: | + flutter pub get + flutter pub outdated diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1742ed9d..9ce9e5e5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,9 +10,29 @@ ## Development - Follow Dart/Flutter conventions -- Run `flutter analyze` before submitting +- Run `dart format .` to format your code (note: generated files like `*.g.dart` are excluded from CI checks) +- Run `flutter analyze` before submitting to check for issues +- Run `flutter test` if tests are available - Test your changes thoroughly +### Code Quality Checks + +The project includes automated CI checks that run on all pull requests: + +1. **Code Formatting**: Ensures code follows Dart formatting standards + - Run locally: `dart format .` to format all files + - Note: CI only checks non-generated files (excludes `.g.dart`, `.freezed.dart`) + - Generated files are reformatted automatically by build tools + +2. **Static Analysis**: Checks for code issues and potential bugs + - Run locally: `flutter analyze` + - Note: CI excludes generated files from analysis (configured in `analysis_options.yaml`) + +3. **Tests**: Runs unit and widget tests (when available) + - Run locally: `flutter test` + +All these checks must pass before your changes can be merged. + ## Internationalization (i18n) This project uses `slang` for internationalization with JSON files. diff --git a/README.md b/README.md index e2092494..b74aed11 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,25 @@ flutter run ## Development +### Code Quality + +Before submitting changes, ensure your code passes all quality checks: + +```bash +# Format code (including generated files) +dart format . + +# Analyze code for issues +flutter analyze + +# Run tests (if available) +flutter test +``` + +**Note**: CI checks exclude generated files (`.g.dart`, `.freezed.dart`) from formatting and analysis checks. You can run `dart format .` locally to format everything, but only your hand-written code will be validated in CI. + +These checks are automatically run in CI for all pull requests. + ### Code Generation The project uses code generation for JSON serialization. After modifying model classes, run: diff --git a/analysis_options.yaml b/analysis_options.yaml index f9b30346..2e3c70e5 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1 +1,6 @@ include: package:flutter_lints/flutter.yaml + +analyzer: + exclude: + - "**/*.g.dart" + - "**/*.freezed.dart"