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
4 changes: 2 additions & 2 deletions docs/RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
5. Test an update from the previous published Harbor release while Harbor remains profile owner.
6. Complete the physical-device release matrix.
7. Create an immutable annotated source tag named `v<versionName>` and verify it points to the intended release commit.
8. From a clean checkout of that exact tag, build the unsigned release APK with the documented JDK and Android SDK versions.
8. From a fresh `git clone` of the repository, check out that exact tag and build the unsigned release APK with the documented JDK and Android SDK versions.
9. Sign the APK with `sh scripts/sign-release.sh`. The script uses an F-Droid-compatible Android Build Tools 34 `apksigner`, writes the exact asset name `app-release-signed.apk` by default, and verifies the resulting certificate before returning success.
10. Publish the GitHub release with `app-release-signed.apk` attached.
11. Verify that F-Droid detects the tag, independently rebuilds it, and successfully completes its reproducibility check before treating the F-Droid release as complete.
Expand Down Expand Up @@ -47,7 +47,7 @@ Before signing, provide these environment variables through the release environm

The signing script passes password references to `apksigner` using its `env:` input mode; it does not put password values in the command arguments.

From a clean checkout of the release tag:
From a fresh `git clone` of the repository, check out the release tag and run:

```shell
./gradlew --no-daemon clean assembleRelease
Expand Down
20 changes: 20 additions & 0 deletions scripts/verify-deterministic-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,33 @@ second_dir=$(mktemp -d)
trap 'rm -rf "$first_dir" "$second_dir"' EXIT
gradle_bin=${GRADLE_BIN:-./gradlew}

if ! command -v unzip >/dev/null 2>&1; then
printf 'unzip is required to inspect release APK metadata\n' >&2
exit 1
fi

verify_vcs_metadata() {
apk=$1
if ! metadata=$(unzip -p "$apk" META-INF/version-control-info.textproto 2>/dev/null); then
printf 'Release APK is missing valid VCS metadata\n' >&2
exit 1
fi

if printf '%s\n' "$metadata" | grep -Fq 'NO_VALID_GIT_FOUND'; then
printf 'Release APK contains invalid Git metadata: NO_VALID_GIT_FOUND\n' >&2
exit 1
fi
}

"$gradle_bin" --no-daemon --no-parallel --no-configuration-cache clean
"$gradle_bin" --no-daemon --no-parallel --no-configuration-cache assembleRelease
cp app/build/outputs/apk/release/app-release-unsigned.apk "$first_dir/harbor.apk"
verify_vcs_metadata "$first_dir/harbor.apk"

"$gradle_bin" --no-daemon --no-parallel --no-configuration-cache clean
"$gradle_bin" --no-daemon --no-parallel --no-configuration-cache assembleRelease
cp app/build/outputs/apk/release/app-release-unsigned.apk "$second_dir/harbor.apk"
verify_vcs_metadata "$second_dir/harbor.apk"

hash_file() {
if command -v sha256sum >/dev/null 2>&1; then
Expand Down
Loading