Skip to content

Commit d2dcf05

Browse files
PururunRawa
authored andcommitted
Update ci flow
Name of something Add test job Fix space Remove prefix Update wait for other jobs Prefix Move extra native Fix names Resolve all fixes Fix trailing space Remove first 10 seconds wait Clean cargo on gradle clean Fixes based on feedback Simiplify mkdirs Rename build-apk.sh to build.sh ups Create parent Fix generate relay list order refactor Update debug instructions Update ndk documentation Update ndk verison Update build instructions
1 parent 907dd71 commit d2dcf05

11 files changed

+83
-70
lines changed

.github/workflows/android-app.yml

+22-19
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ jobs:
9898
retention-days: 7
9999

100100
generate-relay-list:
101-
name: Generate relay list
101+
name: Generate relay list # Used by wait for jobs.
102102
needs: prepare
103103
runs-on: ubuntu-latest
104104
container:
@@ -129,11 +129,16 @@ jobs:
129129

130130
- name: Generate
131131
if: steps.cache-relay-list.outputs.cache-hit != 'true'
132-
env:
133-
RUSTFLAGS: --deny warnings
134-
run: |
135-
mkdir -p android/app/build/extraAssets
136-
cargo run --bin relay_list > android/app/build/extraAssets/relays.json
132+
uses: burrunan/gradle-cache-action@v1
133+
with:
134+
job-id: jdk17
135+
arguments: generateRelayList
136+
gradle-version: wrapper
137+
build-root-directory: android
138+
execution-only-caches: false
139+
# Disable if logs are hard to follow.
140+
concurrent: true
141+
read-only: ${{ github.ref != 'refs/heads/main' }}
137142

138143
- name: Upload
139144
uses: actions/upload-artifact@v4
@@ -144,7 +149,7 @@ jobs:
144149
retention-days: 7
145150

146151
build-native:
147-
name: Build native
152+
name: Build native # Used by wait for jobs.
148153
needs: prepare
149154
runs-on: ubuntu-latest
150155
container:
@@ -154,20 +159,16 @@ jobs:
154159
include:
155160
- arch: "x86_64"
156161
abi: "x86_64"
157-
target: "x86_64-linux-android"
158-
task: "cargoBuildX86_64"
162+
task-variant: "X86_64"
159163
- arch: "i686"
160164
abi: "x86"
161-
target: "i686-linux-android"
162-
task: "cargoBuildX86"
165+
task-variant: "X86"
163166
- arch: "aarch64"
164167
abi: "arm64-v8a"
165-
target: "aarch64-linux-android"
166-
task: "cargoBuildArm64"
168+
task-variant: "Arm64"
167169
- arch: "armv7"
168170
abi: "armeabi-v7a"
169-
target: "armv7-linux-androideabi"
170-
task: "cargoBuildArm"
171+
task-variant: "Arm"
171172
steps:
172173
# Fix for HOME path overridden by GH runners when building in containers, see:
173174
# https://github.com/actions/runner/issues/863
@@ -209,7 +210,7 @@ jobs:
209210
uses: burrunan/gradle-cache-action@v1
210211
with:
211212
job-id: jdk17
212-
arguments: ${{ matrix.task }}
213+
arguments: cargoBuild${{ matrix.task-variant }}
213214
gradle-version: wrapper
214215
build-root-directory: android
215216
execution-only-caches: false
@@ -306,17 +307,19 @@ jobs:
306307
read-only: ${{ github.ref != 'refs/heads/main' }}
307308

308309
- name: Wait for other jobs (native, relay list)
309-
uses: kachick/wait-other-jobs@v2.0.3
310+
uses: kachick/wait-other-jobs@v3.5.0
310311
with:
312+
wait-seconds-before-first-polling: '1'
311313
wait-list: |
312314
[
313315
{
314316
"workflowFile": "android-app.yml",
315-
"jobName": "build-native"
317+
"jobMatchMode": "prefix",
318+
"jobName": "Build native"
316319
},
317320
{
318321
"workflowFile": "android-app.yml",
319-
"jobName": "generate-relay-list"
322+
"jobName": "Generate relay list"
320323
}
321324
]
322325

android/BuildInstructions.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,10 @@ Linux distro:
118118

