Skip to content

Add real Kotlin unit tests for Bible scraper architecture #43

Add real Kotlin unit tests for Bible scraper architecture

Add real Kotlin unit tests for Bible scraper architecture #43

name: release-latest
# Continuous "latest" release: every push to master rebuilds Windows,
# macOS, Linux, and Android artifacts and republishes them under a single
# rolling GitHub Release tagged "latest", overwriting each platform's asset
# on every push. Fully separate from the tag-triggered release.yml /
# release-unix.yml, which still drive the versioned desktop releases —
# untouched by this file. Supersedes the old release-android.yml (folded
# in here so all four platforms share one tag-move step instead of racing
# to force-push "latest" independently).
on:
push:
branches: ["master"]
concurrency:
group: release-latest
cancel-in-progress: true
jobs:
# Moves the rolling "latest" tag to this commit exactly once, before any
# build job publishes a release against it — softprops/action-gh-release
# does NOT move an already-existing tag's target commit on its own.
move-tag:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Move the rolling "latest" tag to this commit
run: |
git tag -f latest
git push origin latest --force
test-kotlin:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "21"
- name: gradlew testDebugUnitTest
working-directory: mobile
run: ./gradlew testDebugUnitTest --no-daemon
test-zig:
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Install GTK4/SQLite3 deps (macOS)
if: runner.os == 'macOS'
run: brew install gtk4 pango cairo glib sqlite3
- name: Install GTK4/SQLite3 deps (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-4-dev libsqlite3-dev pkg-config build-essential
- name: Install Zig (pinned master nightly)
run: |
set -euo pipefail
case "$(uname -s)-$(uname -m)" in
Darwin-arm64|Darwin-aarch64) ZIG_TARGET="aarch64-macos" ;;
Darwin-x86_64) ZIG_TARGET="x86_64-macos" ;;
Linux-x86_64) ZIG_TARGET="x86_64-linux" ;;
Linux-aarch64|Linux-arm64) ZIG_TARGET="aarch64-linux" ;;
*) echo "unsupported platform $(uname -s)-$(uname -m)" >&2; exit 1 ;;
esac
JSON="$(curl -fsSL https://ziglang.org/download/index.json)"
URL="$(echo "$JSON" | jq -r ".master[\"$ZIG_TARGET\"].tarball")"
echo "Installing zig from $URL"
curl -fsSL "$URL" -o "$RUNNER_TEMP/zig.tar.xz"
mkdir -p "$RUNNER_TEMP/zig"
tar -xJf "$RUNNER_TEMP/zig.tar.xz" -C "$RUNNER_TEMP/zig" --strip-components=1
echo "$RUNNER_TEMP/zig" >> "$GITHUB_PATH"
- name: Verify zig
run: zig version
- name: zig build test
run: zig build test --summary all
build-android:
needs: [move-tag, test-kotlin]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
# Full history, not the default shallow (fetch-depth: 1) clone —
# mobile/app/build.gradle.kts derives versionCode from
# `git rev-list --count HEAD`, which only sees 1 commit (and so
# always resolves to versionCode 1, forever) on a shallow clone.
fetch-depth: 0
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "21"
- name: Set up Android SDK
uses: android-actions/setup-android@v3
- name: Build debug-signed APK
run: bash packaging/build-android.sh
- name: Publish rolling release
uses: softprops/action-gh-release@v2
with:
tag_name: latest
name: "Latest (master @ ${{ github.sha }})"
body: |
Android build is DEBUG-SIGNED (sideload only, not from the Play
Store) — see docs/PACKAGING.md. Rebuilt from `${{ github.sha }}`,
replaced on every push to master.
commit: ${{ github.sha }}
prerelease: true
files: dist/metanoia-android-debug.apk
build-macos:
needs: [move-tag, test-zig]
runs-on: macos-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Install GTK4/SQLite3 deps
run: brew install gtk4 pango cairo glib sqlite3
- name: Install Zig (pinned master nightly)
run: |
set -euo pipefail
case "$(uname -m)" in
arm64|aarch64) ZIG_TARGET="aarch64-macos" ;;
x86_64) ZIG_TARGET="x86_64-macos" ;;
*) echo "unsupported arch $(uname -m)" >&2; exit 1 ;;
esac
JSON="$(curl -fsSL https://ziglang.org/download/index.json)"
URL="$(echo "$JSON" | jq -r ".master[\"$ZIG_TARGET\"].tarball")"
echo "Installing zig from $URL"
curl -fsSL "$URL" -o "$RUNNER_TEMP/zig.tar.xz"
mkdir -p "$RUNNER_TEMP/zig"
tar -xJf "$RUNNER_TEMP/zig.tar.xz" -C "$RUNNER_TEMP/zig" --strip-components=1
echo "$RUNNER_TEMP/zig" >> "$GITHUB_PATH"
- name: Verify zig
run: zig version
- name: Build macOS .app bundle
run: bash packaging/build-macos.sh
- name: Install create-dmg
run: brew install create-dmg
- name: Build macOS installer DMG
run: bash packaging/build-macos-dmg.sh
- name: Publish rolling release
uses: softprops/action-gh-release@v2
with:
tag_name: latest
name: "Latest (master @ ${{ github.sha }})"
body: |
macOS build (unsigned/ad-hoc-signed — see docs/PACKAGING.md for
the Gatekeeper caveat). Either double-click Metanoia-*.dmg and
drag Metanoia.app to Applications, or unzip the tarball and run
Metanoia.app directly. Rebuilt from `${{ github.sha }}`, replaced
on every push to master.
commit: ${{ github.sha }}
prerelease: true
files: |
dist/Metanoia-macos-*.tar.gz
dist/Metanoia-*.dmg
build-linux:
needs: [move-tag, test-zig]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Install GTK4/SQLite3 deps
run: |
sudo apt-get update
sudo apt-get install -y libgtk-4-dev libsqlite3-dev pkg-config build-essential
- name: Install Zig (pinned master nightly)
run: |
set -euo pipefail
case "$(uname -m)" in
x86_64) ZIG_TARGET="x86_64-linux" ;;
aarch64|arm64) ZIG_TARGET="aarch64-linux" ;;
*) echo "unsupported arch $(uname -m)" >&2; exit 1 ;;
esac
JSON="$(curl -fsSL https://ziglang.org/download/index.json)"
URL="$(echo "$JSON" | jq -r ".master[\"$ZIG_TARGET\"].tarball")"
echo "Installing zig from $URL"
curl -fsSL "$URL" -o "$RUNNER_TEMP/zig.tar.xz"
mkdir -p "$RUNNER_TEMP/zig"
tar -xJf "$RUNNER_TEMP/zig.tar.xz" -C "$RUNNER_TEMP/zig" --strip-components=1
echo "$RUNNER_TEMP/zig" >> "$GITHUB_PATH"
- name: Verify zig
run: zig version
- name: Build Linux tarball + .deb
run: bash packaging/build-linux.sh
- name: Publish rolling release
uses: softprops/action-gh-release@v2
with:
tag_name: latest
name: "Latest (master @ ${{ github.sha }})"
body: |
Linux build: universal tarball (with install.sh) + .deb for
Debian/Ubuntu — see docs/PACKAGING.md. Rebuilt from
`${{ github.sha }}`, replaced on every push to master.
commit: ${{ github.sha }}
prerelease: true
files: |
dist/Metanoia-linux-*.tar.gz
dist/*.deb
build-appimage:
needs: [move-tag, test-zig]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Install GTK4/SQLite3 deps
run: |
sudo apt-get update
sudo apt-get install -y libgtk-4-dev libsqlite3-dev pkg-config build-essential zsync
- name: Install Zig (pinned master nightly)
run: |
set -euo pipefail
case "$(uname -m)" in
x86_64) ZIG_TARGET="x86_64-linux" ;;
aarch64|arm64) ZIG_TARGET="aarch64-linux" ;;
*) echo "unsupported arch $(uname -m)" >&2; exit 1 ;;
esac
JSON="$(curl -fsSL https://ziglang.org/download/index.json)"
URL="$(echo "$JSON" | jq -r ".master[\"$ZIG_TARGET\"].tarball")"
echo "Installing zig from $URL"
curl -fsSL "$URL" -o "$RUNNER_TEMP/zig.tar.xz"
mkdir -p "$RUNNER_TEMP/zig"
tar -xJf "$RUNNER_TEMP/zig.tar.xz" -C "$RUNNER_TEMP/zig" --strip-components=1
echo "$RUNNER_TEMP/zig" >> "$GITHUB_PATH"
- name: Verify zig
run: zig version
- name: Build AppImage
run: bash packaging/build-appimage.sh
- name: Publish rolling release
uses: softprops/action-gh-release@v2
with:
tag_name: latest
name: "Latest (master @ ${{ github.sha }})"
body: |
Portable single-file AppImage — no installation, `chmod +x` and
run directly on virtually any x86_64 Linux distro (see
docs/PACKAGING.md). Rebuilt from `${{ github.sha }}`, replaced
on every push to master. Carries embedded AppImageUpdate
information — with appimageupdatetool installed, `appimageupdatetool
./Metanoia-x86_64.AppImage` checks/applies updates in place.
commit: ${{ github.sha }}
prerelease: true
files: |
dist/Metanoia-x86_64.AppImage
dist/Metanoia-x86_64.AppImage.zsync
build-flatpak:
needs: [move-tag, test-zig]
runs-on: ubuntu-latest
container:
image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-50
options: --privileged
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Build .flatpak bundle
uses: flatpak/flatpak-github-actions/flatpak-builder@v6
with:
bundle: Metanoia.flatpak
manifest-path: packaging/com.bytecats.metanoia.yml
cache-key: flatpak-builder-${{ github.sha }}
arch: x86_64
- name: Publish rolling release
uses: softprops/action-gh-release@v2
with:
tag_name: latest
name: "Latest (master @ ${{ github.sha }})"
body: |
Flatpak single-file bundle — install with `flatpak install
Metanoia.flatpak` (no Flathub account/review involved, this is
a direct bundle, not a Flathub publish — see
docs/PACKAGING.md). Rebuilt from `${{ github.sha }}`, replaced
on every push to master.
commit: ${{ github.sha }}
prerelease: true
files: Metanoia.flatpak
build-windows:
needs: move-tag
runs-on: windows-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Setup MSYS2
id: msys2
uses: msys2/setup-msys2@v2
with:
msystem: UCRT64
update: true
install: >
mingw-w64-ucrt-x86_64-gtk4
mingw-w64-ucrt-x86_64-pkg-config
mingw-w64-ucrt-x86_64-sqlite3
mingw-w64-ucrt-x86_64-curl
mingw-w64-ucrt-x86_64-git
mingw-w64-ucrt-x86_64-nsis
mingw-w64-ucrt-x86_64-adwaita-icon-theme
- name: Install Zig
shell: pwsh
run: |
$json = Invoke-RestMethod https://ziglang.org/download/index.json
$url = $json.master."x86_64-windows".tarball
$zip = "$env:TEMP\zig.zip"
Invoke-WebRequest -Uri $url -OutFile $zip
Expand-Archive $zip -DestinationPath "$env:USERPROFILE\zig" -Force
$dir = (Get-ChildItem "$env:USERPROFILE\zig" -Recurse -Filter "zig.exe").DirectoryName
echo "$dir" | Out-File $env:GITHUB_PATH -Append
- name: Build
shell: msys2 {0}
env:
MSYS2_PATH_TYPE: inherit
# setup-msys2's default config (release: true, no `location`
# override) does a fresh install under "${RUNNER_TEMP}\msys64",
# NOT the conventional "C:\msys64" — build.zig needs the real
# path to find gtk4/sqlite3's import libs. See build.zig's
# Windows-specific block for the full story.
MSYS2_ROOT: ${{ steps.msys2.outputs.msys2-location }}
run: bash ci/fix-msys2-libs.sh && zig build
- name: Package (assemble real standalone dist folder)
shell: msys2 {0}
env:
MSYS2_PATH_TYPE: inherit
MSYS2_ROOT: ${{ steps.msys2.outputs.msys2-location }}
# Replaces the old bare `Copy-Item zig-out\bin\*` (which shipped
# only metanoia.exe — no DLLs, no data/, no GTK runtime resources,
# and so could not run at all on a machine without a full MSYS2
# install). See packaging/build-windows.sh for the full DLL-closure
# + GTK4-resource-discovery reasoning. Runs in the same msys2 shell
# as the Build step (not pwsh) because it needs `ldd` and live
# `/ucrt64/...` POSIX paths.
run: bash packaging/build-windows.sh
- name: Zip the portable distribution
shell: pwsh
run: |
Compress-Archive -Path "dist\Metanoia\*" -DestinationPath "dist\Metanoia-windows-x86_64.zip" -Force
- name: Build NSIS installer
shell: msys2 {0}
env:
MSYS2_PATH_TYPE: inherit
MSYS2_ROOT: ${{ steps.msys2.outputs.msys2-location }}
# makensis.exe ships in mingw-w64-ucrt-x86_64-nsis (installed
# above, unused until now) at /ucrt64/bin — on PATH in this shell
# the same way zig-build's other MSYS2-provided tools are. Only
# APP_VERSION is passed — DIST_DIR/OUT_FILE/icon path are
# deliberately NOT overridden from here; see the path-resolution
# comment at the top of packaging/windows-installer.nsi for why
# (their defaults are relative to the .nsi file's own directory,
# verified against a real makensis, not the repo root).
run: |
makensis -DAPP_VERSION="latest-${{ github.sha }}" packaging/windows-installer.nsi
- name: Publish rolling release
uses: softprops/action-gh-release@v2
with:
tag_name: latest
name: "Latest (master @ ${{ github.sha }})"
body: |
Windows: unzip Metanoia-windows-x86_64.zip and run
metanoia.exe (no installation needed) — or run
Metanoia-Setup.exe for a normal installed app with a Start Menu
shortcut and uninstaller. Rebuilt from `${{ github.sha }}`,
replaced on every push to master.
commit: ${{ github.sha }}
prerelease: true
files: |
dist/Metanoia-windows-x86_64.zip
dist/Metanoia-Setup.exe