OXYGENHUB
◆ v0.1.7 oxygenhub-android / .flow / pipeline.kdl
4.2 KiB · last changed CI builds on disks of its own for the app's build output and Gradle's cache (refs #28) 7 days ago source blame history raw
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.
9
schema-version 1
10
11
sandbox "android" {
12
    runtime "microvm"
13
    rootfs "cas://blob/d5dabda3166dee2a2fdaca1b245c6e677aa95066beff8b8bb829987cb2fcacd7"
14
    memory-limit "8GiB"
15
    cpu-limit 4
16
    // Loopback only, still offline: Gradle will not start without a
17
    // usable interface for its file-lock listener.
18
    network "loopback"
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
    }
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
    }
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
}
66
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
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"
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"
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
    }
121
    // Firebase's client settings (google-services.json) for alerts (#16).
122
    secret "firebase-config" {
123
        mount-path "/run/secrets/firebase-config"
124
    }
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
}