119119
```bash
120120
cd "$ANDROID_HOME" # Or some other directory to place the Android NDK
121-
wget https://dl.google.com/android/repository/android-ndk-r27b-linux.zip
122-
unzip android-ndk-r27b-linux.zip
121+
wget https://dl.google.com/android/repository/android-ndk-r27c-linux.zip
122+
unzip android-ndk-r27c-linux.zip
123123

124-
cd android-ndk-r27b
124+
cd android-ndk-r27c
125125
export ANDROID_NDK_HOME="$PWD"
126126
```
127127

@@ -162,15 +162,15 @@ Run the following command to download wireguard-go-rs submodule: `git submodule
162162
### Debug build
163163
Run the following command to build a debug build:
164164
```bash
165-
../android/build-apk.sh --dev-build
165+
../android/build.sh --dev-build
166166
```
167167

168168
### Release build
169169
1. Configure a signing key by following [these instructions](#configure-signing-key).
170170
2. Move, copy or symlink the directory from step 1 to [./credentials/](./credentials/) (`<repository>/android/credentials/`).
171171
3. Run the following command to build:
172172
```bash
173-
../android/build-apk.sh --app-bundle
173+
../android/build.sh --app-bundle
174174
```
175175

176176
## Configure signing key

android/app/build.gradle.kts

+26-19
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ plugins {
1414
alias(libs.plugins.kotlin.parcelize)
1515
alias(libs.plugins.kotlin.ksp)
1616
alias(libs.plugins.compose)
17+
alias(libs.plugins.protobuf.core)
1718
alias(libs.plugins.rust.android.gradle)
1819

1920
id(Dependencies.junit5AndroidPluginId) version Versions.junit5Plugin
@@ -240,16 +241,14 @@ android {
240241

241242
createDistBundle.dependsOn("bundle$capitalizedVariantName")
242243

244+
// Ensure we have relay list ready before merging assets.
245+
tasks["merge${capitalizedVariantName}Assets"].dependsOn(tasks["generateRelayList"])
246+
243247
// Ensure that we have all the JNI libs before merging them.
244-
tasks["merge${capitalizedVariantName}JniLibFolders"].apply {
245-
dependsOn(tasks["generateRelayList"])
246-
dependsOn("cargoBuild")
247-
}
248+
tasks["merge${capitalizedVariantName}JniLibFolders"].dependsOn("cargoBuild")
248249

249250
// Ensure all relevant assemble tasks depend on our ensure task.
250-
tasks["assemble$capitalizedVariantName"].apply {
251-
dependsOn(tasks["ensureValidVersionCode"])
252-
}
251+
tasks["assemble$capitalizedVariantName"].dependsOn(tasks["ensureValidVersionCode"])
253252
}
254253
}
255254

@@ -291,7 +290,6 @@ cargo {
291290
add("--locked")
292291
}
293292
}
294-
exec = { spec, _ -> println(spec.commandLine) }
295293
}
296294

297295
tasks.register<Exec>("generateRelayList") {
@@ -308,25 +306,34 @@ tasks.register<Exec>("generateRelayList") {
308306
doLast {
309307
val output = standardOutput as ByteArrayOutputStream
310308
// Create file if needed
311-
File("$extraAssetsDirectory").mkdirs()
312-
File("$extraAssetsDirectory/relays.json").createNewFile()
313-
FileOutputStream("$extraAssetsDirectory/relays.json").use { it.write(output.toByteArray()) }
314-
315-
// Old ensure exists tasks
316-
if (!relayListPath.exists()) {
317-
throw GradleException("Failed to generate relay list")
318-
}
309+
relayListPath.parentFile.mkdirs()
310+
relayListPath.createNewFile()
311+
FileOutputStream(relayListPath).use { it.write(output.toByteArray()) }
319312
}
320313
}
321314

315+
tasks.register<Exec>("cargoClean") {
316+
workingDir = File(repoRootPath)
317+
commandLine("cargo", "clean")
318+
}
319+
320+
if (
321+
gradleLocalProperties(rootProject.projectDir, providers)
322+
.getProperty("CLEAN_CARGO_BUILD")
323+
?.toBoolean() != false
324+
) {
325+
tasks["clean"].dependsOn("cargoClean")
326+
}
327+
328+
// This is a hack and will not work correctly under all scenarios.
329+
// See DROID-1696 for how we can improve this.
322330
fun isReleaseBuild() =
323331
gradle.startParameter.getTaskNames().any { it.contains("release", ignoreCase = true) }
324332

325-
fun isAlphaOrDevBuild() : Boolean {
333+
fun isAlphaOrDevBuild(): Boolean {
326334
val localProperties = gradleLocalProperties(rootProject.projectDir, providers)
327335
val versionName = generateVersionName(localProperties)
328-
return versionName.contains("dev", ignoreCase = true) ||
329-
versionName.contains("alpha", ignoreCase = true)
336+
return versionName.contains("dev") || versionName.contains("alpha")
330337
}
331338

332339
androidComponents {

android/build.gradle.kts

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ plugins {
1818

1919
alias(libs.plugins.detekt) apply true
2020
alias(libs.plugins.dependency.versions) apply true
21-
2221
}
2322

2423
buildscript {

android/build-apk.sh android/build.sh

-6
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,12 @@ if [[ "$BUILD_TYPE" == "release" ]]; then
5252
BUNDLE_TASKS+=(createPlayDevmoleReleaseDistBundle createPlayStagemoleReleaseDistBundle)
5353
elif [[ "$PRODUCT_VERSION" == *"-alpha"* ]]; then
5454
echo "Removing old Rust build artifacts"
55-
cargo clean
5655
GRADLE_TASKS+=(createPlayStagemoleReleaseDistApk)
5756
BUNDLE_TASKS+=(createPlayStagemoleReleaseDistBundle)
5857
PLAY_PUBLISH_TASKS=(publishPlayStagemoleReleaseBundle)
59-
else
60-
cargo clean
6158
fi
6259
fi
6360

64-
pushd "$SCRIPT_DIR"
65-
6661
# Fallback to the system-wide gradle command if the gradlew script is removed.
6762
# It is removed by the F-Droid build process before the build starts.
6863
if [ -f "gradlew" ]; then
@@ -76,7 +71,6 @@ else
7671
fi
7772

7873
$GRADLE_CMD --console plain clean
79-
popd
8074

8175
$GRADLE_CMD --console plain "${GRADLE_TASKS[@]}"
8276

android/docker/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# -v $GRADLE_CACHE_VOLUME_NAME:/root/.gradle:Z \
99
# -v $ANDROID_CREDENTIALS_DIR:/build/android/credentials:Z \
1010
# -v /path/to/repository_root:/build:Z \
11-
# mullvadvpn-app-build-android ./build-apk.sh --dev-build
11+
# mullvadvpn-app-build-android ./android/build.sh --dev-build
1212
#
1313
# See the base image Dockerfile in the repository root (../../Dockerfile)
1414
# for more information.

android/docs/BuildInstructions.macos.md

+17-7
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ brew install --cask android-studio
1717

1818
Install the following packages:
1919
```bash
20-
brew install protobuf gcc go openjdk@17 rustup-init
20+
brew install protobuf gcc go openjdk@17 rustup-init python3
2121
```
2222

2323
> __*NOTE:*__ Ensure that you setup `openjdk@17` to be the active JDK, follow instructions in
@@ -38,7 +38,7 @@ Open Android Studio -> Tools -> SDK Manager, and install `Android SDK Command-li
3838

