name: CI on: push: branches: [main] pull_request: jobs: analyze-and-test: name: Analyze & unit test runs-on: sharedinbox-runner steps: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: flutter-version: "3.41.6" channel: stable cache: true - name: Install dependencies run: flutter pub get - name: Generate Drift code run: flutter pub run build_runner build --delete-conflicting-outputs - name: Check formatting run: dart format --set-exit-if-changed . - name: Analyze run: flutter analyze --fatal-infos - name: Unit + widget tests with coverage run: flutter test test/unit/ test/widget/ --coverage - name: Coverage gate run: dart run scripts/check_coverage.dart integration: name: Integration tests (Stalwart) runs-on: sharedinbox-runner # Run integration tests only on push to main, not on every PR. if: github.event_name == 'push' && github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v4 - uses: DeterminateSystems/nix-installer-action@v14 - uses: DeterminateSystems/magic-nix-cache-action@v8 - name: Cache FVM Flutter SDK uses: actions/cache@v4 with: path: ~/.fvm key: fvm-${{ hashFiles('.fvm/fvm_config.json') }} - name: Cache pub packages uses: actions/cache@v4 with: path: ~/.pub-cache key: pub-${{ hashFiles('pubspec.lock') }} restore-keys: pub- - name: Run integration tests run: | nix develop --command bash -c " fvm install --skip-pub-get && fvm flutter pub get && fvm flutter pub run build_runner build --delete-conflicting-outputs && stalwart-dev/test.sh " integration-ui: name: UI Integration tests (Stalwart + Xvfb) runs-on: sharedinbox-runner if: github.event_name == 'push' && github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v4 - uses: DeterminateSystems/nix-installer-action@v14 - uses: DeterminateSystems/magic-nix-cache-action@v8 - name: Install Flutter Linux build dependencies run: | sudo apt-get update -q sudo apt-get install -y --no-install-recommends \ libgtk-3-dev pkg-config cmake ninja-build clang \ libsecret-1-dev - name: Cache FVM Flutter SDK uses: actions/cache@v4 with: path: ~/.fvm key: fvm-${{ hashFiles('.fvm/fvm_config.json') }} - name: Cache pub packages uses: actions/cache@v4 with: path: ~/.pub-cache key: pub-${{ hashFiles('pubspec.lock') }} restore-keys: pub- - name: Cache Linux debug build uses: actions/cache@v4 with: path: | build/linux .dart_tool/flutter_build key: linux-debug-${{ hashFiles('pubspec.lock', 'lib/**/*.dart', 'integration_test/**/*.dart') }} restore-keys: linux-debug- - name: Run UI integration tests run: | nix develop --command bash -c " fvm install --skip-pub-get && fvm flutter pub get && fvm flutter pub run build_runner build --delete-conflicting-outputs && stalwart-dev/integration_ui_test.sh " build-linux: name: Build Linux desktop runs-on: sharedinbox-runner needs: analyze-and-test steps: - uses: actions/checkout@v4 - name: Install GTK3, build tools and libsecret run: | sudo apt-get update -q sudo apt-get install -y --no-install-recommends \ libgtk-3-dev pkg-config cmake ninja-build clang \ libsecret-1-dev - uses: subosito/flutter-action@v2 with: flutter-version: "3.41.6" channel: stable cache: true - name: Install dependencies run: flutter pub get - name: Generate Drift code run: flutter pub run build_runner build --delete-conflicting-outputs - name: Build Linux release run: flutter build linux --release deploy: name: Deploy Linux build & publish website runs-on: sharedinbox-runner needs: build-linux if: github.event_name == 'push' && github.ref == 'refs/heads/main' env: SSH_HOST: ${{ secrets.SSH_HOST }} SSH_USER: ${{ secrets.SSH_USER }} steps: - uses: actions/checkout@v4 - name: Install build & deploy dependencies run: | sudo apt-get update -q sudo apt-get install -y --no-install-recommends \ libgtk-3-dev pkg-config cmake ninja-build clang \ libsecret-1-dev hugo rsync - uses: subosito/flutter-action@v2 with: flutter-version: "3.41.6" channel: stable cache: true - name: Cache pub packages uses: actions/cache@v4 with: path: ~/.pub-cache key: pub-${{ hashFiles('pubspec.lock') }} restore-keys: pub- - name: Install dependencies run: flutter pub get - name: Generate Drift code run: flutter pub run build_runner build --delete-conflicting-outputs - name: Generate changelog run: | mkdir -p assets git log -n 50 \ --pretty=format:'* %ad [%h](https://codeberg.org/guettli/sharedinbox/commit/%H): %s' \ --date=short > assets/changelog.txt - name: Setup SSH run: | mkdir -p ~/.ssh printf '%s\n' "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 - name: Build Linux release run: | HASH=$(git rev-parse --short HEAD) flutter build linux --release --no-pub --dart-define=GIT_HASH=$HASH - name: Deploy Linux build to server run: | HASH=$(git rev-parse --short HEAD) DATE_PATH=$(date -u +%Y/%m/%d) REMOTE_DIR="public_html/builds/$DATE_PATH" TARBALL="sharedinbox-linux-amd64-$HASH.tar.gz" tar -czf /tmp/$TARBALL -C build/linux/x64/release bundle ssh -o StrictHostKeyChecking=no "$SSH_USER@$SSH_HOST" "mkdir -p $REMOTE_DIR" scp -o StrictHostKeyChecking=no /tmp/$TARBALL "$SSH_USER@$SSH_HOST:$REMOTE_DIR/$TARBALL" DOWNLOAD_URL="https://sharedinbox.de/builds/$DATE_PATH/$TARBALL" EXISTING=$(ssh -o StrictHostKeyChecking=no "$SSH_USER@$SSH_HOST" \ "cat public_html/latest.json 2>/dev/null || echo '{}'") WINDOWS_URL=$(echo "$EXISTING" | \ python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('windows',''))" \ 2>/dev/null || true) if [ -n "$WINDOWS_URL" ]; then echo "{\"version\":\"$HASH\",\"linux\":\"$DOWNLOAD_URL\",\"windows\":\"$WINDOWS_URL\"}" | \ ssh -o StrictHostKeyChecking=no "$SSH_USER@$SSH_HOST" "cat > public_html/latest.json" else echo "{\"version\":\"$HASH\",\"linux\":\"$DOWNLOAD_URL\"}" | \ ssh -o StrictHostKeyChecking=no "$SSH_USER@$SSH_HOST" "cat > public_html/latest.json" fi - name: Generate build history pages run: python3 scripts/generate_build_history.py - name: Build website env: HUGO_PARAMS_GITVERSION: ${{ github.sha }} run: hugo --source website --minify - name: Deploy website run: | rsync -avz --delete \ --exclude='*.apk' \ --exclude='*.tar.gz' \ -e "ssh -o StrictHostKeyChecking=no" \ website/public/ \ "$SSH_USER@$SSH_HOST:public_html/"