Add debug build artifacts and download links to PR workflow

Let reviewers download and test PR changes on a device without building
locally. A sticky PR comment links directly to the artifacts page.

Closes #52

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Doug Borg
2026-02-14 19:41:13 -07:00
parent 9ae7d9c894
commit 8a759e88e9

View File

@@ -24,3 +24,127 @@ jobs:
- name: Test
run: flutter test
build-debug-apk:
name: Build Debug APK
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
- run: flutter pub get
- name: Generate icons and splash screens
run: |
dart run flutter_launcher_icons
dart run flutter_native_splash:create
- name: Build debug APK
run: flutter build apk --debug
- name: Upload debug APK
uses: actions/upload-artifact@v4
with:
name: debug-apk
path: build/app/outputs/flutter-apk/app-debug.apk
if-no-files-found: error
retention-days: 14
build-ios-simulator:
name: Build iOS Simulator
runs-on: macos-26
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v5
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
- run: flutter pub get
- name: Generate icons and splash screens
run: |
dart run flutter_launcher_icons
dart run flutter_native_splash:create
- name: Build iOS simulator app
run: flutter build ios --debug --simulator
- name: Zip Runner.app
run: cd build/ios/iphonesimulator && zip -r "$GITHUB_WORKSPACE/Runner.app.zip" Runner.app
- name: Upload simulator build
uses: actions/upload-artifact@v4
with:
name: ios-simulator
path: Runner.app.zip
if-no-files-found: error
retention-days: 14
comment-artifacts:
name: Post Artifact Links
needs: [build-debug-apk, build-ios-simulator]
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' && !cancelled()
permissions:
pull-requests: write
steps:
- uses: actions/github-script@v7
continue-on-error: true
env:
APK_RESULT: ${{ needs.build-debug-apk.result }}
IOS_RESULT: ${{ needs.build-ios-simulator.result }}
with:
script: |
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}#artifacts`;
const apkOk = process.env.APK_RESULT === 'success';
const iosOk = process.env.IOS_RESULT === 'success';
const lines = ['## Debug builds', ''];
if (apkOk || iosOk) {
lines.push(`Download from the [artifacts page](${runUrl}):`);
if (apkOk) lines.push('- **debug-apk** — install on Android device/emulator');
if (iosOk) lines.push('- **ios-simulator** — unzip and install with `xcrun simctl install booted Runner.app`');
}
if (!apkOk || !iosOk) {
const failed = [];
if (!apkOk) failed.push('Android APK');
if (!iosOk) failed.push('iOS simulator');
lines.push('', `**Failed:** ${failed.join(', ')} — check the [workflow run](${runUrl}) for details.`);
}
const body = lines.join('\n');
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const existing = comments.find(c => c.body.startsWith('## Debug builds'));
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
}