#!/usr/bin/env bash # Submit RECCoon to F-Droid by opening a merge request against fdroiddata. # # It needs a GitLab Personal Access Token with the "api" scope: # 1. Create/account: https://gitlab.com/users/sign_up # 2. Create a token: https://gitlab.com/-/user_settings/personal_access_tokens # name it "fdroid-submit", tick the "api" scope, then copy the glpat-... value. # 3. Save it locally (never commit it): # mkdir -p ~/.config # printf '%s' 'glpat-...' > ~/.config/gitlab-token # chmod 600 ~/.config/gitlab-token # 4. Run: ./tools/submit-to-fdroid.sh # # The script forks fdroid/fdroiddata, adds metadata/com.tomcooks.reccoon.yml on a # branch, and opens the merge request. It is safe to run more than once. set -euo pipefail API="https://gitlab.com/api/v4" UPSTREAM_PATH="fdroid%2Ffdroiddata" BRANCH="reccoon-1.0.0" FILE_PATH="metadata/com.tomcooks.reccoon.yml" FILE_PATH_ENC="metadata%2Fcom.tomcooks.reccoon.yml" HERE="$(cd "$(dirname "$0")" && pwd)" SOURCE_YAML="$HERE/../f-droid/com.tomcooks.reccoon.yml" TOKEN="${GITLAB_TOKEN:-}" if [ -z "$TOKEN" ] && [ -f "$HOME/.config/gitlab-token" ]; then TOKEN="$(tr -d '\r\n' < "$HOME/.config/gitlab-token")" fi if [ -z "$TOKEN" ]; then echo "No GitLab token found. See the comment at the top of this script." >&2 exit 1 fi if [ ! -f "$SOURCE_YAML" ]; then echo "Missing $SOURCE_YAML" >&2 exit 1 fi gl() { curl -sf -H "PRIVATE-TOKEN: $TOKEN" "$@"; } USERNAME="$(gl "$API/user" | jq -r .username)" UPSTREAM_ID="$(gl "$API/projects/$UPSTREAM_PATH" | jq -r .id)" echo "Authenticated as @$USERNAME (upstream id $UPSTREAM_ID)" echo "==> Forking fdroid/fdroiddata (no-op if it already exists)" curl -s -o /dev/null -H "PRIVATE-TOKEN: $TOKEN" -X POST \ "$API/projects/$UPSTREAM_PATH/fork" || true FORK_ID="" for _ in $(seq 1 40); do FORK_ID="$(gl "$API/projects/$USERNAME%2Ffdroiddata" 2>/dev/null | jq -r .id 2>/dev/null || true)" if [ -n "$FORK_ID" ] && [ "$FORK_ID" != "null" ]; then break fi sleep 3 done if [ -z "$FORK_ID" ] || [ "$FORK_ID" = "null" ]; then echo "Fork did not become ready in time." >&2 exit 1 fi echo " fork id: $FORK_ID" echo "==> Creating branch $BRANCH" curl -s -o /dev/null -H "PRIVATE-TOKEN: $TOKEN" -X POST \ "$API/projects/$FORK_ID/repository/branches?branch=$BRANCH&ref=master" || true echo "==> Writing $FILE_PATH" BODY="$(jq -n --arg b "$BRANCH" --arg c "$(cat "$SOURCE_YAML")" \ '{branch:$b, content:$c, commit_message:"Add RECCoon 1.0.0 build metadata"}')" CODE="$(curl -s -o /tmp/fdroid-file.json -w '%{http_code}' \ -H "PRIVATE-TOKEN: $TOKEN" -H 'Content-Type: application/json' \ -X POST "$API/projects/$FORK_ID/repository/files/$FILE_PATH_ENC" -d "$BODY")" if [ "$CODE" = "201" ]; then echo " created" elif [ "$CODE" = "400" ] && grep -q "already exists" /tmp/fdroid-file.json; then echo " already present" else echo " unexpected response (HTTP $CODE):" >&2 cat /tmp/fdroid-file.json >&2 exit 1 fi echo "==> Opening merge request" MR_BODY="$(jq -n --arg b "$BRANCH" --argjson up "$UPSTREAM_ID" \ '{source_branch:$b, target_branch:"master", target_project_id:$up, title:"New app: RECCoon (com.tomcooks.reccoon)", description:"Adds metadata for RECCoon, an offline audio recorder with on-device Parakeet transcription.\n\n- Source: https://git.tomcooks.com/reccoon\n- License: GPL-3.0-or-later\n- Gradle build; the sherpa-onnx runtime is fetched from JitPack\n- Fastlane metadata and the v1.0.0 tag are in the repository"}')" MR_CODE="$(curl -s -o /tmp/fdroid-mr.json -w '%{http_code}' \ -H "PRIVATE-TOKEN: $TOKEN" -H 'Content-Type: application/json' \ -X POST "$API/projects/$FORK_ID/merge_requests" -d "$MR_BODY")" if [ "$MR_CODE" = "201" ]; then echo " merge request: $(jq -r .web_url /tmp/fdroid-mr.json)" else echo " response (HTTP $MR_CODE):" >&2 cat /tmp/fdroid-mr.json >&2 exit 1 fi