Skip to content

Commit ce81126

Browse files
committed
Add full nightly validation
Replace the assemble-only nightly workflow with full JVM, assemble, and Android connected-test validation for main. Open or update a GitHub issue when nightly checks fail so broken main is visible before release work starts.
1 parent 93fabca commit ce81126

2 files changed

Lines changed: 203 additions & 30 deletions

File tree

.github/workflows/nightly-assemble.yml

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
name: Nightly Checks
2+
3+
on:
4+
schedule:
5+
- cron: '0 2 * * *'
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
issues: write
11+
12+
env:
13+
API_LEVEL: 23
14+
ARCH: x86_64
15+
DISK_SIZE: 2048M
16+
17+
jobs:
18+
jvm-and-assemble:
19+
env:
20+
ORG_GRADLE_JVMARGS: "-Xmx5g -XX:MaxMetaspaceSize=1g -Dfile.encoding=UTF-8"
21+
runs-on: ubuntu-latest
22+
timeout-minutes: 60
23+
steps:
24+
- uses: actions/checkout@v5
25+
26+
- uses: actions/setup-java@v5
27+
with:
28+
distribution: temurin
29+
java-version: 17
30+
token: ${{ github.token }}
31+
32+
- name: Gradle cache
33+
uses: gradle/actions/setup-gradle@v5
34+
35+
- name: JVM Tests and Assemble
36+
run: ./gradlew --console=plain spotlessCheck jvmTest assemble
37+
38+
discover-android-modules:
39+
runs-on: ubuntu-latest
40+
outputs:
41+
modules: ${{ steps.discover.outputs.modules }}
42+
steps:
43+
- uses: actions/checkout@v5
44+
45+
- uses: actions/setup-java@v5
46+
with:
47+
distribution: temurin
48+
java-version: 17
49+
token: ${{ github.token }}
50+
51+
- name: Gradle cache
52+
uses: gradle/actions/setup-gradle@v5
53+
54+
- name: Discover Android modules
55+
id: discover
56+
shell: bash
57+
run: |
58+
set -euo pipefail
59+
60+
modules="$(
61+
./gradlew --console=plain tasks --all |
62+
awk -F: '/^composeunstyled-[^:]+:connectedDebugAndroidTest / { print ":" $1 }' |
63+
sort -u
64+
)"
65+
66+
if [ -z "$modules" ]; then
67+
echo "No composeunstyled-* connectedDebugAndroidTest tasks found."
68+
exit 1
69+
fi
70+
71+
modules_json="$(printf '%s\n' "$modules" | jq -R . | jq -s -c .)"
72+
echo "modules=$modules_json" >> "$GITHUB_OUTPUT"
73+
74+
android-tests:
75+
name: ${{ matrix.module }}-android-tests
76+
needs: discover-android-modules
77+
runs-on: ubuntu-latest
78+
timeout-minutes: 60
79+
strategy:
80+
fail-fast: false
81+
matrix:
82+
module: ${{ fromJson(needs.discover-android-modules.outputs.modules) }}
83+
steps:
84+
- name: Enable Hardware Acceleration
85+
run: |
86+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
87+
sudo udevadm control --reload-rules
88+
sudo udevadm trigger --name-match=kvm
89+
90+
- uses: actions/checkout@v5
91+
92+
- uses: actions/setup-java@v5
93+
with:
94+
distribution: temurin
95+
java-version: 17
96+
token: ${{ github.token }}
97+
98+
- name: Gradle cache
99+
uses: gradle/actions/setup-gradle@v5
100+
101+
- name: Restore AVD
102+
uses: actions/cache@v5
103+
id: avd-cache
104+
with:
105+
path: |
106+
~/.android/avd/*
107+
~/.android/adb*
108+
key: avd-${{ env.API_LEVEL }}-${{ env.ARCH }}-${{ env.DISK_SIZE }}
109+
110+
- name: Create AVD
111+
if: steps.avd-cache.outputs.cache-hit != 'true'
112+
uses: reactivecircus/android-emulator-runner@v2
113+
with:
114+
api-level: ${{ env.API_LEVEL }}
115+
arch: ${{ env.ARCH }}
116+
disk-size: ${{ env.DISK_SIZE }}
117+
force-avd-creation: false
118+
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
119+
disable-animations: false
120+
script: echo "Generated AVD snapshot for caching."
121+
122+
- name: Android Tests
123+
uses: reactivecircus/android-emulator-runner@v2
124+
with:
125+
api-level: ${{ env.API_LEVEL }}
126+
arch: ${{ env.ARCH }}
127+
disk-size: ${{ env.DISK_SIZE }}
128+
force-avd-creation: false
129+
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
130+
disable-animations: true
131+
script: ./gradlew --console=plain ${{ matrix.module }}:connectedDebugAndroidTest
132+
133+
report-failure:
134+
needs: [ jvm-and-assemble, discover-android-modules, android-tests ]
135+
if: ${{ always() && (needs.jvm-and-assemble.result == 'failure' || needs.discover-android-modules.result == 'failure' || needs.android-tests.result == 'failure') }}
136+
runs-on: ubuntu-latest
137+
steps:
138+
- name: Open GitHub issue
139+
uses: actions/github-script@v8
140+
with:
141+
script: |
142+
const owner = context.repo.owner;
143+
const repo = context.repo.repo;
144+
const title = 'Nightly checks are failing';
145+
const labels = ['nightly-failure'];
146+
const runUrl = `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}`;
147+
const results = {
148+
'jvm-and-assemble': '${{ needs.jvm-and-assemble.result }}',
149+
'discover-android-modules': '${{ needs.discover-android-modules.result }}',
150+
'android-tests': '${{ needs.android-tests.result }}',
151+
};
152+
153+
const body = [
154+
'Nightly checks failed on `main`.',
155+
'',
156+
`Workflow run: ${runUrl}`,
157+
'',
158+
'Job results:',
159+
...Object.entries(results).map(([job, result]) => `- \`${job}\`: ${result}`),
160+
'',
161+
'Please inspect the failed job logs and fix `main` before cutting a release.',
162+
].join('\n');
163+
164+
const { data: existingIssues } = await github.rest.issues.listForRepo({
165+
owner,
166+
repo,
167+
state: 'open',
168+
labels: labels.join(','),
169+
per_page: 10,
170+
});
171+
const existingIssue = existingIssues.find(issue => issue.title === title);
172+
173+
if (existingIssue) {
174+
await github.rest.issues.createComment({
175+
owner,
176+
repo,
177+
issue_number: existingIssue.number,
178+
body,
179+
});
180+
return;
181+
}
182+
183+
try {
184+
await github.rest.issues.createLabel({
185+
owner,
186+
repo,
187+
name: labels[0],
188+
color: 'd73a4a',
189+
description: 'Main branch nightly validation is failing.',
190+
});
191+
} catch (error) {
192+
if (error.status !== 422) {
193+
throw error;
194+
}
195+
}
196+
197+
await github.rest.issues.create({
198+
owner,
199+
repo,
200+
title,
201+
body,
202+
labels,
203+
});

0 commit comments

Comments
 (0)