GitHub now forces actions/checkout, actions/cache and softprops/action-gh-release onto Node 24 and warns on every run, because the majors pinned here still declare Node 20. Forcing works until it stops. Each moves to the major that made the runtime change and no further: checkout v5, cache v5, action-gh-release v3. The newer majors after those carry unrelated changes, a credential file move and an ESM migration among them, and none of that is what the deprecation is asking for. The inputs used here are the same in all of them, so nothing else needed touching. They require a runner of 2.327.1 or newer, which every GitHub-hosted runner is. The docker actions were never affected.
118 lines
5.6 KiB
YAML
118 lines
5.6 KiB
YAML
name: iOS Dev Repo
|
|
# Builds an unsigned dev IPA and publishes it together with a freshly-generated
|
|
# AltStore source (devrepo.json) to a rolling "dev" prerelease.
|
|
# https://github.com/FTStuff/FTStore/releases/download/dev/devrepo.json
|
|
#
|
|
# Monorepo: the Xcode project lives in ios/, so every build step runs there.
|
|
# app-repo.json stays at the repo root — its raw.githubusercontent URL is what
|
|
# users have subscribed to, so it must not move.
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
paths:
|
|
- "ios/**"
|
|
- ".github/workflows/ios-dev-repo.yml"
|
|
workflow_dispatch:
|
|
concurrency:
|
|
group: dev-repo-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
permissions:
|
|
contents: write
|
|
jobs:
|
|
build:
|
|
# macOS label required: the bare `self-hosted` label also matches the org's
|
|
# Linux runners, which have no xcodebuild and fail the build outright.
|
|
runs-on: [self-hosted, macOS]
|
|
env:
|
|
DEVELOPER_DIR: /Applications/Xcode.app/Contents/Developer # statt sudo xcode-select
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v5
|
|
with:
|
|
submodules: recursive
|
|
fetch-depth: 1
|
|
- name: Cache SwiftPM
|
|
uses: actions/cache@v5
|
|
with:
|
|
path: ~/Library/Caches/org.swift.swiftpm
|
|
key: spm-${{ runner.os }}-${{ hashFiles('**/Package.resolved') }}
|
|
restore-keys: spm-${{ runner.os }}-
|
|
- name: Compute dev version
|
|
run: |
|
|
BASE=$(grep '^FTSTORE_PROJECT_VERSION' ios/FTStore.xcconfig | cut -d= -f2 | tr -d '[:space:]')
|
|
echo "VERSION=${BASE}-dev.${{ github.run_number }}" >> "$GITHUB_ENV"
|
|
echo "DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_ENV"
|
|
- name: Stamp marketing version
|
|
# NOT agvtool: it writes CFBundleShortVersionString into Info.plist, but
|
|
# the target sets MARKETING_VERSION = $(FTSTORE_PROJECT_VERSION) and
|
|
# GENERATE_INFOPLIST_FILE = YES, so Xcode regenerates that key from the
|
|
# build setting and the edit is thrown away. The IPA then reports the
|
|
# base version while devrepo.json advertises the dev one, and every
|
|
# AltStore client sees a permanent "update available". Set the variable
|
|
# the build actually reads, and fail loudly if it ever stops matching.
|
|
run: |
|
|
sed -i '' "s|^FTSTORE_PROJECT_VERSION=.*|FTSTORE_PROJECT_VERSION=${VERSION}|" ios/FTStore.xcconfig
|
|
grep -q "^FTSTORE_PROJECT_VERSION=${VERSION}$" ios/FTStore.xcconfig
|
|
- name: Stamp build number (best effort)
|
|
# Records the source commit in CFBundleVersion. Best effort because
|
|
# agvtool trips over GENERATE_INFOPLIST_FILE=YES ("Cannot find …/YES")
|
|
# while still doing the write.
|
|
continue-on-error: true
|
|
working-directory: ios
|
|
run: agvtool new-version -all "${{ github.sha }}"
|
|
- name: Build (iphoneos, unsigned)
|
|
working-directory: ios
|
|
run: make iphoneos
|
|
- name: Verify the Live Activity extension shipped and can load
|
|
# The Dynamic Island lives in an embedded appex, so an IPA that is wrong
|
|
# about it installs and runs perfectly — the island just never appears,
|
|
# and nothing in the build says why. Every check here is for a way that
|
|
# can happen silently:
|
|
#
|
|
# missing the extension is not in the IPA at all. This is what
|
|
# happened when manager/ shared this build's derived data
|
|
# (identical project, scheme, target and pbxproj GUIDs)
|
|
# and its stale-file sweep went after an extension it has
|
|
# no target for.
|
|
# wrong id iOS refuses to load an app extension whose bundle id is
|
|
# not prefixed by its host app's, and says nothing. The
|
|
# two ids are built from separate settings in the pbxproj,
|
|
# so one can drift from the other — and a disambiguator
|
|
# applied to the app but not the extension does exactly
|
|
# that.
|
|
# wrong point a widget extension must declare the widgetkit extension
|
|
# point. Without it the appex is dead weight.
|
|
#
|
|
# Presence alone was the old check. It passed on all three of these.
|
|
run: ios/scripts/verify-live-activity.sh ios/packages/FTStore.ipa
|
|
- name: Generate devrepo.json
|
|
run: |
|
|
IPA=ios/packages/FTStore.ipa
|
|
SIZE=$(stat -f%z "$IPA")
|
|
URL="https://github.com/${{ github.repository }}/releases/download/dev/FTStore.ipa"
|
|
jq \
|
|
--arg v "$VERSION" --arg d "$DATE" --argjson s "$SIZE" --arg u "$URL" '
|
|
.name = "FTStore (Dev)" |
|
|
.identifier = "app.ftstore.devrepo" |
|
|
.apps[0].name = "FTStore (Dev)" |
|
|
.apps[0].subtitle = "Latest commit build — for testing" |
|
|
.apps[0].version = $v |
|
|
.apps[0].versionDate = $d |
|
|
.apps[0].size = $s |
|
|
.apps[0].downloadURL = $u |
|
|
.apps[0].versions = [ { "version": $v, "date": $d, "size": $s, "downloadURL": $u } ] |
|
|
.news = []
|
|
' app-repo.json > devrepo.json
|
|
echo "Generated devrepo.json for $VERSION (${SIZE} bytes)"
|
|
- name: Publish dev prerelease
|
|
uses: softprops/action-gh-release@v3
|
|
with:
|
|
tag_name: dev
|
|
name: Dev build
|
|
prerelease: true
|
|
make_latest: false
|
|
body: "Rolling development build of the latest `main` commit (${{ github.sha }}). Unsigned — FTStore (formerly Feather) signs it on-device at install."
|
|
files: |
|
|
ios/packages/FTStore.ipa
|
|
devrepo.json
|