3939
Install the necessary Android SDK tools
4040
```bash
41-
~/Library/Android/sdk/cmdline-tools/latest/bin/sdkmanager "platforms;android-35" "build-tools;35.0.0" "platform-tools" "ndk;27.1.12297006"
41+
~/Library/Android/sdk/cmdline-tools/latest/bin/sdkmanager "platforms;android-35" "build-tools;35.0.0" "platform-tools" "ndk;27.2.12479018"
4242
```
4343

4444
Install Android targets
@@ -50,7 +50,7 @@ Export the following environmental variables, and possibly store them for exampl
5050
`~/.zprofile` or `~/.zshrc` file:
5151
```bash
5252
export ANDROID_HOME="$HOME/Library/Android/sdk"
53-
export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/27.1.12297006"
53+
export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/27.2.12479018"
5454
export NDK_TOOLCHAIN_DIR="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin"
5555
export AR_aarch64_linux_android="$NDK_TOOLCHAIN_DIR/llvm-ar"
5656
export AR_armv7_linux_androideabi="$NDK_TOOLCHAIN_DIR/llvm-ar"
@@ -74,10 +74,23 @@ git submodule update --init --recursive --depth=1 wireguard-go-rs
7474
```
7575

7676
## 4. Debug build
77+
78+
### Android Studio
79+
80+
Create the file `android/local.properties` if it does not exist and add the following line:
81+
82+
```bash
83+
rust.pythonCommand=/opt/homebrew/bin/python3
84+
```
85+
86+
You should now be able to run the app directly from Android Studio.
87+
88+
### `android/build.sh`
89+
7790
Run the build script in the root of the project to assemble all the native libraries and the app:
7891

