Build iOS App / Build .ipa and publish source (push) Successful in 28s
The built bundle contains sized variants (AppIcon60x60@2x.png etc.), not a file named AppIcon.png, so the CI cp failed and scp aborted. Commit the 1024x1024 icon.png to the repo root and upload it directly.
99 lines
3.8 KiB
YAML
99 lines
3.8 KiB
YAML
name: Build iOS App
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
build:
|
|
name: Build .ipa and publish source
|
|
runs-on: macos
|
|
env:
|
|
# Per-app: change APP_NAME for each app repo. Used everywhere so the
|
|
# perlis dir name and file names always match (no hardcoded drift).
|
|
APP_NAME: GiteaPR
|
|
# Point xcodebuild at full Xcode without sudo (sudo hangs in CI).
|
|
# DEVELOPER_DIR overrides the active developer directory for all steps.
|
|
DEVELOPER_DIR: /Applications/Xcode.app/Contents/Developer
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Select Xcode
|
|
run: |
|
|
xcodebuild -version
|
|
|
|
- name: Build unsigned .ipa
|
|
run: |
|
|
# Build the app bundle (no signing — SideStore signs on-device)
|
|
xcodebuild \
|
|
-project $APP_NAME.xcodeproj \
|
|
-scheme $APP_NAME \
|
|
-configuration Release \
|
|
-sdk iphoneos \
|
|
-destination 'generic/platform=iOS' \
|
|
-derivedDataPath build \
|
|
CODE_SIGNING_ALLOWED=NO \
|
|
CODE_SIGNING_REQUIRED=NO \
|
|
CODE_SIGN_IDENTITY="" \
|
|
build
|
|
|
|
# Locate the .app bundle
|
|
APP_PATH=$(find build/Build/Products -name "*.app" -type d | head -1)
|
|
echo "App bundle: $APP_PATH"
|
|
|
|
# Package into an .ipa (Payload/App.app structure)
|
|
mkdir -p dist/Payload
|
|
cp -R "$APP_PATH" dist/Payload/
|
|
cd dist
|
|
zip -r ../$APP_NAME.ipa Payload
|
|
cd ..
|
|
ls -la $APP_NAME.ipa
|
|
|
|
- name: Generate app metadata
|
|
run: |
|
|
# Read the version from the built app's Info.plist so it can never
|
|
# drift from MARKETING_VERSION in the pbxproj. SideStore only shows an
|
|
# update when the version changes, so a stale hardcoded version here
|
|
# silently hides new builds.
|
|
APP_PATH=$(find build/Build/Products -name "*.app" -type d | head -1)
|
|
VERSION=$(/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "$APP_PATH/Info.plist")
|
|
BUILD=$(/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "$APP_PATH/Info.plist")
|
|
SIZE=$(stat -f%z $APP_NAME.ipa)
|
|
DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
echo "version=$VERSION build=$BUILD"
|
|
# Per-app metadata file. The perlis aggregator folds this into the
|
|
# root source.json at https://apps.bueso.eu/source.json.
|
|
cat > $APP_NAME.json <<EOF
|
|
{
|
|
"name": "GiteaPR",
|
|
"bundleIdentifier": "com.bueso.giteapr",
|
|
"developerName": "Luis",
|
|
"localizedDescription": "Manage Gitea pull requests from your iPhone.",
|
|
"iconURL": "https://apps.bueso.eu/$APP_NAME/icon.png",
|
|
"downloadURL": "https://apps.bueso.eu/$APP_NAME/$APP_NAME.ipa",
|
|
"version": "$VERSION",
|
|
"versionDate": "$DATE",
|
|
"size": $SIZE,
|
|
"permissions": []
|
|
}
|
|
EOF
|
|
cat $APP_NAME.json
|
|
|
|
- name: Upload to source host (perlis)
|
|
run: |
|
|
# Upload .ipa + per-app metadata + icon to perlis via SSH.
|
|
# PERLIS_SSH_HOST is the Tailscale MagicDNS name (perlis.bueso.loc),
|
|
# reachable from the iMac runner over the Tailscale mesh.
|
|
# icon.png is committed to the repo (1024x1024) and uploaded as-is;
|
|
# the metadata's iconURL points at
|
|
# https://apps.bueso.eu/$APP_NAME/icon.png.
|
|
ssh -o StrictHostKeyChecking=no \
|
|
"${{ secrets.PERLIS_SSH_USER }}@${{ secrets.PERLIS_SSH_HOST }}" \
|
|
"mkdir -p /mnt/appdata/ios-apps/$APP_NAME"
|
|
scp -o StrictHostKeyChecking=no \
|
|
$APP_NAME.ipa $APP_NAME.json icon.png \
|
|
"${{ secrets.PERLIS_SSH_USER }}@${{ secrets.PERLIS_SSH_HOST }}:/mnt/appdata/ios-apps/$APP_NAME/"
|