diff --git a/Makefile b/Makefile deleted file mode 100644 index df6bd824..00000000 --- a/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -.DEFAULT_GOAL := apk -WOLFSKIN_BUILD_IMAGE ?= wolfskin-build:sdk37-jdk21 -WOLFSKIN_GRADLE_VOLUME ?= wolfskin-gradle -WOLFSKIN_SECRETS_DIR ?= /opt/stacks/ventoy/machine-parity/manifest-tank/secrets/wolfskin -export WOLFSKIN_BUILD_IMAGE WOLFSKIN_GRADLE_VOLUME WOLFSKIN_SECRETS_DIR - -.PHONY: build-image apk apk-debug test release-tag -build-image: - docker build --platform linux/amd64 --tag "$(WOLFSKIN_BUILD_IMAGE)" docker - -apk: build-image - @bash docker/gradle.sh release clean assembleDefaultRelease - -apk-debug: build-image - @bash docker/gradle.sh debug assembleDefaultDebug - -test: build-image - @bash docker/gradle.sh debug testDefaultDebugUnitTest - -release-tag: - @bash docker/release-tag.sh diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index ce7d039f..00000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,24 +0,0 @@ -FROM eclipse-temurin:21.0.11_10-jdk-jammy@sha256:dbfd085220ae632a0830166e443747d1ee89e9038d92e3b48c3e5e9d8292b9a7 - -RUN apt-get update && apt-get install -y --no-install-recommends git unzip \ - && rm -rf /var/lib/apt/lists/* -ENV ANDROID_HOME=/opt/android-sdk ANDROID_SDK_ROOT=/opt/android-sdk -ENV PATH="/opt/android-sdk/cmdline-tools/23.0/bin:/opt/android-sdk/build-tools/36.0.0:${PATH}" -RUN curl -fsSL https://dl.google.com/android/repository/commandlinetools-linux-16111833_latest.zip -o /tmp/tools.zip \ - && echo 'e025545c62a8e64c7559119566a569fb1dec5f60 /tmp/tools.zip' | sha1sum -c - \ - && mkdir -p "$ANDROID_HOME/cmdline-tools" \ - && unzip -q /tmp/tools.zip -d /tmp/android-tools \ - && mv /tmp/android-tools/cmdline-tools "$ANDROID_HOME/cmdline-tools/23.0" \ - && rm -rf /tmp/tools.zip /tmp/android-tools \ - && yes | sdkmanager --licenses >/dev/null \ - && sdkmanager 'platforms;android-37.0' 'build-tools;36.0.0' \ - && while IFS='=' read -r name value; do \ - if [ "$name" = Pkg.Revision ]; then test "$value" = 2 || exit 1; fi; \ - done < "$ANDROID_HOME/platforms/android-37.0/source.properties" \ - && curl -fsSL https://dl.google.com/android/repository/platform-tools_r37.0.1-linux.zip -o /tmp/platform-tools.zip \ - && echo '477254aa5f903c15cf51001717bdf347fb6b53e0 /tmp/platform-tools.zip' | sha1sum -c - \ - && unzip -q /tmp/platform-tools.zip -d "$ANDROID_HOME" \ - && rm /tmp/platform-tools.zip \ - && mkdir -m 1777 /gradle -ENV GRADLE_USER_HOME=/gradle HOME=/tmp -COPY signing.init.gradle /opt/wolfskin/signing.init.gradle diff --git a/docker/README.md b/docker/README.md deleted file mode 100644 index 353a716f..00000000 --- a/docker/README.md +++ /dev/null @@ -1,100 +0,0 @@ -# Wolfskin TV container builds - -Run from a full Git checkout with the upstream `v*` and `p*` tags available. The -host needs Docker, GNU Make, Bash, and Git, not Java or the Android SDK. - -```sh -git fetch origin --tags -make apk # clean, signed default release: three ABI splits + universal -make test # upstream testDefaultDebugUnitTest in the same image, no secrets -make apk-debug # default debug, no secrets; MPV stub and no extra codec decoders -``` - -APKs remain under `app/build/outputs/apk/default/{release,debug}/`. Debug builds -are not playback-complete and must not be distributed as releases. Upstream's -`.github/workflows` and dependency version catalog are unchanged; release builds -use the catalog's exact Wholphin extension version (currently `0.2.4`). Do not -place local extension AARs in `app/libs`: upstream prefers them over the pinned -GitHub Packages dependencies. - -Upstream enables JVM unit tests only for debug variants; there is no -`testDefaultReleaseUnitTest` task. `make test` uses the closest default-flavor -task without changing upstream's test configuration. - -## Toolchain and disk use - -`Dockerfile` pins Temurin JDK `21.0.11+10` by image digest, command-line tools -`23.0` and platform-tools `37.0.1` by archive and checksum, and build-tools -`36.0.0` by SDK package version. The SDK manager registers platform `37.0` and -its licenses; the build rejects any platform revision other than 2. An SDK -revision upgrade therefore requires a deliberate Dockerfile update. -Gradle comes from the committed wrapper. The image is built for `linux/amd64`; -the default local image tag is `wolfskin-build:sdk37-jdk21`. -Upstream's build timestamp means APKs are not byte-for-byte reproducible. - -Gradle downloads and caches live in the named volume `wolfskin-gradle`, not -`/tmp`. Module outputs stay in the checkout. Builds run with the host UID/GID, -`--no-daemon`, and at most four workers. The repository's Git metadata is mounted -read-only, including when the checkout is a linked worktree. - -Override `WOLFSKIN_BUILD_IMAGE` to change the locally built image tag and -`WOLFSKIN_GRADLE_VOLUME` to isolate a cache. `make build-image` builds only the -image. Do not delete shared caches during another build. - -## Release credentials - -The default escrow is -`/opt/stacks/ventoy/machine-parity/manifest-tank/secrets/wolfskin/`. Check -`mountpoint -q /mnt/ventoy` before using that path. Set `WOLFSKIN_SECRETS_DIR` -to use another existing directory. Its required files are: - -| File | Contents | -| --- | --- | -| `release.jks` | Separate Wolfskin PKCS12 keystore, RSA 4096, alias `wolfskin` | -| `release.properties` | Java properties `storePassword` and `keyPassword` | -| `github-packages-token` | GitHub token with `read:packages`, username `JustinZeus` | - -The directory must be mode `0700`, each file mode `0600`, owned by the building -user. Never commit them or put their contents in logs. Back up the keystore and -passwords together: losing the release key forces a reinstall. Do not reuse -wolfskin-android's key or the gh CLI login token. - -Release builds mount escrow read-only. The token is loaded inside the container -into upstream's `ORG_GRADLE_PROJECT_WholphinExtensionsUsername` and -`ORG_GRADLE_PROJECT_WholphinExtensionsPassword` environment hooks, never a Docker -command argument. The signing init script registers `wolfskin`; the nonsecret -`release-signing.properties` is mounted as `local.properties` so upstream's -`release.signing.config` hook selects it. Any host `local.properties` is hidden -only for the duration of this container. Keystore and passwords stay outside the -checkout and image. Missing credentials fail the release rather than silently -shipping the MPV stub. - -## Versioning and local release markers - -Upstream computes `versionName` from -`git describe --tags --long --match='v*'`, dropping the leading `v`, and computes -`versionCode` from the count of all local `v*` and `p*` tags. Preserve and fetch -those tags; a shallow or incomplete checkout can give an incorrect version. -Use the full `git describe` output as the human release name. - -After committing the intended release, with a clean checkout and fetched tags: - -```sh -make release-tag -make apk -``` - -The helper creates one lightweight `pwolfskin-YYYY_MM_DD` tag in UTC, appending -`_1`, `_2`, etc. on collision. Each marker adds one to `versionCode` without -changing upstream's `v*`-based version name. It never pushes tags, publishes a -release, or installs an APK. Do not delete published release markers. Tag -creation and publication must be serialized between release operators. - -## Inspecting release artifacts - -Use `apksigner verify --verbose --print-certs APK` and -`aapt2 dump badging APK` inside the build image. Compare the signer SHA-256 with -`keytool -list -v -alias wolfskin -keystore /path/to/release.jks` (enter its -password privately). Inspect APK ZIP entries for real native MPV and ffmpeg -libraries for each shipped ABI; a successful Java compilation alone does not -prove that codec extensions are included. diff --git a/docker/gradle.sh b/docker/gradle.sh deleted file mode 100755 index 76950dc6..00000000 --- a/docker/gradle.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash -# Run the upstream wrapper with a persistent cache and read-only build credentials. -set -euo pipefail -mode=$1 -shift -root=$(git rev-parse --show-toplevel) -git_common=$(git rev-parse --path-format=absolute --git-common-dir) -image=${WOLFSKIN_BUILD_IMAGE:-wolfskin-build:sdk37-jdk21} -cache=${WOLFSKIN_GRADLE_VOLUME:-wolfskin-gradle} -secrets=${WOLFSKIN_SECRETS_DIR:-/opt/stacks/ventoy/machine-parity/manifest-tank/secrets/wolfskin} -arguments=(--rm --platform linux/amd64 --user "$(id -u):$(id -g)" - --mount "type=bind,src=$root,dst=$root" --workdir "$root" - --mount "type=volume,src=$cache,dst=/gradle" - --mount "type=bind,src=$git_common,dst=$git_common,readonly") -gradle_arguments=(--no-daemon --console=plain --max-workers=4) -if [[ $mode == release ]]; then - for name in release.jks release.properties github-packages-token; do - if [[ ! -s $secrets/$name ]]; then - printf 'Missing build credential: %s/%s\n' "$secrets" "$name" >&2 - exit 1 - fi - done - arguments+=(--mount "type=bind,src=$secrets,dst=/run/wolfskin,readonly" - --mount "type=bind,src=$root/docker/release-signing.properties,dst=$root/local.properties,readonly") - gradle_arguments+=(--init-script /opt/wolfskin/signing.init.gradle) - docker run "${arguments[@]}" "$image" bash -euc ' - export ORG_GRADLE_PROJECT_WholphinExtensionsUsername=JustinZeus - export ORG_GRADLE_PROJECT_WholphinExtensionsPassword=$(cat /run/wolfskin/github-packages-token) - exec ./gradlew "$@" - ' bash "${gradle_arguments[@]}" "$@" -else - docker run "${arguments[@]}" "$image" ./gradlew "${gradle_arguments[@]}" "$@" -fi diff --git a/docker/release-signing.properties b/docker/release-signing.properties deleted file mode 100644 index 7e15afe4..00000000 --- a/docker/release-signing.properties +++ /dev/null @@ -1 +0,0 @@ -release.signing.config=wolfskin diff --git a/docker/release-tag.sh b/docker/release-tag.sh deleted file mode 100755 index 14b2637c..00000000 --- a/docker/release-tag.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash -# Add one lightweight release marker without publishing it. -set -euo pipefail -if [[ -n $(git status --porcelain) ]]; then - printf 'Commit or discard checkout changes before tagging a release.\n' >&2 - exit 1 -fi -base="pwolfskin-$(date -u +%Y_%m_%d)" -tag=$base -sequence=1 -while git show-ref --verify --quiet "refs/tags/$tag"; do - tag="${base}_${sequence}" - sequence=$((sequence + 1)) -done -git tag "$tag" -printf 'Created %s locally; no tag was pushed.\n' "$tag" -printf 'versionName: %s\n' "$(git describe --tags --long --match='v*' | cut -c 2-)" -printf 'versionCode: %s\n' "$(git tag --list 'v*' 'p*' | wc -l)" diff --git a/docker/signing.init.gradle b/docker/signing.init.gradle deleted file mode 100644 index b07a4770..00000000 --- a/docker/signing.init.gradle +++ /dev/null @@ -1,17 +0,0 @@ -// Keep signing material outside the checkout; upstream selects this configuration via local.properties. -allprojects { - pluginManager.withPlugin('com.android.application') { - def passwords = new Properties() - file('/run/wolfskin/release.properties').withInputStream { passwords.load(it) } - android.signingConfigs.create('wolfskin') { - storeFile = file('/run/wolfskin/release.jks') - storePassword = passwords.getProperty('storePassword') - keyPassword = passwords.getProperty('keyPassword') - keyAlias = 'wolfskin' - enableV1Signing = true - enableV2Signing = true - enableV3Signing = true - enableV4Signing = true - } - } -}