Build / Desktop, server and tools (push) Successful in 51s
- Every day the F-Droid repository's tools are checked for a newer version that has been out for at least two weeks. When there is one, or when the app's listing changed, the repository is rebuilt with it, and releases use it only once that worked, so a faulty update of the tools can never hold up a release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T9uhaCTSycTh1r8At679Pz
127 lines
5.1 KiB
Bash
Executable File
127 lines
5.1 KiB
Bash
Executable File
#!/bin/sh
|
|
set -eu
|
|
version=${1:-}
|
|
here=$(pwd)
|
|
root=${PACKAGES_ROOT:-/var/www/packages.arasaka.software}
|
|
keep=${FDROID_KEEP:-3}
|
|
url=https://packages.arasaka.software/fdroid/repo
|
|
fingerprint=5F52CFF4F52F4E0B6DA6CD044BFCEAF78D1D42DB24F2470602DB7F19CBFDF846
|
|
id=software.arasaka.meweb
|
|
if [ -z "${MEWEB_KEYSTORE_B64:-}" ] || [ -z "${MEWEB_KEYSTORE_PASS:-}" ]; then
|
|
echo "::error::the repository secrets MEWEB_KEYSTORE_B64 and MEWEB_KEYSTORE_PASS are not set"
|
|
exit 1
|
|
fi
|
|
if [ -n "$version" ]; then
|
|
apk=$here/releases/$version/MeWeb-$version-android.apk
|
|
test -f "$apk"
|
|
major=$(echo "$version" | cut -d. -f1)
|
|
minor=$(echo "$version" | cut -d. -f2)
|
|
patch=$(echo "$version" | cut -d. -f3)
|
|
code=$((major * 10000 + minor * 100 + patch))
|
|
elif [ ! -e "$root/fdroid/repo" ]; then
|
|
echo "no repository at $root/fdroid/repo yet: the first release makes it"
|
|
exit 0
|
|
fi
|
|
|
|
tools/setup.sh --group fdroid
|
|
tools=$(cd "$here/tools/fdroid/linux-x64" && pwd -P)
|
|
uv=$tools/uv-x86_64-unknown-linux-gnu/uv
|
|
python=$(command -v python3)
|
|
JAVA_HOME=$(ls -d "$here"/tools/jdk/linux-x64/*/ | head -n 1)
|
|
ANDROID_HOME=$here/tools/android-sdk
|
|
PATH=$JAVA_HOME/bin:$PATH
|
|
export JAVA_HOME ANDROID_HOME PATH
|
|
|
|
exec 9>>"$root/.lock"
|
|
flock -w 2700 9
|
|
work=$(mktemp -d)
|
|
trap 'rm -rf "$work"' EXIT
|
|
keyless() {
|
|
env -u MEWEB_KEYSTORE_B64 -u MEWEB_KEYSTORE_PASS UV_CACHE_DIR="$tools/cache" "$@"
|
|
}
|
|
|
|
if [ -n "$version" ] && "$tools/current/bin/fdroid" --version > /dev/null 2>&1; then
|
|
install=$(readlink -f "$tools/current")
|
|
else
|
|
settled=$(date -u -d '14 days ago' +%Y-%m-%dT%H:%M:%SZ)
|
|
echo fdroidserver | keyless "$uv" pip compile -q --python "$python" --exclude-newer "$settled" --generate-hashes \
|
|
--no-header --no-annotate -o "$work/lock.txt" -
|
|
install=$tools/fdroidserver-$(sha256sum < "$work/lock.txt" | cut -c1-12)
|
|
if ! "$install/bin/fdroid" --version > /dev/null 2>&1; then
|
|
rm -rf "$install"
|
|
keyless "$uv" venv -q --python "$python" "$install"
|
|
keyless "$uv" pip sync -q --python "$install/bin/python" "$work/lock.txt"
|
|
cp "$work/lock.txt" "$install/lock.txt"
|
|
fi
|
|
fi
|
|
tool=$("$install/bin/fdroid" --version)
|
|
stamp=$( { cat "$install/lock.txt"; cd packaging/fdroid && find config.yml icon.png metadata -type f | LC_ALL=C sort | xargs sha256sum; } | sha256sum | cut -d' ' -f1)
|
|
if [ -z "$version" ] && [ "$(cat "$(readlink -f "$root/fdroid/repo")/../built-from" 2>/dev/null)" = "$stamp" ]; then
|
|
echo "nothing new: the repository is already built with fdroidserver $tool and this listing"
|
|
exit 0
|
|
fi
|
|
echo "fdroidserver $tool, $(basename "$install")"
|
|
|
|
(umask 077 && printf '%s' "$MEWEB_KEYSTORE_B64" | base64 -d > "$work/meweb.keystore")
|
|
MEWEB_KEYSTORE=$work/meweb.keystore
|
|
export MEWEB_KEYSTORE MEWEB_KEYSTORE_PASS
|
|
unset MEWEB_KEYSTORE_B64
|
|
held=$(keytool -J-Duser.language=en -list -v -keystore "$MEWEB_KEYSTORE" -storepass:env MEWEB_KEYSTORE_PASS -alias meweb | sed -n 's/^.*SHA256: *//p' | tr -d ':')
|
|
test "$held" = "$fingerprint"
|
|
|
|
state=$root/.fdroid
|
|
snap=$state/$(date -u +%Y%m%d%H%M%S)-${version:-tools}
|
|
mkdir -p "$snap/repo" "$snap/metadata" "$snap/tmp"
|
|
if [ -e "$root/fdroid/repo" ]; then
|
|
prior=$(readlink -f "$root/fdroid/repo")/..
|
|
for file in "$prior"/repo/*.apk; do
|
|
[ -e "$file" ] && ln "$file" "$snap/repo/"
|
|
done
|
|
for icons in "$prior"/repo/icons*; do
|
|
[ -d "$icons" ] && cp -a "$icons" "$snap/repo/"
|
|
done
|
|
cp -a "$prior/metadata/." "$snap/metadata/"
|
|
cp "$prior/repo/index-v2.json" "$snap/repo/"
|
|
if [ -f "$prior/tmp/apkcache.json" ]; then cp "$prior/tmp/apkcache.json" "$snap/tmp/"; fi
|
|
fi
|
|
cp packaging/fdroid/config.yml "$snap/config.yml"
|
|
chmod 600 "$snap/config.yml"
|
|
cp packaging/fdroid/icon.png "$snap/icon.png"
|
|
cp -r packaging/fdroid/metadata/. "$snap/metadata/"
|
|
if [ -n "$version" ]; then
|
|
rm -f "$snap/repo/${id}_$code.apk"
|
|
cp "$apk" "$snap/repo/${id}_$code.apk"
|
|
fi
|
|
(cd "$snap/repo" && ls "$id"_*.apk | sed 's/.*_\([0-9]*\)\.apk$/\1/' | sort -n | head -n "-$keep" | while read -r old; do
|
|
rm -f "${id}_$old.apk"
|
|
done)
|
|
newest=$(cd "$snap/repo" && ls "$id"_*.apk | sed 's/.*_\([0-9]*\)\.apk$/\1/' | sort -n | tail -n 1)
|
|
|
|
(cd "$snap" && "$install/bin/fdroid" update)
|
|
rm -rf "$snap/repo/status"
|
|
chmod -R u=rwX,go=rX "$snap/repo"
|
|
echo "$stamp" > "$snap/built-from"
|
|
|
|
mkdir -p "$root/fdroid"
|
|
ln -sfn "../.fdroid/$(basename "$snap")/repo" "$root/fdroid/repo.new"
|
|
mv -T -f "$root/fdroid/repo.new" "$root/fdroid/repo"
|
|
ls -1d "$state"/*/ | sort | head -n -3 | while read -r old; do
|
|
find "$old" -maxdepth 0 -mmin +1440 -exec rm -rf {} +
|
|
done
|
|
echo "published $root/fdroid/repo, newest ${id}_$newest.apk, with fdroidserver $tool"
|
|
|
|
if [ "$root" = /var/www/packages.arasaka.software ]; then
|
|
curl -fsS "$url/entry.jar" -o "$work/entry.jar"
|
|
signed=$(keytool -J-Duser.language=en -printcert -jarfile "$work/entry.jar" | sed -n 's/^.*SHA256: *//p' | head -n 1 | tr -d ':')
|
|
test "$signed" = "$fingerprint"
|
|
curl -fsS "$url/index-v2.json" | grep -Eq "\"versionCode\": ?$newest\b"
|
|
curl -fsSI "$url/${id}_$newest.apk" > /dev/null
|
|
echo "live at $url: newest $id $newest"
|
|
fi
|
|
|
|
ln -sfn "$(basename "$install")" "$tools/current.new"
|
|
mv -T -f "$tools/current.new" "$tools/current"
|
|
for old in "$tools"/fdroidserver-*; do
|
|
[ "$old" = "$install" ] || rm -rf "$old"
|
|
done
|