Skip to content

Commit

Permalink
Update ci flow
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Pururun authored and Rawa committed Dec 19, 2024
1 parent 907dd71 commit d2dcf05
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 70 deletions.
41 changes: 22 additions & 19 deletions .github/workflows/android-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ jobs:
retention-days: 7

generate-relay-list:
name: Generate relay list
name: Generate relay list # Used by wait for jobs.
needs: prepare
runs-on: ubuntu-latest
container:
Expand Down Expand Up @@ -129,11 +129,16 @@ jobs:

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

- name: Upload
uses: actions/upload-artifact@v4
Expand All @@ -144,7 +149,7 @@ jobs:
retention-days: 7

build-native:
name: Build native
name: Build native # Used by wait for jobs.
needs: prepare
runs-on: ubuntu-latest
container:
Expand All @@ -154,20 +159,16 @@ jobs:
include:
- arch: "x86_64"
abi: "x86_64"
target: "x86_64-linux-android"
task: "cargoBuildX86_64"
task-variant: "X86_64"
- arch: "i686"
abi: "x86"
target: "i686-linux-android"
task: "cargoBuildX86"
task-variant: "X86"
- arch: "aarch64"
abi: "arm64-v8a"
target: "aarch64-linux-android"
task: "cargoBuildArm64"
task-variant: "Arm64"
- arch: "armv7"
abi: "armeabi-v7a"
target: "armv7-linux-androideabi"
task: "cargoBuildArm"
task-variant: "Arm"
steps:
# Fix for HOME path overridden by GH runners when building in containers, see:
# https://github.com/actions/runner/issues/863
Expand Down Expand Up @@ -209,7 +210,7 @@ jobs:
uses: burrunan/gradle-cache-action@v1
with:
job-id: jdk17
arguments: ${{ matrix.task }}
arguments: cargoBuild${{ matrix.task-variant }}
gradle-version: wrapper
build-root-directory: android
execution-only-caches: false
Expand Down Expand Up @@ -306,17 +307,19 @@ jobs:
read-only: ${{ github.ref != 'refs/heads/main' }}

- name: Wait for other jobs (native, relay list)
uses: kachick/wait-other-jobs@v2.0.3
uses: kachick/wait-other-jobs@v3.5.0
with:
wait-seconds-before-first-polling: '1'
wait-list: |
[
{
"workflowFile": "android-app.yml",
"jobName": "build-native"
"jobMatchMode": "prefix",
"jobName": "Build native"
},
{
"workflowFile": "android-app.yml",
"jobName": "generate-relay-list"
"jobName": "Generate relay list"
}
]
Expand Down
10 changes: 5 additions & 5 deletions android/BuildInstructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,10 @@ Linux distro:

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

cd android-ndk-r27b
cd android-ndk-r27c
export ANDROID_NDK_HOME="$PWD"
```

Expand Down Expand Up @@ -162,15 +162,15 @@ Run the following command to download wireguard-go-rs submodule: `git submodule
### Debug build
Run the following command to build a debug build:
```bash
../android/build-apk.sh --dev-build
../android/build.sh --dev-build
```

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

## Configure signing key
Expand Down
45 changes: 26 additions & 19 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ plugins {
alias(libs.plugins.kotlin.parcelize)
alias(libs.plugins.kotlin.ksp)
alias(libs.plugins.compose)
alias(libs.plugins.protobuf.core)
alias(libs.plugins.rust.android.gradle)

id(Dependencies.junit5AndroidPluginId) version Versions.junit5Plugin
Expand Down Expand Up @@ -240,16 +241,14 @@ android {

createDistBundle.dependsOn("bundle$capitalizedVariantName")

// Ensure we have relay list ready before merging assets.
tasks["merge${capitalizedVariantName}Assets"].dependsOn(tasks["generateRelayList"])

// Ensure that we have all the JNI libs before merging them.
tasks["merge${capitalizedVariantName}JniLibFolders"].apply {
dependsOn(tasks["generateRelayList"])
dependsOn("cargoBuild")
}
tasks["merge${capitalizedVariantName}JniLibFolders"].dependsOn("cargoBuild")

// Ensure all relevant assemble tasks depend on our ensure task.
tasks["assemble$capitalizedVariantName"].apply {
dependsOn(tasks["ensureValidVersionCode"])
}
tasks["assemble$capitalizedVariantName"].dependsOn(tasks["ensureValidVersionCode"])
}
}

Expand Down Expand Up @@ -291,7 +290,6 @@ cargo {
add("--locked")
}
}
exec = { spec, _ -> println(spec.commandLine) }
}

