summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJonatan Rhodin <jonatan.rhodin@mullvad.net>2025-01-28 10:35:56 +0100
committerJonatan Rhodin <jonatan.rhodin@mullvad.net>2025-01-28 10:35:56 +0100
commitad6080818b68537c60ac00a232bf7458ce29b0eb (patch)
treebe88797d5613567c2e1806fbbf82d438bd720dc3
parent95e51f000f8259dfb3e5966831bd102937e6e935 (diff)
parent1fd061cc62fa0b3deb56302d8d74d513345c3037 (diff)
downloadmullvadvpn-ad6080818b68537c60ac00a232bf7458ce29b0eb.tar.xz
mullvadvpn-ad6080818b68537c60ac00a232bf7458ce29b0eb.zip
Merge branch 'ensure-relay-list-is-built-and-bundled-in-a-reproducible-way-droid-1674'
-rw-r--r--.github/workflows/android-app.yml53
-rw-r--r--android/app/build.gradle.kts44
-rw-r--r--android/buildSrc/src/main/kotlin/Utils.kt17
-rwxr-xr-xandroid/scripts/update-lockfile.sh1
-rw-r--r--android/service/build.gradle.kts13
-rw-r--r--android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt5
-rw-r--r--android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/util/ContextExtensions.kt20
-rwxr-xr-xprepare-release.sh9
8 files changed, 61 insertions, 101 deletions
diff --git a/.github/workflows/android-app.yml b/.github/workflows/android-app.yml
index 862e2e507d..95383d4ffc 100644
--- a/.github/workflows/android-app.yml
+++ b/.github/workflows/android-app.yml
@@ -104,49 +104,6 @@ jobs:
if-no-files-found: error
retention-days: 7
- generate-relay-list:
- name: Generate relay list # Used by wait for jobs.
- needs: prepare
- runs-on: ubuntu-latest
- container:
- image: ${{ needs.prepare.outputs.container_image }}
- steps:
- # Fix for HOME path overridden by GH runners when building in containers, see:
- # https://github.com/actions/runner/issues/863
- - name: Fix HOME path
- run: echo "HOME=/root" >> $GITHUB_ENV
-
- - name: Get date
- id: get-date
- shell: bash
- run: echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT
-
- - name: Cache
- uses: actions/cache@v4
- id: cache-relay-list
- with:
- path: android/app/build/extraAssets/relays.json
- key: relay-list-${{ steps.get-date.outputs.date }}
-
- - name: Checkout repository
- if: steps.cache-relay-list.outputs.cache-hit != 'true'
- uses: actions/checkout@v4
- with:
- submodules: true
-
- - name: Generate
- if: steps.cache-relay-list.outputs.cache-hit != 'true'
- shell: bash
- run: ./android/gradlew -p android generateRelayList
-
- - name: Upload
- uses: actions/upload-artifact@v4
- with:
- name: relay-list
- path: android/app/build/extraAssets/relays.json
- if-no-files-found: error
- retention-days: 7
-
build-native:
name: Build native # Used by wait for jobs.
needs: prepare
@@ -311,10 +268,6 @@ jobs:
"workflowFile": "android-app.yml",
"jobMatchMode": "prefix",
"jobName": "Build native"
- },
- {
- "workflowFile": "android-app.yml",
- "jobName": "Generate relay list"
}
]
@@ -324,11 +277,6 @@ jobs:
path: android/app/build/rustJniLibs/android
merge-multiple: true
- - uses: actions/download-artifact@v4
- with:
- name: relay-list
- path: android/app/build/extraAssets
-
- name: Build app
uses: burrunan/gradle-cache-action@v1
with:
@@ -410,7 +358,6 @@ jobs:
arguments: |
${{ matrix.assemble-command }}
-x cargoBuild
- -x generateRelayList
-x mergeOssProdDebugJniLibFolders
-x mergePlayStagemoleDebugJniLibFolders
gradle-version: wrapper
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts
index 409b042d8c..36625c50e4 100644
--- a/android/app/build.gradle.kts
+++ b/android/app/build.gradle.kts
@@ -1,9 +1,7 @@
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
import com.android.build.gradle.internal.tasks.factory.dependsOn
import com.github.triplet.gradle.androidpublisher.ReleaseStatus
-import java.io.ByteArrayOutputStream
import java.io.FileInputStream
-import java.io.FileOutputStream
import java.util.Properties
import org.gradle.internal.extensions.stdlib.capitalized
@@ -21,8 +19,7 @@ plugins {
}
val repoRootPath = rootProject.projectDir.absoluteFile.parentFile.absolutePath
-val extraAssetsDirectory = layout.buildDirectory.dir("extraAssets").get()
-val relayListPath = extraAssetsDirectory.file("relays.json").asFile
+val relayListDirectory = file("$repoRootPath/dist-assets/relays/").absolutePath
val defaultChangelogAssetsDirectory = "$repoRootPath/android/src/main/play/release-notes/"
val rustJniLibsDir = layout.buildDirectory.dir("rustJniLibs/android").get()
@@ -133,7 +130,7 @@ android {
gradleLocalProperties(rootProject.projectDir, providers)
.getOrDefault("OVERRIDE_CHANGELOG_DIR", defaultChangelogAssetsDirectory)
- assets.srcDirs(extraAssetsDirectory, changelogDir)
+ assets.srcDirs(relayListDirectory, changelogDir)
}
}
@@ -240,9 +237,6 @@ 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 {
// This is required for the merge task to run every time the .so files are updated.
@@ -265,8 +259,10 @@ junitPlatform {
}
cargo {
+ val localProperties = gradleLocalProperties(rootProject.projectDir, providers)
val isReleaseBuild = isReleaseBuild()
- val enableApiOverride = !isReleaseBuild || isAlphaOrDevBuild()
+ val enableApiOverride =
+ !isReleaseBuild || isDevBuild(localProperties) || isAlphaBuild(localProperties)
module = repoRootPath
libname = "mullvad-jni"
// All available targets:
@@ -300,23 +296,6 @@ cargo {
}
}
-tasks.register<Exec>("generateRelayList") {
- workingDir = File(repoRootPath)
- standardOutput = ByteArrayOutputStream()
-
- onlyIf { isReleaseBuild() || !relayListPath.exists() }
-
- commandLine("cargo", "run", "-p", "mullvad-api", "--bin", "relay_list")
-
- doLast {
- val output = standardOutput as ByteArrayOutputStream
- // Create file if needed
- relayListPath.parentFile.mkdirs()
- relayListPath.createNewFile()
- FileOutputStream(relayListPath).use { it.write(output.toByteArray()) }
- }
-}
-
tasks.register<Exec>("cargoClean") {
workingDir = File(repoRootPath)
commandLine("cargo", "clean")
@@ -330,19 +309,6 @@ if (
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) || it.contains("fdroid", ignoreCase = true)
- }
-
-fun isAlphaOrDevBuild(): Boolean {
- val localProperties = gradleLocalProperties(rootProject.projectDir, providers)
- val versionName = generateVersionName(localProperties)
- return versionName.contains("dev") || versionName.contains("alpha")
-}
-
androidComponents {
beforeVariants { variantBuilder ->
variantBuilder.enable =
diff --git a/android/buildSrc/src/main/kotlin/Utils.kt b/android/buildSrc/src/main/kotlin/Utils.kt
index af00586bea..514d511c03 100644
--- a/android/buildSrc/src/main/kotlin/Utils.kt
+++ b/android/buildSrc/src/main/kotlin/Utils.kt
@@ -1,6 +1,23 @@
import java.util.*
import org.gradle.api.Project
+// This is a hack and will not work correctly under all scenarios.
+// See DROID-1696 for how we can improve this.
+fun Project.isReleaseBuild() =
+ gradle.startParameter.getTaskNames().any {
+ it.contains("release", ignoreCase = true) || it.contains("fdroid", ignoreCase = true)
+ }
+
+fun Project.isAlphaBuild(localProperties: Properties): Boolean {
+ val versionName = generateVersionName(localProperties)
+ return versionName.contains("alpha")
+}
+
+fun Project.isDevBuild(localProperties: Properties): Boolean {
+ val versionName = generateVersionName(localProperties)
+ return versionName.contains("-dev-")
+}
+
fun Project.generateVersionCode(localProperties: Properties): Int {
return localProperties.getProperty("OVERRIDE_VERSION_CODE")?.toIntOrNull()
?: execVersionCodeCargoCommand()
diff --git a/android/scripts/update-lockfile.sh b/android/scripts/update-lockfile.sh
index 0c20ae31c3..9c08ff80a0 100755
--- a/android/scripts/update-lockfile.sh
+++ b/android/scripts/update-lockfile.sh
@@ -20,7 +20,6 @@ GRADLE_TASKS=(
"lint"
)
EXCLUDED_GRADLE_TASKS=(
- "-xgenerateRelayList"
"-xcargoBuild"
)
diff --git a/android/service/build.gradle.kts b/android/service/build.gradle.kts
index 717e2c6ef7..8c9f0034cb 100644
--- a/android/service/build.gradle.kts
+++ b/android/service/build.gradle.kts
@@ -1,3 +1,5 @@
+import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
+
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
@@ -9,7 +11,16 @@ android {
compileSdk = Versions.compileSdkVersion
buildToolsVersion = Versions.buildToolsVersion
- defaultConfig { minSdk = Versions.minSdkVersion }
+ defaultConfig {
+ minSdk = Versions.minSdkVersion
+ val localProperties = gradleLocalProperties(rootProject.projectDir, providers)
+ val shouldRequireBundleRelayFile = isReleaseBuild() && !isDevBuild(localProperties)
+ buildConfigField(
+ "Boolean",
+ "REQUIRE_BUNDLED_RELAY_FILE",
+ shouldRequireBundleRelayFile.toString(),
+ )
+ }
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
index e4c8eba3c6..3c26ad89de 100644
--- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
+++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
@@ -220,7 +220,10 @@ class MullvadVpnService : TalpidVpnService() {
}
private fun Context.prepareFiles() {
- extractAndOverwriteIfAssetMoreRecent(RELAY_LIST_ASSET_NAME)
+ extractAndOverwriteIfAssetMoreRecent(
+ RELAY_LIST_ASSET_NAME,
+ BuildConfig.REQUIRE_BUNDLED_RELAY_FILE,
+ )
}
companion object {
diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/util/ContextExtensions.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/util/ContextExtensions.kt
index 51240fa16d..b4d50caa25 100644
--- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/util/ContextExtensions.kt
+++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/util/ContextExtensions.kt
@@ -1,23 +1,31 @@
package net.mullvad.mullvadvpn.service.util
import android.content.Context
+import co.touchlab.kermit.Logger
import java.io.File
+import java.io.FileNotFoundException
import java.io.FileOutputStream
-fun Context.extractAndOverwriteIfAssetMoreRecent(assetName: String) {
+fun Context.extractAndOverwriteIfAssetMoreRecent(assetName: String, requireAssetFile: Boolean) {
val forceOverwriteIfMoreRecent = lastUpdatedTime() > File(filesDir, assetName).lastModified()
val destination = File(filesDir, assetName)
if (!destination.exists() || forceOverwriteIfMoreRecent) {
- extractFile(assetName, destination)
+ extractFile(assetName, destination, requireAssetFile)
}
}
private fun Context.lastUpdatedTime(): Long =
packageManager.getPackageInfo(packageName, 0).lastUpdateTime
-private fun Context.extractFile(asset: String, destination: File) {
- val destinationStream = FileOutputStream(destination)
- assets.open(asset).copyTo(destinationStream)
- destinationStream.close()
+private fun Context.extractFile(asset: String, destination: File, requireAssetFile: Boolean) {
+ if (assets.list("")?.contains(asset) == true) {
+ val destinationStream = FileOutputStream(destination)
+ assets.open(asset).copyTo(destinationStream)
+ destinationStream.close()
+ } else if (requireAssetFile) {
+ throw FileNotFoundException("Asset $asset not found")
+ } else {
+ Logger.i("Asset $asset not found")
+ }
}
diff --git a/prepare-release.sh b/prepare-release.sh
index b1e7da8f96..4170b0fbe9 100755
--- a/prepare-release.sh
+++ b/prepare-release.sh
@@ -66,6 +66,15 @@ if [[ "$ANDROID" == "true" &&
exit 1
fi
+if [[ "$ANDROID" == "true" ]]; then
+ echo "Generate relays.json"
+ mkdir dist-assets/relays
+ cargo run -q -p mullvad-api --bin relay_list > dist-assets/relays/relays.json
+
+ git commit -S -m "Add relay list to bundle with $PRODUCT_VERSION" \
+ dist-assets/relays/relays.json
+fi
+
if [[ "$DESKTOP" == "true" ]]; then
echo "$PRODUCT_VERSION" > dist-assets/desktop-product-version.txt
git commit -S -m "Update desktop app version to $PRODUCT_VERSION" \