-
Notifications
You must be signed in to change notification settings - Fork 27
137 lines (120 loc) · 5.01 KB
/
Copy pathandroid-apk-build.yml
File metadata and controls
137 lines (120 loc) · 5.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
name: Android APK Build
permissions:
contents: write
on:
push:
branches: [main, dev]
paths: ['app/**']
pull_request:
branches: [main, dev]
paths: ['app/**']
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
# A cloud build is a poll, not a compile, so anything approaching this is a
# hang. The previous local build had no limit and sat for hours.
timeout-minutes: 60
defaults:
run:
working-directory: ./app
steps:
- name: Setup repo
uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v4.0.2
with:
node-version: 20.x
cache: 'npm'
cache-dependency-path: ./app/package-lock.json
# No JDK or Android SDK: EAS compiles this in the cloud. Installing a
# toolchain the runner never uses cost minutes on every run.
- name: Setup Expo
uses: expo/expo-github-action@v8
with:
expo-version: latest
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
- name: Install dependencies
run: npm ci
- name: Initialize EAS
run: eas init --force --non-interactive
# Cloud build. `--local` compiled the whole app on a 2-core runner, which
# took hours and routinely had to be cancelled.
# Cheap (a few seconds) and often the fastest way to see why the previous
# attempt failed, without waiting out another full build.
- name: Report the previous Android build
continue-on-error: true
run: |
eas build:list --platform android --limit 3 --non-interactive --json \
| jq '.[] | {id, status, error, createdAt}'
- name: Build Android APK
run: |
# `set +e`, not just `set -uo pipefail`: GitHub runs the step as
# `bash -e`, so without this the script aborts on the failing build and
# the diagnostics below never run.
set +e
eas build --platform android --profile local --non-interactive --wait --json \
> "$RUNNER_TEMP/build.json"
rc=$?
if [ $rc -ne 0 ]; then
# A failed cloud build otherwise reports only "Build failed" here, with
# the actual Gradle error visible solely on expo.dev. Print it.
echo "::group::EAS build result"; cat "$RUNNER_TEMP/build.json" || true; echo "::endgroup::"
echo "::group::Last Android build on EAS"
eas build:list --platform android --limit 1 --non-interactive --json \
| jq '.[0] | {id, status, error, createdAt}'
echo "::endgroup::"
exit $rc
fi
url=$(jq -r '.[0].artifacts.buildUrl // .[0].artifacts.applicationArchiveUrl' \
"$RUNNER_TEMP/build.json")
if [ -z "$url" ] || [ "$url" = "null" ]; then
echo "No artifact URL in the build result:"; cat "$RUNNER_TEMP/build.json"; exit 1
fi
curl -fsSL -o "${{ github.workspace }}/app-release.apk" "$url"
ls -la "${{ github.workspace }}/app-release.apk"
# Attached to every run, so a build off any branch is installable without
# needing a GitHub release.
- name: Upload APK as a workflow artifact
uses: actions/upload-artifact@v4
with:
name: chronicle-android-apk
path: ${{ github.workspace }}/app-release.apk
retention-days: 30
- name: Generate release tag
id: tag
run: |
echo "RELEASE_TAG=android-v1.0.0-$(date +'%Y%m%d-%H%M%S')" >> $GITHUB_OUTPUT
echo "RELEASE_NAME=Friend Lite Android $(date +'%Y-%m-%d %H:%M:%S')" >> $GITHUB_OUTPUT
echo "BUILD_TIME=$(date +'%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_OUTPUT
- name: Create Release
id: create_release
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.tag.outputs.RELEASE_TAG }}
release_name: ${{ steps.tag.outputs.RELEASE_NAME }}
body: |
## 📱 Android APK Build
**Built from commit:** ${{ github.sha }}
**Branch:** ${{ github.ref_name }}
**Build time:** ${{ steps.tag.outputs.BUILD_TIME }}
Ready to install on Android devices!
draft: false
prerelease: true
# Same condition as Create Release above. Without it this ran on every
# branch with an empty upload_url and failed after the build had already
# succeeded.
- name: Upload Android APK to Release
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ github.workspace }}/app-release.apk
asset_name: chronicle-android.apk
asset_content_type: application/vnd.android.package-archive