From c2c2e2d666562ba585a77f5ed31fefaefaca1f8d Mon Sep 17 00:00:00 2001 From: Julian Mutter Date: Fri, 12 Jun 2026 19:48:20 +0200 Subject: [PATCH] Improve docker setup and update scripts --- hosting/Dockerfile | 17 +++--- hosting/deploy-docker.sh | 4 ++ hosting/update-repo.sh | 6 -- hosting/update.sh | 63 ++++++++++++++------ scripts/apk-update-scripts/sheetless.sh | 79 +++++++++++++++++++++++++ scripts/decrypt.sh | 4 ++ scripts/update-apks.sh | 32 ++++++++++ 7 files changed, 175 insertions(+), 30 deletions(-) create mode 100755 hosting/deploy-docker.sh delete mode 100755 hosting/update-repo.sh create mode 100755 scripts/apk-update-scripts/sheetless.sh create mode 100755 scripts/decrypt.sh create mode 100755 scripts/update-apks.sh diff --git a/hosting/Dockerfile b/hosting/Dockerfile index d9907f488..7c9e08b89 100644 --- a/hosting/Dockerfile +++ b/hosting/Dockerfile @@ -1,15 +1,18 @@ -# Use lightweight Nginx + Git +# environment variables necessary to run: +# REPO_URL the url of this repo +# BRANCH the branch to work at + FROM nginx:alpine -# Install git and bash RUN apk add --no-cache git bash - -# Copy nginx config COPY nginx.conf /etc/nginx/nginx.conf -# Copy update script COPY update.sh /update.sh RUN chmod +x /update.sh -# Start update loop + nginx -CMD ["/bin/bash", "-c", "/update.sh & nginx -g 'daemon off;'"] +# Add the cron job to run every 30 minutes +# Redirecting to /proc/1/fd/1 ensures the script's echo statements show up in `docker logs` +RUN echo "*/30 * * * * bash /update.sh > /proc/1/fd/1 2>&1" > /etc/crontabs/root + +# Start the cron daemon in the background (-b) and nginx in the foreground +CMD crond -b && nginx -g 'daemon off;' diff --git a/hosting/deploy-docker.sh b/hosting/deploy-docker.sh new file mode 100755 index 000000000..0eeca4236 --- /dev/null +++ b/hosting/deploy-docker.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +docker build . -t gitlab.julian-mutter.de/julian/fdroid-frajul:latest +docker push gitlab.julian-mutter.de/julian/fdroid-frajul:latest diff --git a/hosting/update-repo.sh b/hosting/update-repo.sh deleted file mode 100755 index aca83345c..000000000 --- a/hosting/update-repo.sh +++ /dev/null @@ -1,6 +0,0 @@ -# !/bin/sh - -git pull -cd fdroid -fdroid update -c -fdroid update diff --git a/hosting/update.sh b/hosting/update.sh index eb67bb101..ffaa7dd0b 100644 --- a/hosting/update.sh +++ b/hosting/update.sh @@ -1,25 +1,54 @@ #! /bin/bash -if [ ! -d "/repo/.git" ]; then +if [ ! -d "/code/.git" ]; then + echo "Performing initial setup!" + mkdir /code echo "Cloning repository..." - git clone --branch "$BRANCH" "$REPO_URL" "/repo" + git clone --branch "$BRANCH" "$REPO_URL" "/code" + echo "Decrypting secrets..." + cd /code + ./scripts/decrypt.sh + echo "Done" fi -while true; do - echo "Running repo update..." +echo "Running regular repo update..." +echo "" - cd "/repo" || exit - git fetch origin - LOCAL=$(git rev-parse HEAD) - REMOTE=$(git rev-parse origin/binaries) +cd "/code" +git fetch origin +LOCAL=$(git rev-parse HEAD) +REMOTE=$(git rev-parse "origin/$BRANCH") - if [ "$LOCAL" != "$REMOTE" ]; then - echo "Updating repo..." - git reset --hard origin/binaries - echo "Update complete." - else - echo "Nothing to do." - fi +NEED_FDROID_UPDATE=false - sleep 600 # check every 10 min -done +# Update repo +if [ "$LOCAL" != "$REMOTE" ]; then + NEED_FDROID_UPDATE=true + echo "Pulling repo..." + git pull "origin/$BRANCH" + echo "Pull complete" + echo "Decrypting secrets..." + ./scripts/decrypt.sh + echo "Done" +else + echo "No changes in repo." +fi + +# Update apks +echo "Updating apks..." +./scripts/update-apks.sh + +if [ $? -eq 10 ]; then + NEED_FDROID_UPDATE=true +fi + +# Run fdroid update if needed +if [ "$NEED_FDROID_UPDATE" = true ]; then + echo "Running fdroid update..." + fdroid update -c + fdroid update + echo "Done" +else + echo "No changes made so no fdroid update necessary." + echo "Done" +fi diff --git a/scripts/apk-update-scripts/sheetless.sh b/scripts/apk-update-scripts/sheetless.sh new file mode 100755 index 000000000..62c1b6c8f --- /dev/null +++ b/scripts/apk-update-scripts/sheetless.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ========================================== +# CONFIGURATION +# ========================================== +GITEA_URL="https://gitlab.julian-mutter.de" +REPO_OWNER="julian" +REPO_NAME="sheetless" +APP_NAME="de.frajul.sheetless" +TARGET_ASSET_NAME="app-release.apk" +FDROID_REPO_DIR="./fdroid/repo" +FDROID_ARCHIVE_DIR="./fdroid/archive" + +# ========================================== +# SETUP & API CALL +# ========================================== +mkdir -p "$FDROID_REPO_DIR" + +API_URL="${GITEA_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/releases" + +echo "Fetching releases from Gitea..." +RELEASES_JSON=$(curl -sL "$API_URL") + +# Check if Gitea returned a valid JSON array +if ! echo "$RELEASES_JSON" | jq -e 'type == "array"' >/dev/null; then + echo "Error: Failed to fetch releases. Check your URL, Repo names, or Token." + exit 1 +fi + +# ========================================== +# SYNC LOGIC +# ========================================== +UPDATE_TRIGGERED=false + +echo "Processing versioned releases for asset: $TARGET_ASSET_NAME" + +# Single jq command to: +# 1. Ignore "latest" releases +# 2. Extract ONLY the matching asset URL +# 3. Output as Tab-Separated Values (TSV) for safe bash reading +while IFS=$'\t' read -r TAG DOWNLOAD_URL; do + + # Skip empty lines if jq returns nothing + [[ -z "$TAG" ]] && continue + + LOCAL_FILE="$FDROID_REPO_DIR/${APP_NAME}_${TAG}.apk" + ARCHIVE_FILE="$FDROID_ARCHIVE_DIR/${APP_NAME}_${TAG}.apk" + + echo "Checking release: $TAG..." + + if [[ -f "$LOCAL_FILE" ]]; then + echo " -> Already exists locally. Skipping." + else + echo " -> Downloading new version: $LOCAL_FILE" + + curl -sL -o "$LOCAL_FILE" "$DOWNLOAD_URL" + + echo "Set var to true" + UPDATE_TRIGGERED=true + fi + + # Feed the jq output into the loop from the bottom +done < <(echo "$RELEASES_JSON" | jq -r --arg target "$TARGET_ASSET_NAME" ' + .[] + | select(.tag_name != "latest") + | .tag_name as $tag + | .assets[] + | select(.name == $target) + | "\($tag)\t\(.browser_download_url)" +') + +if [ "$UPDATE_TRIGGERED" = true ]; then + echo "Sync complete. New updates were downloaded." + exit 10 +else + echo "Sync complete. No new updates found." + exit 0 +fi diff --git a/scripts/decrypt.sh b/scripts/decrypt.sh new file mode 100755 index 000000000..82dfdd945 --- /dev/null +++ b/scripts/decrypt.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +sops -d fdroid/encrypted-config.yml > fdroid/config.yml +sops -d fdroid/encrypted-keystore.p12 > fdroid/keystore.p12 diff --git a/scripts/update-apks.sh b/scripts/update-apks.sh new file mode 100755 index 000000000..500c7089b --- /dev/null +++ b/scripts/update-apks.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +CHANGES_PRODUCED=false + +# Put here all apk update scripts +UPDATE_SCRIPTS=( + "./scripts/apk-update-scripts/sheetless.sh" +) + +for script in "${UPDATE_SCRIPTS[@]}"; do + echo "--------------------------------" + echo "Executing: $script" + + # Run the script + $script + + # Capture the exit code immediately + if [ $? -eq 10 ]; then + echo " -> $script returned 10 (change)" + CHANGES_PRODUCED=true + fi +done + +echo "--------------------------------" + +if [ "$CHANGES_PRODUCED" = true ]; then + echo "Result: At least one script produced a change" + exit 10 +else + echo "Result: Not script produced a change" + exit 0 +fi