Harden release task against network failures

This commit is contained in:
Adam Brown 2026-06-08 21:45:29 -07:00
parent 2c45082ffb
commit 60a61541e9
No known key found for this signature in database
4 changed files with 108 additions and 26 deletions

View file

@ -66,7 +66,12 @@ jobs:
${{ runner.os }}-gradle-
- name: Package Windows ".msi" distribution
run: ./gradlew :desktop:packageReleaseMsi
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
timeout_minutes: 30
max_attempts: 3
shell: pwsh
command: ./gradlew :desktop:packageReleaseMsi
- name: Rename MSI Artifact
shell: cmd
@ -93,7 +98,12 @@ jobs:
echo Successfully renamed file to "hammer.msi"
- name: Package Windows ".exe" distribution
run: ./gradlew :desktop:packageReleaseExe
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
timeout_minutes: 30
max_attempts: 3
shell: pwsh
command: ./gradlew :desktop:packageReleaseExe
- name: Rename EXE Artifact
shell: cmd
@ -152,15 +162,33 @@ jobs:
restore-keys: |
${{ runner.os }}-gradle-
# appimagetool and the AppImage runtime are pinned in linuxDistributions.kt;
# cache them so buildDistAppImage doesn't re-download them every release.
- name: Cache appimagetool
uses: actions/cache@v5
with:
path: |
appimagetool-x86_64.AppImage
appimage-runtime-x86_64
key: appimagetool-1.9.1-runtime-20251108
# buildDistAppImage generates the .zsync delta file with the system zsyncmake;
# appimagetool's bundled copy is broken, so install the system zsync package.
- name: Install zsync
run: |
sudo apt-get update
sudo apt-get install -y zsync
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
timeout_minutes: 10
max_attempts: 3
command: |
sudo apt-get update
sudo apt-get install -y zsync
- name: Package Linux ".deb" distribution
run: ./gradlew :desktop:packageReleaseDeb
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
timeout_minutes: 30
max_attempts: 3
command: ./gradlew :desktop:packageReleaseDeb
- name: Rename DEB Artifact
run: |
@ -180,7 +208,11 @@ jobs:
echo "File renamed successfully."
- name: Package Linux ".rpm" distribution
run: ./gradlew :desktop:packageReleaseRpm
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
timeout_minutes: 30
max_attempts: 3
command: ./gradlew :desktop:packageReleaseRpm
- name: Rename RPM Artifact
run: |
@ -200,7 +232,11 @@ jobs:
echo "File renamed successfully."
- name: Build Linux ".appimage" distribution
run: ./gradlew buildDistAppImage
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
timeout_minutes: 30
max_attempts: 3
command: ./gradlew buildDistAppImage
- name: Create Release
uses: ncipollo/release-action@339a81892b84b4eeb0f6e744e4574d79d0d9b8dd # v1.21.0
@ -236,7 +272,11 @@ jobs:
${{ runner.os }}-gradle-
- name: Package MacOS ".dmg" distribution
run: ./gradlew :desktop:packageReleaseDmg
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
timeout_minutes: 30
max_attempts: 3
command: ./gradlew :desktop:packageReleaseDmg
- name: Rename DMG Artifact
run: |
@ -256,7 +296,11 @@ jobs:
echo "File renamed successfully."
- name: Package MacOS ".pkg" distribution
run: ./gradlew :desktop:packageReleasePkg
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
timeout_minutes: 30
max_attempts: 3
command: ./gradlew :desktop:packageReleasePkg
- name: Rename PKG Artifact
run: |
@ -312,7 +356,11 @@ jobs:
${{ runner.os }}-gradle-
- name: Package Server distributions
run: ./gradlew :server:assembleDist
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
timeout_minutes: 30
max_attempts: 3
command: ./gradlew :server:assembleDist
- name: Rename tar Artifact
run: |
@ -380,11 +428,14 @@ jobs:
RELEASE_STORE_PASSWORD: ${{ secrets.RELEASE_STORE_PASSWORD }}
RELEASE_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }}
RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
run: |
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
timeout_minutes: 30
max_attempts: 3
# Build the F-Droid flavor for the GitHub release APK: it enables the
# public-storage projects feature (adds the storage permissions). The
# Google Play build is produced separately via publish-google-play.yml.
./gradlew :android:assembleRelease -Pfdroid=true
command: ./gradlew :android:assembleRelease -Pfdroid=true
- name: Rename APK Artifact
run: |
@ -468,10 +519,14 @@ jobs:
cache: gradle
- name: Install Flatpak and flatpak-builder
run: |
sudo apt-get update
sudo apt-get install -y flatpak flatpak-builder
flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
timeout_minutes: 10
max_attempts: 3
command: |
sudo apt-get update
sudo apt-get install -y flatpak flatpak-builder
flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
- name: Cache Flatpak SDK and runtime
uses: actions/cache@v5
@ -480,15 +535,23 @@ jobs:
key: flatpak-sdk-runtime-24.08
- name: Install Flatpak SDK and runtime
run: |
flatpak install --user -y flathub org.freedesktop.Platform//24.08
flatpak install --user -y flathub org.freedesktop.Sdk//24.08
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
timeout_minutes: 15
max_attempts: 3
command: |
flatpak install --user -y flathub org.freedesktop.Platform//24.08
flatpak install --user -y flathub org.freedesktop.Sdk//24.08
- name: Grant Permission to Execute
run: chmod +x gradlew
- name: Build Flatpak
run: ./gradlew buildDistFlatpak
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
timeout_minutes: 30
max_attempts: 3
command: ./gradlew buildDistFlatpak
- name: Create Release
uses: ncipollo/release-action@339a81892b84b4eeb0f6e744e4574d79d0d9b8dd # v1.21.0

