Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 0 additions & 33 deletions .github/workflows/desktop_macos_make.yml

This file was deleted.

128 changes: 128 additions & 0 deletions .github/workflows/desktop_make.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
name: Desktop package apps
on:
workflow_dispatch:
push:

concurrency:
group: desktop-packaging-${{ github.ref }}
cancel-in-progress: false

jobs:
package-macos:
name: Package macOS app
runs-on: macos-latest
env:
ORGANIZATION: ooni
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup (repo action)
uses: ./.github/actions/setup

- name: Cache Gradle
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}-${{ hashFiles('**/gradle.properties','**/*.gradle','**/*.gradle.kts') }}
restore-keys: |
${{ runner.os }}-gradle-

- name: Setup signing and notarization
run: |
echo "Details are not clear" # Placeholder for actual setup steps

- name: Package DMG
run: ./gradlew copyBrandingToCommonResources packageDmg -Porganization=${{ env.ORGANIZATION }}

- name: Sparkle appcast generation
run: ./gradlew generateSparkleAppCast -Porganization=${{ env.ORGANIZATION }}

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: desktopApps-macos-${{ github.run_id }}
path: |
composeApp/build/compose/binaries/main/dmg/OONI Probe-*.dmg
composeApp/build/compose/binaries/main/app/OONI Probe.app
composeApp/macos-appcast.xml
retention-days: 7

package-windows:
name: Package Windows app
runs-on: windows-latest
env:
ORGANIZATION: ooni
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup (repo action)
uses: ./.github/actions/setup

- name: Cache Gradle
uses: actions/cache@v4
with:
path: |
%USERPROFILE%\\.gradle\\caches
%USERPROFILE%\\.gradle\\wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}-${{ hashFiles('**/gradle.properties','**/*.gradle','**/*.gradle.kts') }}
restore-keys: |
${{ runner.os }}-gradle-

- name: Package Exe
shell: pwsh
run: .\gradlew.bat copyBrandingToCommonResources packageExe -Porganization=${{ env.ORGANIZATION }}

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: desktopApps-windows-${{ github.run_id }}
path: |
composeApp/build/compose/binaries/main/exe/OONI Probe-*.exe
retention-days: 7

package-linux:
name: Package Linux app
runs-on: ubuntu-latest
env:
ORGANIZATION: ooni
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup (repo action)
uses: ./.github/actions/setup

- name: Cache Gradle
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}-${{ hashFiles('**/gradle.properties','**/*.gradle','**/*.gradle.kts') }}
restore-keys: |
${{ runner.os }}-gradle-

- name: Package Deb
run: ./gradlew copyBrandingToCommonResources packageDeb -Porganization=${{ env.ORGANIZATION }}

- name: Install libfuse2
run: |
sudo add-apt-repository universe
sudo apt-get update
sudo apt-get install -y libfuse2

- name: Package AppImage
run: ./gradlew copyBrandingToCommonResources packageAppImage -Porganization=${{ env.ORGANIZATION }}

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: desktopApps-linux-${{ github.run_id }}
path: |
composeApp/build/compose/binaries/main/deb/ooni-probe_*_amd64.deb
composeApp/build/compose/binaries/main/appimage-workspace/OONI-Probe-*-x86_64.AppImage
retention-days: 7
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ output
composeApp/src/desktopMain/resources/windows/WinSparkle.*

/composeApp/src/desktopMain/frameworks/
composeApp/macos-appcast.xml

certificates/*.pem
21 changes: 17 additions & 4 deletions buildSrc/src/main/kotlin/TaskRegistration.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import ooni.appimage.PackageAppImageTask
import ooni.sparkle.GenerateSparkleAppCastTask
import ooni.sparkle.SetupSparkleTask
import ooni.sparkle.WinSparkleSetupTask
import org.gradle.api.Project
import org.gradle.api.tasks.Exec
import org.gradle.api.tasks.JavaExec
import org.gradle.kotlin.dsl.register
import org.gradle.kotlin.dsl.withType
import java.io.File
import kotlin.let
import ooni.sparkle.SetupSparkleTask
import ooni.sparkle.WinSparkleSetupTask
import ooni.appimage.PackageAppImageTask

private fun isMac() = System.getProperty("os.name").lowercase().contains("mac")

Expand Down Expand Up @@ -79,6 +79,19 @@ private fun Project.registerSparkleTask() {
.orElse(layout.buildDirectory.dir("processedResources/desktop/main/macos/")),
)
}

tasks.register("generateSparkleAppCast", GenerateSparkleAppCastTask::class) {
group = "setup"
description = "Generates Sparkle appcast using the specified DMG file."
onlyIf { isMac() }
dependsOn("setupSparkle")

sparkleVersion.set(providers.gradleProperty("sparkleVersion").orElse("2.8.0"))
edKeyFile.set(rootProject.file("certificates/sparkle_eddsa_private.pem"))
appCastFile.set("macos-appcast.xml")
downloadUrlPrefix.set("https://distribution.ooni.org")

}
}

private fun Project.registerWinSparkleTask() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package ooni.sparkle

import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.process.ExecOperations
import javax.inject.Inject

abstract class GenerateSparkleAppCastTask : DefaultTask() {
@get:Inject
abstract val execOperations: ExecOperations

@get:Input
abstract val sparkleVersion: Property<String>

@get:InputFile
abstract val edKeyFile: RegularFileProperty

@get:Input
abstract val appCastFile: Property<String>

@get:Input
abstract val downloadUrlPrefix: Property<String>

@TaskAction
fun run() {
val sparkleTool = sparkleVersion
.map { project.layout.buildDirectory.file("sparkle/extracted-$it/bin/generate_appcast") }
.get()

val dmgFile = project.file("build/compose/binaries/main/dmg")

val command = listOf(
sparkleTool.get().asFile.absolutePath,
"-o",
appCastFile.get(),
"--ed-key-file",
edKeyFile.get().asFile.absolutePath,
"--download-url-prefix",
downloadUrlPrefix.get(),
dmgFile.absolutePath
)

project.logger.lifecycle("Running Sparkle generate_appcast with command: ${command.joinToString(" ")}")

execOperations.exec {
commandLine(command)
}.assertNormalExitValue()
}
}
7 changes: 3 additions & 4 deletions docs/Release.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ successfully and download the generated apps (zipped artifact).

##### 2.7.2 Sign windows app

We need to sign both the windows `.exe` and `.msix` files using our Extended Validation certificate.
Follow the steps on our internal process to do so.
- We need to sign the windows `.exe` file using our Extended Validation certificate. Follow the steps on our internal process to do so.
- Generate the WinSparkle appcast for the signed `.exe` file.

#### 2.8 Create Release

Expand All @@ -146,8 +146,7 @@ based on the new tag.
**2.8.2** Write our manual release notes and add at the bottom the automatic changelog using the
`Generate release notes` button.

**2.8.3** Upload all the desktop files downloaded during step *2.7.1*, except the `download.html`
file, and swapping the windows `.exe` and `.msix` files for their signed versions (step *2.7.2*).
**2.8.3** Upload all the desktop files downloaded during step *2.7.1*, and swapping the windows `.exe` files for their signed versions (step *2.7.2*).

**2.8.4** Publish release

Expand Down
Loading