tasks.register<Exec>("generateRelayList") {
Expand All @@ -308,25 +306,34 @@ tasks.register<Exec>("generateRelayList") {
doLast {
val output = standardOutput as ByteArrayOutputStream
// Create file if needed
File("$extraAssetsDirectory").mkdirs()
File("$extraAssetsDirectory/relays.json").createNewFile()
FileOutputStream("$extraAssetsDirectory/relays.json").use { it.write(output.toByteArray()) }

// Old ensure exists tasks
if (!relayListPath.exists()) {
throw GradleException("Failed to generate relay list")
}
relayListPath.parentFile.mkdirs()
relayListPath.createNewFile()
FileOutputStream(relayListPath).use { it.write(output.toByteArray()) }
}
}

tasks.register<Exec>("cargoClean") {
workingDir = File(repoRootPath)
commandLine("cargo", "clean")
}

if (
gradleLocalProperties(rootProject.projectDir, providers)
.getProperty("CLEAN_CARGO_BUILD")
?.toBoolean() != false
) {
tasks["clean"].dependsOn("cargoClean")
}

// This is a hack and will not work correctly under all scenarios.
// See DROID-1696 for how we can improve this.
fun isReleaseBuild() =
gradle.startParameter.getTaskNames().any { it.contains("release", ignoreCase = true) }

fun isAlphaOrDevBuild() : Boolean {
fun isAlphaOrDevBuild(): Boolean {
val localProperties = gradleLocalProperties(rootProject.projectDir, providers)
val versionName = generateVersionName(localProperties)
return versionName.contains("dev", ignoreCase = true) ||
versionName.contains("alpha", ignoreCase = true)
return versionName.contains("dev") || versionName.contains("alpha")
}

androidComponents {
Expand Down
1 change: 0 additions & 1 deletion android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ plugins {

alias(libs.plugins.detekt) apply true
alias(libs.plugins.dependency.versions) apply true

}

buildscript {
Expand Down
6 changes: 0 additions & 6 deletions android/build-apk.sh → android/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,12 @@ if [[ "$BUILD_TYPE" == "release" ]]; then
BUNDLE_TASKS+=(createPlayDevmoleReleaseDistBundle createPlayStagemoleReleaseDistBundle)
elif [[ "$PRODUCT_VERSION" == *"-alpha"* ]]; then
echo "Removing old Rust build artifacts"
cargo clean
GRADLE_TASKS+=(createPlayStagemoleReleaseDistApk)
BUNDLE_TASKS+=(createPlayStagemoleReleaseDistBundle)
PLAY_PUBLISH_TASKS=(publishPlayStagemoleReleaseBundle)
else
cargo clean
fi
fi

pushd "$SCRIPT_DIR"

# Fallback to the system-wide gradle command if the gradlew script is removed.
# It is removed by the F-Droid build process before the build starts.
if [ -f "gradlew" ]; then
Expand All @@ -76,7 +71,6 @@ else
fi

$GRADLE_CMD --console plain clean
popd

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

Expand Down
2 changes: 1 addition & 1 deletion android/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# -v $GRADLE_CACHE_VOLUME_NAME:/root/.gradle:Z \
# -v $ANDROID_CREDENTIALS_DIR:/build/android/credentials:Z \
# -v /path/to/repository_root:/build:Z \
# mullvadvpn-app-build-android ./build-apk.sh --dev-build
# mullvadvpn-app-build-android ./android/build.sh --dev-build
#
# See the base image Dockerfile in the repository root (../../Dockerfile)
# for more information.
Expand Down
24 changes: 17 additions & 7 deletions android/docs/BuildInstructions.macos.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ brew install --cask android-studio

Install the following packages:
```bash
brew install protobuf gcc go openjdk@17 rustup-init
brew install protobuf gcc go openjdk@17 rustup-init python3
```

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

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

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

## 4. Debug build

### Android Studio

Create the file `android/local.properties` if it does not exist and add the following line:

```bash
rust.pythonCommand=/opt/homebrew/bin/python3
```

You should now be able to run the app directly from Android Studio.

### `android/build.sh`

Run the build script in the root of the project to assemble all the native libraries and the app:

```bash
./android/build-apk.sh --dev-build
./android/build.sh --dev-build
```

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

Your native binaries have now been built, any subsequent builds that does not have changes to the
native code can be done in Android Studio or using gradle.

# Build options and configuration

For configuring signing or options to your build continue with the general [build instructions](../BuildInstructions.md).
Expand Down
16 changes: 7 additions & 9 deletions android/docs/DebugInstructions.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
## Debugging the native libraries in Android Studio with LLDB

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

NOTE: When running LLDB, Android Studio can sometimes get into a state where it will try to
connect to the debugger when running the app normally, which blocks the app from starting.
Expand Down
2 changes: 1 addition & 1 deletion building/android-container-image.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ghcr.io/mullvad/mullvadvpn-app-build-android:7b6bc0f44
ghcr.io/mullvad/mullvadvpn-app-build-android:3ac5745b0
2 changes: 1 addition & 1 deletion building/containerized-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ case $platform in
shift 1
;;
android)
build_command=("./android/build-apk.sh")
build_command=("./android/build.sh")
shift 1
;;
*)
Expand Down
4 changes: 3 additions & 1 deletion wireguard-go-rs/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ fn build_android_dynamic_lib(daita: bool) -> anyhow::Result<()> {
// or if the libwg.so file has been changed. The latter is required since the
// libwg.so file could be deleted. It however means that this build will need
// to run two times before it is properly cached.
// FIXME: Figure out a way to do this better. This is tracked in DROID-1697.
println!(
"cargo::rerun-if-changed={}",
android_output_path(target)?.join("libwg.so").display()
Expand Down Expand Up @@ -232,7 +233,8 @@ fn android_move_binary(binary: &Path, output: &Path) -> anyhow::Result<()> {
std::fs::create_dir_all(parent_of_output)?;

let mut copy_command = Command::new("cp");
// P command is required to not rebuild this module everytime
// -p command is required to preserve ownership and timestamp of the file to prevent a
// rebuild of this module everytime.
copy_command
.arg("-p")
.arg(binary.to_str().unwrap())
Expand Down

0 comments on commit d2dcf05

Please sign in to comment.