Add CI: auto-build IPA and GitHub Releases

- Shared Xcode scheme for headless xcodebuild
- build.yml: build unsigned IPA on push/PR, upload artifact
- release.yml: on v* tags (or manual dispatch), publish Release with IPA
This commit is contained in:
Mak5er committed 2026-08-11 05:28:06 +03:00
1 parent 18a67ec171
commit dd3b90d629
5 files changed
+267 -1

No files matched your search

+61
View File
@@ -0,0 +1,61 @@
name: Build IPA
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
concurrency:
group: build-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Build unsigned IPA
runs-on: macos-15
timeout-minutes: 45
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Select Xcode
run: |
# Prefer newest installed Xcode
ls /Applications | grep -i Xcode || true
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
xcodebuild -version
xcodebuild -showsdks | grep iphoneos || true
- name: Resolve packages
run: |
xcodebuild -project "Pocket Poster.xcodeproj" \
-scheme "Pocket Poster" \
-resolvePackageDependencies
- name: Build IPA
run: |
chmod +x ./ipabuild.sh
./ipabuild.sh
- name: Prepare artifact
run: |
VERSION=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' \
"build/DerivedDataApp/Build/Products/Release-iphoneos/Pocket Poster.app/Info.plist" 2>/dev/null \
|| grep -m1 'MARKETING_VERSION' "Pocket Poster.xcodeproj/project.pbxproj" | sed 's/[^0-9.]//g')
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
test -f "build/Pocket_Poster.ipa" || cp "build/Pocket Poster.ipa" "build/Pocket_Poster.ipa"
cp "build/Pocket_Poster.ipa" "build/Pocket_Poster_${VERSION}.ipa"
ls -lh build/*.ipa
- name: Upload IPA (artifact)
uses: actions/upload-artifact@v4
with:
name: Pocket_Poster-${{ env.VERSION }}
path: |
build/Pocket_Poster.ipa
build/Pocket_Poster_*.ipa
if-no-files-found: error
retention-days: 30
+112
View File
@@ -0,0 +1,112 @@
name: Release IPA
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Release tag (e.g. v3.2.2). Leave empty to use MARKETING_VERSION.'
required: false
default: ''
permissions:
contents: write
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
release:
name: Build & publish release
runs-on: macos-15
timeout-minutes: 45
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Select Xcode
run: |
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
xcodebuild -version
- name: Resolve packages
run: |
xcodebuild -project "Pocket Poster.xcodeproj" \
-scheme "Pocket Poster" \
-resolvePackageDependencies
- name: Build IPA
run: |
chmod +x ./ipabuild.sh
./ipabuild.sh
- name: Prepare release files
id: meta
run: |
set -euo pipefail
APP_PLIST="build/DerivedDataApp/Build/Products/Release-iphoneos/Pocket Poster.app/Info.plist"
VERSION=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "$APP_PLIST")
BUILD=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleVersion' "$APP_PLIST")
BUNDLE_ID=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$APP_PLIST")
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ inputs.tag }}" ]; then
TAG="${{ inputs.tag }}"
elif [[ "${{ github.ref }}" == refs/tags/* ]]; then
TAG="${GITHUB_REF_NAME}"
else
TAG="v${VERSION}"
fi
# ipabuild.sh emits Pocket_Poster.ipa (+ legacy name)
test -f "build/Pocket_Poster.ipa" || cp "build/Pocket Poster.ipa" "build/Pocket_Poster.ipa"
cp "build/Pocket_Poster.ipa" "build/Pocket_Poster_${VERSION}.ipa"
{
echo "version=$VERSION"
echo "build=$BUILD"
echo "bundle_id=$BUNDLE_ID"
echo "tag=$TAG"
} >> "$GITHUB_OUTPUT"
cat > release_notes.md <<EOF
## Pocket Poster ${VERSION}
bad_query fork for **iOS 26 – 27.0b4**
- On-device PosterBoard hash (no PC / Nugget)
- Apply wallpapers via sandbox escape
- Reset Collections (descriptor wipe)
- Mond-style WebKit respring (works in LiveContainer)
**Bundle ID:** \`${BUNDLE_ID}\`
**Build:** ${BUILD}
Sideload with TrollStore / SideStore / LiveContainer.
---
Credits: [forcequitOS/bad_query](https://github.com/forcequitOS/bad_query) · original [leminlimez/Pocket-Poster](https://github.com/leminlimez/Pocket-Poster)
EOF
ls -lh build/*.ipa
echo "Tag: $TAG Version: $VERSION"
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.meta.outputs.tag }}
name: Pocket Poster ${{ steps.meta.outputs.version }}
body_path: release_notes.md
draft: false
prerelease: false
generate_release_notes: true
files: |
build/Pocket_Poster.ipa
build/Pocket_Poster_${{ steps.meta.outputs.version }}.ipa
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1620"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6F09B79C2DEB694B00CDE89C"
BuildableName = "Pocket Poster.app"
BlueprintName = "Pocket Poster"
ReferencedContainer = "container:Pocket Poster.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6F09B79C2DEB694B00CDE89C"
BuildableName = "Pocket Poster.app"
BlueprintName = "Pocket Poster"
ReferencedContainer = "container:Pocket Poster.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6F09B79C2DEB694B00CDE89C"
BuildableName = "Pocket Poster.app"
BlueprintName = "Pocket Poster"
ReferencedContainer = "container:Pocket Poster.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
+11
View File
@@ -11,6 +11,17 @@
</a>
</div>
## Download
Latest IPA: [**Releases**](https://github.com/Mak5er/Pocket-Poster/releases/latest)
CI builds an unsigned IPA on every push to `main` and publishes a GitHub Release when you push a tag like `v3.2.2` (or run **Release IPA** from Actions).
```bash
# cut a release from your machine
git tag v3.2.2 && git push origin v3.2.2
```
## Getting Started
### iOS 26 / 27.0b4 (bad_query)
+6 -1
View File
@@ -42,7 +42,12 @@ fi
mkdir Payload
cp -r "${APPLICATION_NAME}.app" "Payload/${APPLICATION_NAME}.app"
strip "Payload/${APPLICATION_NAME}.app/${APPLICATION_NAME}"
zip -vr "${APPLICATION_NAME}.ipa" Payload
# quiet zip for CI logs; name with underscore for download URLs
zip -qr "Pocket_Poster.ipa" Payload
# keep legacy name too
cp "Pocket_Poster.ipa" "${APPLICATION_NAME}.ipa"
rm -rf "${APPLICATION_NAME}.app"
rm -rf Payload
echo "Built: $WORKING_LOCATION/build/Pocket_Poster.ipa"
echo "Built: $WORKING_LOCATION/build/${APPLICATION_NAME}.ipa"