1
.gitignore vendored
View file

@ -85,5 +85,6 @@ fastlane/README.md
/stage/
/Hammer.AppDir/
/appimagetool-x86_64.AppImage
/appimage-runtime-x86_64
/nul
/.claude/

View file

@ -3,6 +3,9 @@ package com.darkrockstudios.build
import org.gradle.api.GradleException
import org.gradle.api.Project
private const val APPIMAGETOOL_VERSION = "1.9.1"
private const val APPIMAGE_RUNTIME_VERSION = "20251108"
/**
* Checks if the current OS is Linux, throws a GradleException with helpful message if not.
*/
@ -76,6 +79,7 @@ fun Project.registerBuildDistAppImageTask() {
val appSourceDir = rootDir.resolve("desktop/build/installers/main-release/app/hammer")
val iconFile = rootDir.resolve("desktop/icons/linux.png")
val appimagetool = rootDir.resolve("appimagetool-x86_64.AppImage")
val runtimeFile = rootDir.resolve("appimage-runtime-x86_64")
// Clean previous build
appDir.deleteRecursively()
@ -86,8 +90,8 @@ fun Project.registerBuildDistAppImageTask() {
providers.exec {
workingDir = rootDir
commandLine(
"wget", "-q",
"https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
"wget", "-q", "-O", appimagetool.absolutePath,
"https://github.com/AppImage/appimagetool/releases/download/$APPIMAGETOOL_VERSION/appimagetool-x86_64.AppImage"
)
}.result.get()
providers.exec {
@ -95,6 +99,19 @@ fun Project.registerBuildDistAppImageTask() {
}.result.get()
}
// Download the AppImage runtime if not present. Passing it via --runtime-file
// stops appimagetool from fetching the runtime from GitHub at pack time, which
// removes a network dependency from the release build.
if (!runtimeFile.exists()) {
providers.exec {
workingDir = rootDir
commandLine(
"wget", "-q", "-O", runtimeFile.absolutePath,
"https://github.com/AppImage/type2-runtime/releases/download/$APPIMAGE_RUNTIME_VERSION/runtime-x86_64"
)
}.result.get()
}
// Create AppDir structure
val usrDir = appDir.resolve("usr")
val applicationsDir = appDir.resolve("usr/share/applications")
@ -145,6 +162,7 @@ fun Project.registerBuildDistAppImageTask() {
commandLine(
appimagetool.absolutePath,
"--appimage-extract-and-run",
"--runtime-file", runtimeFile.absolutePath,
"-u", "gh-releases-zsync|Wavesonics|hammer-editor|latest|hammer*.AppImage.zsync",
appDir.absolutePath,
outputDir.resolve("hammer.AppImage").absolutePath

View file

@ -1,9 +1,9 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip
networkTimeout=10000
retries=0
retryBackOffMs=500
networkTimeout=30000
retries=3
retryBackOffMs=1000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists