Skip to content

deps: bump the minor-and-patch group across 3 directories with 1 update #361

deps: bump the minor-and-patch group across 3 directories with 1 update

deps: bump the minor-and-patch group across 3 directories with 1 update #361

Workflow file for this run

name: Test Android Builds
on:
push:
branches: [main]
# No paths filter on pull_request — required status checks need this workflow to
# always trigger so the aggregator can report. find-projects below narrows the
# matrix to only projects whose subtree changed, so docs-only / other-framework
# PRs produce an empty matrix → build job skipped → aggregator passes via
# `result == 'skipped'`.
pull_request:
schedule:
- cron: "0 9 * * 1"
workflow_dispatch:
permissions:
contents: read
# Needed by find-projects' `gh api .../pulls/N/files` call.
pull-requests: read
jobs:
find-projects:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.find.outputs.matrix }}
steps:
- uses: actions/checkout@v6
# Default shallow checkout — we only need the working tree for `find`
# below, not git history. The PR's changed files come from gh api.
- id: find
env:
EVENT_NAME: ${{ github.event_name }}
PR_NUMBER: ${{ github.event.pull_request.number }}
WORKFLOW_FILE: .github/workflows/test-android.yml
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
# Discover any sample with an Android Gradle wrapper. Today: react-native
# samples and native android samples.
ALL=$(find samples -name "gradlew" -not -path "*/node_modules/*" -not -path "*/build/*" -exec dirname {} \; 2>/dev/null | sort)
if [ "$EVENT_NAME" = "pull_request" ]; then
CHANGED=$(gh api --paginate "/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/files" --jq '.[].filename' 2>/dev/null || echo "")
if printf '%s\n' "$CHANGED" | grep -qFx "$WORKFLOW_FILE"; then
FILTERED="$ALL"
else
# For each gradlew dir, walk up to find a package.json. If found (an
# RN sample — gradlew sits under <rn-root>/android/), watch the RN
# root: JS dep changes upstairs affect Android autolinking. If not
# found (a native Android sample), watch the gradlew dir itself.
# Mirrors the "Install JS dependencies (RN samples)" step's walk-up.
FILTERED=$(while IFS= read -r proj; do
[ -z "$proj" ] && continue
watch_root="$proj"
d="$proj"
while [ "$d" != "." ] && [ "$d" != "/" ]; do
if [ -f "$d/package.json" ]; then
watch_root="$d"
break
fi
d=$(dirname "$d")
done
if printf '%s\n' "$CHANGED" | grep -q "^${watch_root}/"; then
echo "$proj"
fi
done <<< "$ALL")
fi
else
FILTERED="$ALL"
fi
MATRIX=$(printf '%s\n' "$FILTERED" | jq -R -s -c 'split("\n") | map(select(. != ""))')
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"
build:
needs: find-projects
if: ${{ needs.find-projects.outputs.matrix != '[]' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
android_dir: ${{ fromJson(needs.find-projects.outputs.matrix) }}
steps:
- uses: actions/checkout@v6
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
distribution: "temurin"
java-version: "17"
- name: Set up Android SDK
# The community `android-actions/setup-android` action isn't on the org's
# third-party action allowlist, so we install Android command-line tools
# ourselves. The build number in the cmdline-tools URL is pinned (Google
# publishes new ones periodically; bump intentionally rather than chasing).
env:
ANDROID_HOME: ${{ runner.temp }}/android-sdk
CMDLINE_TOOLS_ZIP: commandlinetools-linux-11076708_latest.zip
# SHA-256 of the build above as published by Google. Bumping the build
# number requires updating this hash; mismatch fails the workflow so we
# never silently run a corrupted/poisoned download.
CMDLINE_TOOLS_SHA256: 2d2d50857e4eb553af5a6dc3ad507a17adf43d115264b1afc116f95c92e5e258
run: |
set -euo pipefail
mkdir -p "$ANDROID_HOME/cmdline-tools"
cd "$ANDROID_HOME/cmdline-tools"
curl -fsSL "https://dl.google.com/android/repository/$CMDLINE_TOOLS_ZIP" -o tools.zip
echo "$CMDLINE_TOOLS_SHA256 tools.zip" | sha256sum -c -
unzip -q tools.zip
mv cmdline-tools latest
rm tools.zip
# Expose for subsequent steps (Gradle reads ANDROID_HOME).
{
echo "ANDROID_HOME=$ANDROID_HOME"
echo "ANDROID_SDK_ROOT=$ANDROID_HOME"
} >> "$GITHUB_ENV"
{
echo "$ANDROID_HOME/cmdline-tools/latest/bin"
echo "$ANDROID_HOME/platform-tools"
} >> "$GITHUB_PATH"
# Accept licenses (sdkmanager errors out otherwise).
printf 'y\n%.0s' $(seq 1 50) | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" --licenses > /dev/null
"$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" \
"platform-tools" "platforms;android-36" "build-tools;36.0.0"
# React Native samples need their JS deps installed first so autolinking
# can resolve native modules from node_modules. Detect by walking up to
# the directory that owns package.json.
- uses: actions/setup-node@v6
with:
node-version: "22"
- name: Enable Corepack
run: corepack enable
- name: Install JS dependencies (RN samples)
run: |
# ${{ matrix.android_dir }} is e.g. "samples/react-native/login-pkce/android".
# Walk up until we find a package.json or hit the repo root.
dir="${{ matrix.android_dir }}"
while [ "$dir" != "." ] && [ "$dir" != "/" ]; do
if [ -f "$dir/package.json" ]; then
echo "Installing JS deps in $dir"
(cd "$dir" && yarn install --immutable)
break
fi
dir=$(dirname "$dir")
done
- name: Generate debug keystore
# The committed sample doesn't ship debug.keystore (gitignored).
# Generate a throwaway one so Gradle's `validateSigningDebug` passes.
run: |
keytool -genkeypair -v \
-keystore "${{ matrix.android_dir }}/app/debug.keystore" \
-storepass android -alias androiddebugkey -keypass android \
-keyalg RSA -keysize 2048 -validity 10000 \
-dname "CN=Android Debug,O=Android,C=US"
- name: Cache Gradle
uses: actions/cache@v5
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles(format('{0}/gradle/wrapper/gradle-wrapper.properties', matrix.android_dir), format('{0}/build.gradle*', matrix.android_dir), format('{0}/app/build.gradle*', matrix.android_dir)) }}
restore-keys: gradle-${{ runner.os }}-
- name: assembleDebug
working-directory: ${{ matrix.android_dir }}
run: ./gradlew assembleDebug --no-daemon
# Stable aggregator for branch protection.
all-tests-passed:
name: Android tests passed
needs: build
if: always()
runs-on: ubuntu-latest
steps:
- name: Verify build matrix succeeded
if: needs.build.result != 'success' && needs.build.result != 'skipped'
run: exit 1