| 8a657957 Andy McCall ↶ |
1 |
// The OxygenHub Android app's pipeline (OxygenFlow, #19). Every push runs |
| 2 |
// the unit tests with coverage and a debug build in OxygenFlow's Android |
| 3 |
// image, with no network: the JDK, the Android SDK and NDK, Gradle, |
| 4 |
// cargo-ndk, rust-core's crates and the app's Gradle dependencies are all |
| 5 |
// in the image (oxygenflow/images/android). Rebuild and re-pin it when the |
| 6 |
// app's SDK, Gradle or dependency versions change, or rust-core's |
| 7 |
// Cargo.lock does. Locally, ./gradlew :app:createDebugUnitTestCoverageReport |
| 8 |
// runs the same tests. |
| 9481bfa7 Andy McCall ↶ |
9 |
schema-version 1 |
| 10 |
|
| 8a657957 Andy McCall ↶ |
11 |
sandbox "android" { |
| 12 |
runtime "microvm" |
| b610bc6e Andy McCall ↶ |
13 |
rootfs "cas://blob/d5dabda3166dee2a2fdaca1b245c6e677aa95066beff8b8bb829987cb2fcacd7" |
| 8a657957 Andy McCall ↶ |
14 |
memory-limit "8GiB" |
| 15 |
cpu-limit 4 |
| 03f2c036 Andy McCall ↶ |
16 |
// Loopback only, still offline: Gradle will not start without a |
| 17 |
// usable interface for its file-lock listener. |
| 18 |
network "loopback" |
| 8a657957 Andy McCall ↶ |
19 |
// Gradle reads dependencies from the image's read-only cache and |
| 20 |
// writes its own state under /tmp. |
| 21 |
env { |
| 22 |
ANDROID_HOME "/opt/android-sdk" |
| 23 |
JAVA_HOME "/usr/lib/jvm/java-17-openjdk-amd64" |
| 24 |
GRADLE_RO_DEP_CACHE "/opt/gradle-home/caches" |
| 25 |
GRADLE_USER_HOME "/tmp/gradle" |
| 26 |
CARGO_INCREMENTAL "0" |
| 27 |
} |
| 28 |
} |
| 29 |
|
| 30 |
job "test" { |
| 31 |
sandbox "android" |
| 32 |
timeout "60m" |
| 33 |
// rust-core (with oxy-core and the runner) for two ABIs is most of the |
| 34 |
// build: kept from the last passing run, so only what changed builds. |
| 35 |
mount { |
| 36 |
source "ephemeral://disk" |
| 37 |
target "/src/rust-core/target" |
| 38 |
size "20GiB" |
| 39 |
cache "rust-core-target" |
| 40 |
key "rust-core/Cargo.lock" |
| 41 |
} |
| bd1d3ad7 Andy McCall ↶ |
42 |
// The workspace has room for the checkout and a little more: the app's |
| 43 |
// build output and Gradle's project cache get disks of their own. |
| 44 |
mount { |
| 45 |
source "ephemeral://disk" |
| 46 |
target "/src/app/build" |
| 47 |
size "8GiB" |
| 48 |
} |
| 49 |
mount { |
| 50 |
source "ephemeral://disk" |
| 51 |
target "/src/.gradle" |
| 52 |
size "2GiB" |
| 53 |
} |
| 8a657957 Andy McCall ↶ |
54 |
exec "bash" "scripts/ci.sh" |
| 55 |
output { |
| 56 |
artifact "junit" { |
| 57 |
path "/src/junit.xml" |
| 58 |
when "always" |
| 59 |
} |
| 60 |
artifact "coverage" { |
| 61 |
path "/src/coverage.xml" |
| 62 |
when "always" |
| 63 |
} |
| 64 |
} |
| 65 |
} |
| bfa2eff0 Andy McCall ↶ |
66 |
|
| 23279b95 Andy McCall ↶ |
67 |
// The release's secrets checked in seconds, with no build (#7): the |
| 68 |
// keystore's SHA-256, the key its password opens and Firebase's JSON. |
| 69 |
// By hand only: oh run start --job release-check. |
| 70 |
job "release-check" { |
| 71 |
sandbox "android" |
| 72 |
timeout "5m" |
| 73 |
on { |
| 74 |
manual |
| 75 |
} |
| 76 |
secret "android-keystore" { |
| 77 |
mount-path "/run/secrets/android-keystore" |
| 78 |
} |
| 79 |
secret "android-keystore-password" { |
| 80 |
mount-path "/run/secrets/android-keystore-password" |
| 81 |
} |
| 82 |
secret "firebase-config" { |
| 83 |
mount-path "/run/secrets/firebase-config" |
| 84 |
} |
| 85 |
exec "bash" "scripts/release-check.sh" |
| 86 |
} |
| 87 |
|
| bfa2eff0 Andy McCall ↶ |
88 |
// A signed release APK when the version in gradle.properties changes (#7), |
| 89 |
// for a release on oxygenhub.io. The keystore and its password are the |
| 90 |
// repository's secrets, mounted as files (never in the environment). |
| 91 |
job "release" { |
| 92 |
sandbox "android" |
| 93 |
timeout "60m" |
| 94 |
depends-on "test" |
| 95 |
scope "gradle.properties" |
| 96 |
mount { |
| 97 |
source "ephemeral://disk" |
| 98 |
target "/src/rust-core/target" |
| 99 |
size "20GiB" |
| 100 |
cache "rust-core-target" |
| 101 |
key "rust-core/Cargo.lock" |
| bd1d3ad7 Andy McCall ↶ |
102 |
} |
| 103 |
// The workspace has room for the checkout and a little more: the app's |
| 104 |
// build output and Gradle's project cache get disks of their own. |
| 105 |
mount { |
| 106 |
source "ephemeral://disk" |
| 107 |
target "/src/app/build" |
| 108 |
size "8GiB" |
| 109 |
} |
| 110 |
mount { |
| 111 |
source "ephemeral://disk" |
| 112 |
target "/src/.gradle" |
| 113 |
size "2GiB" |
| bfa2eff0 Andy McCall ↶ |
114 |
} |
| 115 |
secret "android-keystore" { |
| 116 |
mount-path "/run/secrets/android-keystore" |
| 117 |
} |
| 118 |
secret "android-keystore-password" { |
| 119 |
mount-path "/run/secrets/android-keystore-password" |
| 120 |
} |
| aa21eb5e Andy McCall ↶ |
121 |
// Firebase's client settings (google-services.json) for alerts (#16). |
| 122 |
secret "firebase-config" { |
| 123 |
mount-path "/run/secrets/firebase-config" |
| 124 |
} |
| bfa2eff0 Andy McCall ↶ |
125 |
exec "bash" "scripts/release.sh" |
| 126 |
output { |
| 127 |
artifact "oxygenhub-android-universal.apk" { |
| 128 |
path "/src/dist/oxygenhub-android-universal.apk" |
| 129 |
} |
| 130 |
artifact "SHA256SUMS" { |
| 131 |
path "/src/dist/SHA256SUMS" |
| 132 |
} |
| 133 |
} |
| 134 |
} |