mirror of
https://github.com/block/buzz.git
synced 2026-10-31 14:31:02 +00:00
`ubuntu-latest` now resolves to Ubuntu 26.04, whose default JDK is 25.
Gradle 8.14.5 doesn't support JDK 25, so every Android CI build fails at
project configuration ("Gradle build failed due to Java/Gradle
incompatibility"). This breaks main and every open mobile PR. The last
green Android run (18:09Z today) was on the 24.04 image, which defaults
to JDK 17.
This pins Temurin JDK 17 with `actions/setup-java` (SHA-pinned to
v6.1.0) for the Android lane only. Other lanes are unchanged.
### Validation
- The pinned `actions/setup-java` SHA matches the upstream `v6.1.0` tag.
- This PR's own Android lane is the end-to-end check.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Signed-off-by: Tom Brow <tomb@squareup.com>
Co-authored-by: Tom Brow <tomb@squareup.com>
Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@buzz.block.builderlab.xyz>
279 lines
11 KiB
YAML
279 lines
11 KiB
YAML
name: CI / Clients
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
web:
|
|
required: true
|
|
type: boolean
|
|
mobile:
|
|
required: true
|
|
type: boolean
|
|
lane:
|
|
required: true
|
|
type: string
|
|
outputs:
|
|
web_result:
|
|
value: ${{ jobs.results.outputs.web_result }}
|
|
mobile_result:
|
|
value: ${{ jobs.results.outputs.mobile_result }}
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
BUZZ_TEST_POSTGRES_PASSWORD: buzz_dev
|
|
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright
|
|
|
|
jobs:
|
|
web:
|
|
name: Web
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
if: inputs.lane == 'required' && (github.event_name == 'push' || inputs.web)
|
|
permissions:
|
|
contents: read
|
|
steps:
|
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
with:
|
|
fetch-depth: 2
|
|
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
|
- name: Get pnpm store directory
|
|
id: pnpm-cache
|
|
run: echo "STORE_PATH=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
|
|
- name: Restore pnpm store cache
|
|
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
|
with:
|
|
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
|
key: pnpm-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
restore-keys: pnpm-${{ runner.os }}-
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Web lint and format
|
|
run: just web-check
|
|
- name: Web build
|
|
run: just web-build
|
|
- name: Save pnpm store cache
|
|
if: github.event_name == 'push'
|
|
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
|
with:
|
|
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
|
key: pnpm-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
|
|
# Mobile lanes run in parallel; the required check reads the combined
|
|
# matrix result. Test shards split files, so each compiles only its own.
|
|
mobile:
|
|
name: Mobile (${{ matrix.name }})
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
if: inputs.lane == 'required' && (github.event_name == 'push' || inputs.mobile)
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- name: Checks
|
|
lane: checks
|
|
- name: Tests 1/3
|
|
lane: test
|
|
shard: 0
|
|
- name: Tests 2/3
|
|
lane: test
|
|
shard: 1
|
|
- name: Tests 3/3
|
|
lane: test
|
|
shard: 2
|
|
- name: Android
|
|
lane: android
|
|
permissions:
|
|
contents: read
|
|
steps:
|
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
with:
|
|
fetch-depth: 2
|
|
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
|
- name: Compute Hermit cache key
|
|
id: hermit-bin-hash
|
|
run: |
|
|
hash="$(find ./bin ! -type d | sort | xargs openssl sha256 | openssl sha256 -r | cut -d' ' -f1)"
|
|
echo "hash=$hash" >> "$GITHUB_OUTPUT"
|
|
- name: Restore Hermit package cache
|
|
id: hermit-cache
|
|
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
|
with:
|
|
path: ~/.cache/hermit/pkg
|
|
key: ${{ runner.os }}-hermit-cache-${{ steps.hermit-bin-hash.outputs.hash }}
|
|
restore-keys: ${{ runner.os }}-hermit-cache-
|
|
- name: Prime Flutter SDK
|
|
run: flutter --version
|
|
- name: Save Hermit package cache
|
|
if: always() && steps.hermit-cache.outputs.cache-hit != 'true'
|
|
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
|
continue-on-error: true
|
|
with:
|
|
path: ~/.cache/hermit/pkg
|
|
key: ${{ runner.os }}-hermit-cache-${{ steps.hermit-bin-hash.outputs.hash }}
|
|
- name: Restore pub cache
|
|
id: pub-cache
|
|
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
|
with:
|
|
path: ~/.pub-cache
|
|
key: pub-${{ runner.os }}-${{ hashFiles('mobile/pubspec.lock') }}
|
|
restore-keys: pub-${{ runner.os }}-
|
|
- name: Install dependencies
|
|
run: cd mobile && flutter pub get
|
|
- name: Save pub cache
|
|
if: always() && steps.pub-cache.outputs.cache-hit != 'true'
|
|
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
|
continue-on-error: true
|
|
with:
|
|
path: ~/.pub-cache
|
|
key: pub-${{ runner.os }}-${{ hashFiles('mobile/pubspec.lock') }}
|
|
- name: Format check
|
|
if: matrix.lane == 'checks'
|
|
run: cd mobile && dart format --output=none --set-exit-if-changed .
|
|
- name: Analyze
|
|
if: matrix.lane == 'checks'
|
|
run: cd mobile && flutter analyze
|
|
- name: Test
|
|
if: matrix.lane == 'test'
|
|
run: /bin/bash scripts/mobile-test-shard.sh ${{ matrix.shard }} 3 --dart-define=BUZZ_PUSH_GATEWAY_URL=https://push.example
|
|
- name: Test native secp256k1 package
|
|
if: matrix.lane == 'checks'
|
|
run: cd mobile/packages/buzz_secp256k1 && dart pub get && dart test
|
|
- name: Test configured authentication domains
|
|
if: matrix.lane == 'checks'
|
|
run: >-
|
|
cd mobile && flutter test
|
|
--dart-define=BUZZ_PUSH_GATEWAY_URL=https://push.example
|
|
--dart-define=BUZZ_AUTH_DOMAINS=buzz.xyz,builderlab.xyz,builderlabstaging.xyz
|
|
test/shared/auth/community_entry_requirements_test.dart
|
|
test/features/invites/invite_join_provider_test.dart
|
|
test/features/onboarding/onboarding_entry_routes_test.dart
|
|
test/shared/hosted/hosted_environment_test.dart
|
|
test/shared/hosted/self_hosted_entry_test.dart
|
|
test/features/onboarding/hosted_app_gate_environment_test.dart
|
|
test/features/onboarding/hosted_journeys_test.dart
|
|
test/features/onboarding/hosted_communities_test.dart
|
|
test/features/pairing/pairing_hosted_handoff_test.dart
|
|
test/shared/agents/remote_agents_test.dart
|
|
test/features/agents
|
|
- name: Test mobile without push configuration
|
|
if: matrix.lane == 'checks'
|
|
run: cd mobile && flutter test test/shared/push/push_unconfigured_build_test.dart
|
|
- name: Test mobile recipe argument forwarding
|
|
if: matrix.lane == 'checks'
|
|
run: /bin/bash scripts/test-mobile-gateway-recipes.sh
|
|
# ubuntu-latest (26.04) defaults to JDK 25, which Gradle 8.14 does not
|
|
# support. Pin the JDK 17 the 24.04 image used.
|
|
- name: Set up JDK 17
|
|
if: matrix.lane == 'android'
|
|
uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
|
|
with:
|
|
distribution: temurin
|
|
java-version: "17"
|
|
- name: Restore Gradle cache
|
|
if: matrix.lane == 'android'
|
|
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
|
with:
|
|
path: |
|
|
~/.gradle/caches
|
|
~/.gradle/wrapper
|
|
key: gradle-${{ runner.os }}-${{ hashFiles('mobile/android/**/*.gradle*', 'mobile/android/gradle/wrapper/gradle-wrapper.properties', 'mobile/pubspec.lock') }}
|
|
restore-keys: gradle-${{ runner.os }}-
|
|
# SDK component and plugin downloads intermittently fail on hosted
|
|
# runners; retry once only for those, so real build failures still fail.
|
|
- name: Build Android debug APK
|
|
if: matrix.lane == 'android'
|
|
run: |
|
|
set -o pipefail
|
|
log="$RUNNER_TEMP/android-build.log"
|
|
if ! just mobile-build-android 2>&1 | tee "$log"; then
|
|
grep -qE 'InstallFailedException|Could not (resolve|GET|download)' "$log"
|
|
just mobile-build-android
|
|
fi
|
|
- name: Test Android JVM units
|
|
if: matrix.lane == 'android'
|
|
run: cd mobile/android && ./gradlew :app:testDebugUnitTest --console=plain
|
|
- name: Save Gradle cache
|
|
if: matrix.lane == 'android' && github.event_name == 'push'
|
|
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
|
continue-on-error: true
|
|
with:
|
|
path: |
|
|
~/.gradle/caches
|
|
~/.gradle/wrapper
|
|
key: gradle-${{ runner.os }}-${{ hashFiles('mobile/android/**/*.gradle*', 'mobile/android/gradle/wrapper/gradle-wrapper.properties', 'mobile/pubspec.lock') }}
|
|
|
|
# The unsigned release build needs nothing from the native lane, so it runs
|
|
# beside it instead of after the simulator tests.
|
|
mobile-swift:
|
|
name: Mobile Swift (${{ matrix.name }})
|
|
runs-on: macos-latest
|
|
timeout-minutes: 45
|
|
if: inputs.lane == 'mobile-swift' && inputs.mobile
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- name: Native
|
|
lane: native
|
|
- name: Release
|
|
lane: release
|
|
steps:
|
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
|
- name: Install Flutter dependencies
|
|
run: cd mobile && flutter pub get
|
|
# `swift test` builds BuzzPushKit; the Release lane covers its release build.
|
|
- name: Test
|
|
if: matrix.lane == 'native'
|
|
run: swift test --package-path mobile/ios/BuzzPushKit
|
|
- name: Test native pagination geometry
|
|
if: matrix.lane == 'native'
|
|
run: /bin/bash scripts/test-mobile-pagination.sh
|
|
- name: Generate iOS build configuration
|
|
if: matrix.lane == 'native'
|
|
run: cd mobile && flutter build ios --simulator --debug --no-pub --config-only
|
|
# Build the complete simulator app and RunnerTests once, in the
|
|
# background, while the simulator boots and runs the native-control
|
|
# scripts. The build also guards Apple Silicon simulator linking (#7646).
|
|
- name: Test native controls and Runner unit tests
|
|
if: matrix.lane == 'native'
|
|
run: |
|
|
device=$(xcrun simctl create "Native tests" "iPhone 16")
|
|
trap 'xcrun simctl shutdown "$device"; xcrun simctl delete "$device"' EXIT
|
|
xcode=(xcodebuild -workspace mobile/ios/Runner.xcworkspace -scheme Runner
|
|
-configuration Debug -destination "platform=iOS Simulator,id=$device"
|
|
CODE_SIGNING_ALLOWED=NO)
|
|
build_log="$RUNNER_TEMP/runner-build.log"
|
|
"${xcode[@]}" build-for-testing > "$build_log" 2>&1 &
|
|
build=$!
|
|
xcrun simctl boot "$device"
|
|
xcrun simctl bootstatus "$device" -b
|
|
/bin/bash scripts/test-mobile-pagination-accessibility.sh "$device"
|
|
/bin/bash scripts/test-mobile-carousel.sh "$device"
|
|
/bin/bash scripts/test-mobile-member-picker.sh "$device"
|
|
/bin/bash scripts/test-mobile-me-agent-accessibility.sh "$device"
|
|
if ! wait "$build"; then
|
|
cat "$build_log"
|
|
exit 1
|
|
fi
|
|
tail -n 5 "$build_log"
|
|
"${xcode[@]}" -parallel-testing-enabled NO -only-testing:RunnerTests \
|
|
test-without-building
|
|
- name: Build complete unsigned iOS release
|
|
if: matrix.lane == 'release'
|
|
run: |
|
|
/bin/bash scripts/test-mobile-gateway-recipes.sh
|
|
cd mobile && flutter build ios --release --no-codesign --no-pub
|
|
|
|
results:
|
|
name: Results
|
|
if: ${{ always() }}
|
|
needs: [web, mobile, mobile-swift]
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
permissions: {}
|
|
outputs:
|
|
web_result: ${{ needs.web.result }}
|
|
mobile_result: ${{ needs.mobile.result }}
|
|
steps:
|
|
- run: echo "Captured client job results"
|