Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
version: 2
updates:
# Enable version updates for Gradle dependencies
- package-ecosystem: "gradle"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
open-pull-requests-limit: 10
reviewers:
- "KidsPOSProject/android-team"
labels:
- "dependencies"
- "android"
commit-message:
prefix: "chore"
include: "scope"

# Enable version updates for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
open-pull-requests-limit: 5
reviewers:
- "KidsPOSProject/devops"
labels:
- "github-actions"
- "ci/cd"
commit-message:
prefix: "ci"
include: "scope"
176 changes: 176 additions & 0 deletions .github/workflows/android-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
name: Android CI

on:
push:
branches: [ main, develop, feat-* ]
pull_request:
branches: [ main, develop ]

jobs:
lint:
name: Lint Check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Run Lint
run: ./gradlew lintProdDebug lintDemoDebug

- name: Upload Lint Results
if: always()
uses: actions/upload-artifact@v3
with:
name: lint-results
path: app/build/reports/lint-results-*.html

unit-tests:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Run Unit Tests
run: ./gradlew testProdDebugUnitTest testDemoDebugUnitTest

- name: Generate Test Report
if: always()
run: ./gradlew jacocoTestReport

- name: Upload Unit Test Results
if: always()
uses: actions/upload-artifact@v3
with:
name: unit-test-results
path: app/build/reports/tests/testProdDebugUnitTest/

- name: Upload Code Coverage
if: always()
uses: actions/upload-artifact@v3
with:
name: code-coverage
path: app/build/reports/jacoco/jacocoTestReport/

- name: Upload coverage to Codecov
if: always()
uses: codecov/codecov-action@v3
with:
file: app/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml
flags: unit-tests
name: unit-tests-coverage

instrumented-tests:
name: Instrumented Tests
runs-on: macos-latest
strategy:
matrix:
api-level: [26, 29, 33]
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Cache AVD
uses: actions/cache@v3
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-${{ matrix.api-level }}

- name: Create AVD and generate snapshot for caching
if: steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: false
script: echo "Generated AVD snapshot for caching."

- name: Run Instrumented Tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
script: ./gradlew connectedProdDebugAndroidTest

- name: Upload Instrumented Test Results
if: always()
uses: actions/upload-artifact@v3
with:
name: instrumented-test-results-${{ matrix.api-level }}
path: app/build/reports/androidTests/connected/

build:
name: Build APK
runs-on: ubuntu-latest
needs: [lint, unit-tests]
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Build Debug APK
run: ./gradlew assembleProdDebug assembleDemoDebug

- name: Upload APK
uses: actions/upload-artifact@v3
with:
name: debug-apk
path: |
app/build/outputs/apk/prod/debug/*.apk
app/build/outputs/apk/demo/debug/*.apk

- name: Build Release APK
run: ./gradlew assembleProdRelease assembleDemoRelease

- name: Upload Release APK
uses: actions/upload-artifact@v3
with:
name: release-apk
path: |
app/build/outputs/apk/prod/release/*.apk
app/build/outputs/apk/demo/release/*.apk
120 changes: 120 additions & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
name: PR Checks

on:
pull_request:
types: [opened, synchronize, reopened]

jobs:
danger-check:
name: Danger Check
runs-on: ubuntu-latest
if: github.event.pull_request.head.repo.full_name == github.repository
steps:
- uses: actions/checkout@v4

- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.0'
bundler-cache: true

- name: Install Danger
run: |
gem install danger
gem install danger-android_lint

- name: Run Danger
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: danger

code-quality:
name: Code Quality Checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Run Detekt
run: ./gradlew detekt

- name: Upload Detekt Results
if: always()
uses: actions/upload-artifact@v3
with:
name: detekt-results
path: app/build/reports/detekt/

- name: Check Kotlin Code Style
run: ./gradlew ktlintCheck

- name: Comment PR
if: always()
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const path = require('path');

// Read lint results if available
let comment = '## Code Quality Report\n\n';

try {
// Add results summary
comment += '### Summary\n';
comment += '- [x] Code style checks completed\n';
comment += '- [x] Static analysis completed\n';

// Post comment
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
} catch (error) {
console.log('Error posting comment:', error);
}

size-check:
name: APK Size Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Build APK
run: ./gradlew assembleProdRelease

- name: Check APK Size
run: |
APK_SIZE=$(ls -la app/build/outputs/apk/prod/release/*.apk | awk '{print $5}')
APK_SIZE_MB=$(echo "scale=2; $APK_SIZE / 1048576" | bc)
echo "APK Size: ${APK_SIZE_MB} MB"

# Fail if APK is larger than 50MB
if (( $(echo "$APK_SIZE_MB > 50" | bc -l) )); then
echo "Error: APK size exceeds 50MB limit"
exit 1
fi
26 changes: 26 additions & 0 deletions Dangerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Check PR size
warn("Big PR! Consider breaking it up into smaller ones.") if git.lines_of_code > 500

# Warn when there's no PR description
warn("Please provide a PR description") if github.pr_body.length < 10

# Check for modified test files
has_test_changes = git.modified_files.any? { |file| file.include?("Test.kt") }
has_source_changes = git.modified_files.any? { |file| file.include?("src/main") }

if has_source_changes && !has_test_changes
warn("You modified source files but didn't add or modify any tests. Please consider adding tests.")
end

# Check for TODO/FIXME comments
for file in git.modified_files
next unless file.end_with?(".kt", ".java")

diff = git.diff_for_file(file)
if diff && diff.patch.include?("TODO") || diff.patch.include?("FIXME")
warn("TODO/FIXME comment added in #{file}")
end
end

# Congratulate on adding tests
message("Great job adding tests! 🎉") if has_test_changes
Loading