7992
```bash
80-
./android/build-apk.sh --dev-build
93+
./android/build.sh --dev-build
8194
```
8295

8396
Once the build is complete you should receive a message looking similar to this:
@@ -92,9 +105,6 @@ Once the build is complete you should receive a message looking similar to this:
92105
**********************************
93106
```
94107

95-
Your native binaries have now been built, any subsequent builds that does not have changes to the
96-
native code can be done in Android Studio or using gradle.
97-
98108
# Build options and configuration
99109

100110
For configuring signing or options to your build continue with the general [build instructions](../BuildInstructions.md).

android/docs/DebugInstructions.md

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
## Debugging the native libraries in Android Studio with LLDB
22

3-
1. Make sure the native libraries have been built with debug symbols. If using the `build-apk.sh`
4-
script, run `SKIP_STRIPPING=yes ../build-apk.sh --dev-build`.
5-
2. In Android Studio, go to `Run -> Edit configurations...`
6-
3. Make sure the `app` configuration is selected.
7-
4. In the `Debugger` tab, select `Dual (Java + Native)`
8-
5. Start debugging the app as usual from Android Studio. The app should now stop on a SIGURG signal.
9-
6. Select the `LLDB` tab in the debugger. Now you can set breakpoints etc, e.g.
3+
1. In Android Studio, go to `Run -> Edit configurations...`
4+
2. Make sure the `app` configuration is selected.
5+
3. In the `Debugger` tab, select `Dual (Java + Native)`
6+
4. Start debugging the app as usual from Android Studio. The app should now stop on a SIGURG signal.
7+
5. Select the `LLDB` tab in the debugger. Now you can set breakpoints etc, e.g.
108
`breakpoint set -n open_tun`
11-
7. Before continuing run `pro hand -p true -s false SIGURG`
12-
8. Click `Resume Program` and the app will resume until the breakpoint is hit.
9+
6. Before continuing run `pro hand -p true -s false SIGURG`
10+
7. Click `Resume Program` and the app will resume until the breakpoint is hit.
1311

1412
NOTE: When running LLDB, Android Studio can sometimes get into a state where it will try to
1513
connect to the debugger when running the app normally, which blocks the app from starting.

building/android-container-image.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
ghcr.io/mullvad/mullvadvpn-app-build-android:7b6bc0f44
1+
ghcr.io/mullvad/mullvadvpn-app-build-android:3ac5745b0

building/containerized-build.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ case $platform in
1818
shift 1
1919
;;
2020
android)
21-
build_command=("./android/build-apk.sh")
21+
build_command=("./android/build.sh")
2222
shift 1
2323
;;
2424
*)

wireguard-go-rs/build.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ fn build_android_dynamic_lib(daita: bool) -> anyhow::Result<()> {
172172
// or if the libwg.so file has been changed. The latter is required since the
173173
// libwg.so file could be deleted. It however means that this build will need
174174
// to run two times before it is properly cached.
175+
// FIXME: Figure out a way to do this better. This is tracked in DROID-1697.
175176
println!(
176177
"cargo::rerun-if-changed={}",
177178
android_output_path(target)?.join("libwg.so").display()
@@ -232,7 +233,8 @@ fn android_move_binary(binary: &Path, output: &Path) -> anyhow::Result<()> {
232233
std::fs::create_dir_all(parent_of_output)?;
233234

234235
let mut copy_command = Command::new("cp");
235-
// P command is required to not rebuild this module everytime
236+
// -p command is required to preserve ownership and timestamp of the file to prevent a
237+
// rebuild of this module everytime.
236238
copy_command
237239
.arg("-p")
238240
.arg(binary.to_str().unwrap())

0 commit comments

Comments
 (0)