diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..0082ef4 --- /dev/null +++ b/.github/workflows/build.yml @@ -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 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..0aeb587 --- /dev/null +++ b/.github/workflows/release.yml @@ -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 < + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md index fa42ce2..57c7817 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,17 @@ +## 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) diff --git a/ipabuild.sh b/ipabuild.sh index 39671f8..33f00e0 100755 --- a/ipabuild.sh +++ b/ipabuild.sh @@ -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"