Skip to content

Fix Initializer for conditional binding must have Optional type, not … #271

Fix Initializer for conditional binding must have Optional type, not …

Fix Initializer for conditional binding must have Optional type, not … #271

Workflow file for this run

name: ProStore iOS Build and Release
on:
workflow_dispatch:
push:
branches: [ main ]
paths-ignore:
- 'README.md'
- 'gallery/**'
- 'website/**'
- '.github/**'
permissions:
contents: write
jobs:
build-unsigned-ipa:
name: Build IPA
runs-on: macos-15
timeout-minutes: 60
outputs:
version: ${{ steps.get_version.outputs.version }}
release_exists: ${{ steps.check_release.outputs.exists }}
changelog: ${{ steps.generate_changelog.outputs.CHANGELOG }}
cached_object_version: ${{ steps.cache_object_version.outputs.object_version }}
steps:
- name: Checkout Repo
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: true
- name: Show Xcode Version
run: |
echo "=== xcodebuild -version ==="
xcodebuild -version || true
echo "=== sw_vers ==="
sw_vers || true
- name: Install Build Tools
run: |
# jq
if ! command -v jq >/dev/null 2>&1; then
echo "jq not found — attempting to install via brew"
if command -v brew >/dev/null 2>&1; then
brew install jq || true
fi
fi
# yq
if ! command -v yq >/dev/null 2>&1; then
echo "yq not found — attempting to install via brew"
if command -v brew >/dev/null 2>&1; then
brew install yq || true
fi
fi
# gh (GitHub CLI)
if ! command -v gh >/dev/null 2>&1; then
echo "gh not found — attempting to install via brew"
if command -v brew >/dev/null 2>&1; then
brew install gh || true
fi
fi
# xcodegen
if ! command -v xcodegen >/dev/null 2>&1; then
echo "xcodegen not found — attempting to install via brew"
if command -v brew >/dev/null 2>&1; then
brew install xcodegen || true
fi
fi
# Fallback: official gh installer script (works across platforms)
if ! command -v gh >/dev/null 2>&1; then
echo "gh still not found — attempting official installer script"
curl -fsSL https://cli.github.com/install.sh | sh || true
fi
echo "Tool versions (if installed):"
echo "jq: $(jq --version 2>/dev/null || echo 'not installed')"
echo "yq: $(yq --version 2>/dev/null || echo 'not installed')"
echo "gh: $(gh --version 2>/dev/null || echo 'not installed')"
echo "xcodegen: $(xcodegen --version 2>/dev/null || echo 'not installed')"
shell: bash
- name: Check Project Files
run: |
echo "Workspace files:"
ls -la || true
echo "project.yml (first 200 lines):"
sed -n '1,200p' project.yml || true
- name: Generate Xcode Project
run: |
set -e
xcodegen generate --spec project.yml
echo "Generated project at: $(pwd)/prostore.xcodeproj"
echo "project.pbxproj header (first 60 lines):"
sed -n '1,60p' prostore.xcodeproj/project.pbxproj || true
- name: Resolve Swift Packages
run: |
set -e
echo "Resolving Swift package dependencies for prostore..."
xcodebuild -resolvePackageDependencies -project prostore.xcodeproj -scheme prostore -configuration Release
- name: Build IPA
id: cache_object_version
run: |
set -e
ARCHIVE_PATH="$PWD/build/prostore.xcarchive"
mkdir -p build
# Cache file
CACHE_FILE=".object_version_cache"
CACHED_VERSION=""
candidates=(77) # Add other candidate versions if needed
# Try cached version first
if [ -f "$CACHE_FILE" ]; then
CACHED_VERSION=$(cat "$CACHE_FILE" | tr -d '\n')
echo "Found cached objectVersion: $CACHED_VERSION"
echo "----- Testing cached objectVersion = $CACHED_VERSION -----"
/usr/bin/perl -0777 -pe "s/objectVersion = \\d+;/objectVersion = $CACHED_VERSION;/" -i.bak prostore.xcodeproj/project.pbxproj || true
set +e
xcodebuild clean archive \
-project prostore.xcodeproj \
-scheme prostore \
-archivePath "$ARCHIVE_PATH" \
-sdk iphoneos \
-configuration Release \
CODE_SIGN_IDENTITY="" CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO
rc=$?
set -e
if [ $rc -eq 0 ]; then
echo "✅ Cached objectVersion $CACHED_VERSION works!"
echo "object_version=$CACHED_VERSION" >> $GITHUB_OUTPUT
exit 0
else
echo "❌ Cached objectVersion $CACHED_VERSION failed, trying candidates..."
fi
fi
# Try all candidates
build_ok=0
for v in "${candidates[@]}"; do
echo "----- Attempting build with objectVersion = $v -----"
/usr/bin/perl -0777 -pe "s/objectVersion = \\d+;/objectVersion = $v;/" -i.bak prostore.xcodeproj/project.pbxproj || true
echo "Header preview:"
sed -n '1,20p' prostore.xcodeproj/project.pbxproj || true
set +e
xcodebuild clean archive \
-project prostore.xcodeproj \
-scheme prostore \
-archivePath "$ARCHIVE_PATH" \
-sdk iphoneos \
-configuration Release \
CODE_SIGN_IDENTITY="" CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO
rc=$?
set -e
if [ $rc -eq 0 ]; then
echo "✅ xcodebuild succeeded with objectVersion = $v"
echo "object_version=$v" >> $GITHUB_OUTPUT
echo "$v" > "$CACHE_FILE"
build_ok=1
break
else
echo "❌ xcodebuild failed (exit $rc). Trying next objectVersion..."
fi
done
if [ "$build_ok" -ne 1 ]; then
echo "ERROR: All objectVersion attempts failed."
echo "===== project.pbxproj header ====="
sed -n '1,200p' prostore.xcodeproj/project.pbxproj || true
echo "===== build directory listing ====="
ls -la build || true
exit 74
fi
- name: Package Device IPA
run: |
set -e
ARCHIVE_PATH="$PWD/build/prostore.xcarchive"
APP_PATH="$ARCHIVE_PATH/Products/Applications/prostore.app"
OUTPUT_IPA="build/com.prostoreios.prostore-unsigned-ios.ipa"
echo "Device app path: $APP_PATH"
if [ ! -d "$APP_PATH" ]; then
echo "ERROR: App not found at expected path. Listing archive contents:"
ls -la "$ARCHIVE_PATH" || true
exit 1
fi
mkdir -p build/Payload
rm -rf build/Payload/* || true
cp -R "$APP_PATH" build/Payload/
(cd build && zip -r "$(basename "$OUTPUT_IPA")" Payload) || exit 1
echo "Created device ipa: $OUTPUT_IPA"
ls -la "$OUTPUT_IPA" || true
- name: Upload Device IPA
uses: actions/upload-artifact@v4
with:
name: com.prostoreios.prostore-unsigned-ios.ipa
path: build/com.prostoreios.prostore-unsigned-ios.ipa
- name: Get App Version
id: get_version
run: |
VERSION=$(yq '.targets.prostore.info.properties.CFBundleShortVersionString' project.yml)
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Detected version: $VERSION"
- name: Check Release Exists
id: check_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ steps.get_version.outputs.version }}"
TAG="v$VERSION"
echo "Checking if release $TAG exists..."
if command -v gh >/dev/null 2>&1 && gh release view "$TAG" >/dev/null 2>&1; then
echo "exists=true" >> $GITHUB_OUTPUT
else
echo "exists=false" >> $GITHUB_OUTPUT
fi
- name: Create Changelog
id: generate_changelog
if: steps.check_release.outputs.exists == 'false'
run: |
set -e
VERSION="${{ steps.get_version.outputs.version }}"
CURRENT_VERSION="$VERSION"
SINCE_COMMIT=""
# Walk commits that touched project.yml from newest -> oldest
for c in $(git rev-list HEAD -- project.yml); do
file=$(git show "$c:project.yml" 2>/dev/null || true)
if [ -z "$file" ]; then
continue
fi
v=$(printf "%s" "$file" | yq '.targets.prostore.info.properties.CFBundleShortVersionString' 2>/dev/null || true)
if [ -z "$v" ]; then
continue
fi
if [ "$v" != "$CURRENT_VERSION" ]; then
SINCE_COMMIT="$c"
break
fi
done
# Always capture HEAD message
HEAD_MSG=$(git log -1 --pretty=format:%s HEAD || echo "")
# Derive SINCE_DATE (ISO 8601) from SINCE_COMMIT
if [ -n "$SINCE_COMMIT" ]; then
SINCE_DATE=$(git show -s --format=%cI "$SINCE_COMMIT" 2>/dev/null || true)
else
SINCE_DATE=""
fi
# Determine repo owner/repo
ORIGIN_URL=$(git remote get-url origin 2>/dev/null || true)
OWNER_REPO=$(printf "%s" "$ORIGIN_URL" | sed -E 's#.*github.com[:/]+([^/]+/[^/]+)(\.git)?#\1#')
# Fetch workflow runs
RUNS_JSON=""
if [ -n "$OWNER_REPO" ] && command -v gh >/dev/null 2>&1; then
echo "Fetching recent workflow runs for ${OWNER_REPO}..."
RUNS_JSON=$(gh api -H "Accept: application/vnd.github+json" \
/repos/"$OWNER_REPO"/actions/runs \
-f per_page=100 -f event=push 2>/dev/null || true)
if [ -z "$RUNS_JSON" ] || [ "$(printf "%s" "$RUNS_JSON" | jq '.workflow_runs | length')" -eq 0 ]; then
RUNS_JSON=$(gh api -H "Accept: application/vnd.github+json" \
/repos/"$OWNER_REPO"/actions/runs \
-f per_page=100 -f event=workflow_dispatch 2>/dev/null || true)
fi
fi
WORKFLOW_LINES=""
if [ -n "$RUNS_JSON" ] && printf "%s" "$RUNS_JSON" | jq -e '.workflow_runs | length > 0' >/dev/null 2>&1; then
if [ -n "$SINCE_DATE" ]; then
SINCE_DATE_UTC=$(date -u -j -f "%Y-%m-%dT%H:%M:%S%z" "$SINCE_DATE" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || echo "$SINCE_DATE")
WORKFLOW_LINES=$(printf "%s" "$RUNS_JSON" | jq -r --arg SINCE "$SINCE_DATE_UTC" '
[.workflow_runs[] | select(.created_at >= $SINCE)] |
sort_by(.created_at)[] |
( "- " + (.head_commit.message // .name // .workflow_name) +
" (#" + (.run_number|tostring) + ") — " +
((.conclusion // "in_progress") | tostring) +
" — " + (.created_at // "") +
" — branch: " + (.head_branch // "") )' || true)
else
WORKFLOW_LINES=$(printf "%s" "$RUNS_JSON" | jq -r '
[.workflow_runs[]] | sort_by(.created_at)[] |
( " - " +
(if (.head_commit.message | length) > 0 then .head_commit.message
else (if (.name|length) > 0 then .name else .workflow_name end) end) +
" (#" + (.run_number|tostring) + ") — " +
((.conclusion // "in_progress") | tostring) +
" — " + (.created_at // "") +
" — branch: " + (.head_branch // "") )' || true)
fi
if [ -n "$WORKFLOW_LINES" ]; then
WORKFLOW_LINES=$(printf "%s\n" "$WORKFLOW_LINES" | awk 'NF && !seen[$0]++ { print $0 }' || true)
fi
fi
# Fallback to commit messages
if [ -z "$WORKFLOW_LINES" ]; then
if [ -n "$SINCE_COMMIT" ]; then
COMMITS_RAW=$(git log --pretty=format:%s "${SINCE_COMMIT}..HEAD" --reverse 2>/dev/null || true)
COMMITS_RAW=$(echo "$COMMITS_RAW" | grep -v "Update ProStore app repo to v" || true)
else
COMMITS_RAW=""
fi
fi
# Build description
printf -v DESC "What's new in Version %s?\n" "$VERSION"
if [ -n "$HEAD_MSG" ]; then
DESC+=$'- '"$HEAD_MSG"$'\n'
fi
if [ -n "$WORKFLOW_LINES" ]; then
DESC+="${WORKFLOW_LINES}"$'\n'
elif [ -n "$COMMITS_RAW" ]; then
OTHER_LINES=$(printf "%s\n" "$COMMITS_RAW" | awk -v head="$HEAD_MSG" 'NF && $0!=head { print "- "$0 }' || true)
if [ -n "$OTHER_LINES" ]; then
DESC+="${OTHER_LINES}"$'\n'
fi
fi
DESC="${DESC%$'\n'}"
echo "CHANGELOG<<EOF" >> $GITHUB_OUTPUT
printf '%s\n' "$DESC" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
shell: bash
sign-ipas:
name: Sign IPAs
needs: build-unsigned-ipa
runs-on: macos-15
timeout-minutes: 60
steps:
- name: Download Unsigned IPA
uses: actions/download-artifact@v4
with:
name: com.prostoreios.prostore-unsigned-ios.ipa
path: build
- name: Fetch Certificates List and Sign
run: |
set -euo pipefail
UNSIGNED_IPA="build/com.prostoreios.prostore-unsigned-ios.ipa"
if [ ! -f "$UNSIGNED_IPA" ]; then
echo "ERROR: Unsigned IPA not found: $UNSIGNED_IPA"
exit 1
fi
# Fetch README.md containing the certificates table
curl -s https://raw.githubusercontent.com/ProStore-iOS/certificates/refs/heads/main/README.md -o readme.md
echo "----- README excerpt -----"
sed -n '1,200p' readme.md || true
echo "----- Matching lines (table rows) -----"
# Print all data rows from the Markdown table:
# lines that start with '|' but skip the alignment row and header row containing 'Company'
awk -F'|' '/^\|/ && $2 !~ /Company/ && $2 !~ /^:/{ name=$2; gsub(/^[ \t]+|[ \t]+$/,"",name); print " " $0 }' readme.md || true
# Extract company/display names (field 2) from every table data row (skip header & alignment)
# This produces one company/display name per line.
awk -F'|' '/^\|/ && $2 !~ /Company/ && $2 !~ /^:/{ name=$2; gsub(/^[ \t]+|[ \t]+$/,"",name); print name }' readme.md > cert-names.txt || true
MATCH_COUNT=0
if [ -f cert-names.txt ]; then
MATCH_COUNT=$(wc -l < cert-names.txt | tr -d ' ')
fi
echo "Found $MATCH_COUNT certificate line(s) in README."
if [ "$MATCH_COUNT" -eq 0 ]; then
echo "No certificate rows found. Exiting."
exit 0
fi
# Install dependencies (no-op if already installed)
brew install pkg-config openssl minizip
# Build zsign
rm -rf zsign || true
git clone https://github.com/zhlynn/zsign.git
pushd zsign/build/macos >/dev/null
make clean && make
popd >/dev/null
# Locate the zsign binary (expected at zsign/bin/zsign)
ZSIGN_PATH="$(pwd)/zsign/bin/zsign"
if [ ! -x "$ZSIGN_PATH" ]; then
echo "zsign not found at expected path $ZSIGN_PATH; searching..."
FOUND=$(find "$(pwd)/zsign" -type f -name zsign -perm -111 -print -quit || true)
if [ -n "$FOUND" ]; then
ZSIGN_PATH="$FOUND"
else
echo "zsign binary not found. Listing zsign tree for debugging:"
ls -la zsign || true
exit 1
fi
fi
echo "Using zsign: $ZSIGN_PATH"
ls -l "$ZSIGN_PATH" || true
# Prepare output directory for signed IPAs
SIGNED_DIR="signed-ipas"
mkdir -p "$SIGNED_DIR"
# Iterate over every certificate name (one per line) and attempt to sign
while IFS= read -r FULL_NAME || [ -n "$FULL_NAME" ]; do
# skip empty lines
if [ -z "${FULL_NAME// /}" ]; then
echo "Skipping empty certificate name"
continue
fi
echo "---- Processing: '$FULL_NAME' ----"
# Create safe short name for filenames and dirs
SHORT_NAME=$(echo "$FULL_NAME" | tr '[:upper:]' '[:lower:]' \
| sed -E 's/[^a-z0-9]+/-/g' | sed -E 's/^-+|-+$//g')
# URL-encode the full display name for GitHub raw path
ENCODED=$(printf '%s' "$FULL_NAME" | python3 -c 'import sys,urllib.parse as u; print(u.quote(sys.stdin.read().strip()))')
CERT_DIR="certs/$SHORT_NAME"
mkdir -p "$CERT_DIR"
pushd "$CERT_DIR" >/dev/null
# Try downloading the three required files. If any are missing, skip this cert.
echo "Downloading assets for '$FULL_NAME' (encoded: $ENCODED)..."
if ! curl -sS -fLO "https://github.com/ProStore-iOS/certificates/raw/refs/heads/main/${ENCODED}/${ENCODED}.mobileprovision"; then
echo " -> Missing mobileprovision for '$FULL_NAME', skipping."
popd >/dev/null
continue
fi
if ! curl -sS -fLO "https://github.com/ProStore-iOS/certificates/raw/refs/heads/main/${ENCODED}/${ENCODED}.p12"; then
echo " -> Missing .p12 for '$FULL_NAME', skipping."
popd >/dev/null
continue
fi
if ! curl -sS -fLO "https://github.com/ProStore-iOS/certificates/raw/refs/heads/main/${ENCODED}/password.txt"; then
echo " -> Missing password.txt for '$FULL_NAME', skipping."
popd >/dev/null
continue
fi
popd >/dev/null
SIGNED_IPA="${SIGNED_DIR}/com.prostoreios.prostore-signed-${SHORT_NAME}-ios.ipa"
# Run zsign; ensure p12 password is read safely
P12_PASS="$(cat "${CERT_DIR}/password.txt" || echo "")"
if [ -z "$P12_PASS" ]; then
echo " -> Empty password for ${FULL_NAME}, skipping."
continue
fi
echo " -> Signing into $SIGNED_IPA ..."
if "$ZSIGN_PATH" -k "${CERT_DIR}/${ENCODED}.p12" \
-p "$P12_PASS" \
-m "${CERT_DIR}/${ENCODED}.mobileprovision" \
-o "$SIGNED_IPA" \
"$UNSIGNED_IPA"; then
echo " -> Signed OK: $SIGNED_IPA"
else
echo " -> zsign failed for $FULL_NAME; see zsign output above. Skipping."
# don't exit whole job; continue with next cert
continue
fi
done < cert-names.txt
echo "Signing complete. Signed files:"
ls -la "$SIGNED_DIR" || true
- name: Upload signed IPAs
uses: actions/upload-artifact@v4
with:
name: signed-ipas
path: signed-ipas/*.ipa
create-github-release:
name: Create GitHub Release
needs: [build-unsigned-ipa, sign-ipas]
# job-level if must use expression syntax and reference the correct job id
if: ${{ needs.build-unsigned-ipa.outputs.release_exists == 'false' }}
runs-on: ubuntu-latest
steps:
- name: Install GitHub CLI
run: |
if ! command -v gh >/dev/null 2>&1; then
echo "gh not found — attempting official installer script"
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt update
sudo apt install gh -y || true
fi
echo "gh: $(gh --version 2>/dev/null || echo 'not installed')"
- name: Download All Artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Create Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ needs.build-unsigned-ipa.outputs.version }}
CHANGELOG: ${{ needs.build-unsigned-ipa.outputs.changelog }}
run: |
TAG="v$VERSION"
echo "Creating release $TAG with notes:"
printf '%s\n' "$CHANGELOG"
IPAS=$(find artifacts -type f -name '*.ipa' -print0 | xargs -0)
if [ -z "$IPAS" ]; then
echo "No IPAs found to upload."
exit 1
fi
gh release create "$TAG" \
$IPAS \
--title "ProStore v$VERSION" \
--notes "$CHANGELOG" \
--repo "$GITHUB_REPOSITORY"
shell: bash
update-prostore-repo-json:
name: Update ProStore Repo JSON
needs: build-unsigned-ipa
if: ${{ needs.build-unsigned-ipa.outputs.release_exists == 'false' }}
runs-on: ubuntu-latest
env:
VERSION: ${{ needs.build-unsigned-ipa.outputs.version }}
CHANGELOG: ${{ needs.build-unsigned-ipa.outputs.changelog }}
steps:
- name: Install jq
run: |
if ! command -v jq >/dev/null 2>&1; then
echo "jq not found — attempting to install"
sudo apt update
sudo apt install jq -y || true
fi
echo "jq: $(jq --version 2>/dev/null || echo 'not installed')"
- name: Download Device IPA
uses: actions/download-artifact@v4
with:
name: com.prostoreios.prostore-unsigned-ios.ipa
path: build
- name: Update Apps JSON in Pages Repo
env:
PAGES_PAT: ${{ secrets.PAGES_PAT }}
run: |
set -e
IPA_PATH="$PWD/build/com.prostoreios.prostore-unsigned-ios.ipa"
DOWNLOAD_URL="https://github.com/ProStore-iOS/ProStore/releases/download/v$VERSION/com.prostoreios.prostore-unsigned-ios.ipa"
if [ -f "$IPA_PATH" ]; then
IPA_SIZE=$(stat -c%s "$IPA_PATH")
SHA256=$(sha256sum "$IPA_PATH" | awk '{print $1}')
else
IPA_SIZE=0
SHA256=""
fi
VERSION_DATE_ISO=$(date -u +"%Y-%m-%dT%H:%M:%S%z")
MIN_OS="16.0"
FULL_DATE=$(date +%Y%m%d%H%M%S)
ICON_URL="https://raw.githubusercontent.com/ProStore-iOS/ProStore-iOS.github.io/refs/heads/main/ProStore_icon.png"
BUNDLE="com.prostoreios.prostore"
META_DESC="The BEST alternative app store for iOS!"
DEVNAME="ProStore iOS"
SCREENSHOTS='["https://raw.githubusercontent.com/ProStore-iOS/ProStore/refs/heads/main/gallery/Screenshot1.png","https://raw.githubusercontent.com/ProStore-iOS/ProStore/refs/heads/main/gallery/Screenshot2.png","https://raw.githubusercontent.com/ProStore-iOS/ProStore/refs/heads/main/gallery/Screenshot3.png","https://raw.githubusercontent.com/ProStore-iOS/ProStore/refs/heads/main/gallery/Screenshot4.png","https://raw.githubusercontent.com/ProStore-iOS/ProStore/refs/heads/main/gallery/Screenshot5.png"]'
PAGES_REPO="ProStore-iOS/ProStore-iOS.github.io"
PAGES_DIR=$(mktemp -d)
git clone --depth 1 "https://x-access-token:${PAGES_PAT}@github.com/${PAGES_REPO}.git" "$PAGES_DIR"
cd "$PAGES_DIR"
REPO_FILE="apps.json"
if [ ! -f "$REPO_FILE" ]; then
jq -n --arg icon "$ICON_URL" '{
name: "Official ProStore Repo",
identifier: "com.prostoreios.prostore.repo",
sourceURL: "https://ProStore-iOS.github.io/apps.json",
iconURL: $icon,
website: "https://ProStore-iOS.github.io",
subtitle: "The BEST alternative app store for iOS!",
apps: []
}' > "$REPO_FILE"
fi
TMP=$(mktemp)
NEW_VERSION=$(jq -c -n \
--arg version "$VERSION" \
--arg date "$VERSION_DATE_ISO" \
--arg desc "$CHANGELOG" \
--arg url "$DOWNLOAD_URL" \
--arg sha "$SHA256" \
--arg minos "$MIN_OS" \
--arg fulldate "$FULL_DATE" \
--argjson size "$IPA_SIZE" \
'{version: $version, date: $date, localizedDescription: $desc, downloadURL: $url, size: $size, sha256: $sha, minOSVersion: $minos, fullDate: $fulldate}')
JQ_QUERY='(.apps //= []) | if ( .apps | map(.bundleIdentifier // .bundleID) | index($bundle) ) then .apps |= map( if ((.bundleIdentifier // .bundleID) == $bundle) then ( { "name": $name, "bundleIdentifier": $bundle, "developerName": $dev, "localizedDescription": $appdesc, "iconURL": $icon, "screenshotURLs": $screenshots } + { "versions": ( [ $newVer ] + ( .versions // [] ) ) } ) else . end ) else .apps += [ { "name": $name, "bundleIdentifier": $bundle, "developerName": $dev, "localizedDescription": $appdesc, "iconURL": $icon, "screenshotURLs": $screenshots, "versions": [ $newVer ] } ] end'
jq --argjson newVer "$NEW_VERSION" \
--arg name "ProStore" \
--arg bundle "$BUNDLE" \
--arg dev "$DEVNAME" \
--arg appdesc "$META_DESC" \
--arg icon "$ICON_URL" \
--argjson screenshots "$SCREENSHOTS" \
"$JQ_QUERY" "$REPO_FILE" > "$TMP" && mv "$TMP" "$REPO_FILE"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add "$REPO_FILE"
if git diff --quiet --cached; then
echo "No changes to apps.json — nothing to commit/push."
exit 0
fi
git commit -m "Update apps.json for ProStore v${VERSION}"
echo "Pushing apps.json to ${PAGES_REPO}:main"
git push "https://x-access-token:${PAGES_PAT}@github.com/${PAGES_REPO}.git" HEAD:main
shell: bash