mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-09-01 19:49:54 +02:00
153 lines
5.5 KiB
YAML
153 lines
5.5 KiB
YAML
name: Notesnook iOS Preview Build
|
|
|
|
# UNTRUSTED stage. Runs on `pull_request`, so fork code is checked out and
|
|
# compiled with a read-only GITHUB_TOKEN and NO repository secrets. It only
|
|
# produces an *unsigned* archive. Signing, Firebase distribution and PR
|
|
# comments happen in ios.preview.publish.yml, which runs in the trusted
|
|
# `workflow_run` context and never executes fork code. Because no secrets are
|
|
# exposed here, the build runs automatically for every PR (including forks)
|
|
# with no authorization gate.
|
|
|
|
on:
|
|
pull_request:
|
|
types: [opened, reopened, synchronize]
|
|
branches: [master, beta]
|
|
paths:
|
|
- "apps/mobile/**"
|
|
- "packages/**"
|
|
- ".github/workflows/ios.preview.build.yml"
|
|
- ".github/workflows/ios.preview.publish.yml"
|
|
|
|
# A fork that spams pushes shouldn't queue up macOS builds.
|
|
concurrency:
|
|
group: ios-preview-${{ github.event.pull_request.number }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
build:
|
|
runs-on: macos-26
|
|
timeout-minutes: 60
|
|
|
|
steps:
|
|
- name: Checkout PR code
|
|
uses: actions/checkout@v5
|
|
with:
|
|
ref: ${{ github.event.pull_request.head.sha }}
|
|
|
|
- name: Setup Node
|
|
uses: ./.github/actions/setup-node-with-cache
|
|
|
|
- name: Setup Xcode
|
|
uses: maxim-lobanov/setup-xcode@v1
|
|
with:
|
|
xcode-version: "26.1.1"
|
|
|
|
- name: Setup iOS Platform
|
|
run: |
|
|
# GitHub runs this as `/bin/bash -e`, so `set +e` is required -- without
|
|
# it the first failure aborts the step before any retry can happen.
|
|
# Both commands hit "Unable to connect to simulator" (exit 70) when
|
|
# CoreSimulatorService is wedged, so retry each and bounce it between.
|
|
set +e
|
|
DL_DIR="$RUNNER_TEMP/ios-platform"
|
|
|
|
retry() {
|
|
for i in 1 2 3; do
|
|
"$@" && return 0
|
|
echo "Attempt $i failed ($*); resetting CoreSimulator..."
|
|
sudo killall -9 com.apple.CoreSimulator.CoreSimulatorService simdiskimaged 2>/dev/null
|
|
sleep 20
|
|
xcrun simctl list runtimes >/dev/null 2>&1
|
|
done
|
|
echo "::error::Failed after 3 attempts: $*"
|
|
exit 1
|
|
}
|
|
|
|
xcrun simctl list runtimes >/dev/null 2>&1
|
|
retry xcodebuild -downloadPlatform iOS -exportPath "$DL_DIR"
|
|
|
|
# Find the dmg; its name embeds a build number that changes.
|
|
DMG="$(find "$DL_DIR" -name '*.dmg' | head -n1)"
|
|
[ -n "$DMG" ] || { echo "::error::No dmg in $DL_DIR"; exit 1; }
|
|
retry xcodebuild -importPlatform "$DMG"
|
|
|
|
- name: Install node modules
|
|
run: |
|
|
npm ci --ignore-scripts --prefer-offline --no-audit
|
|
npm run bootstrap -- --scope=mobile
|
|
|
|
- name: Build packages
|
|
run: npm run tx @notesnook/mobile:build
|
|
|
|
- name: Cache Pods
|
|
uses: actions/cache@v4
|
|
id: pods-cache
|
|
with:
|
|
path: apps/mobile/ios/Pods
|
|
key: ${{ runner.os }}-pods-${{ hashFiles('apps/mobile/ios/Podfile.lock') }}
|
|
|
|
- name: Install Pods
|
|
run: |
|
|
cd apps/mobile/ios
|
|
pod install
|
|
|
|
- name: Check for typescript errors
|
|
run: |
|
|
npm run tx mobile:build
|
|
cd apps/mobile
|
|
npx tsc --noEmit
|
|
|
|
- name: Get marketing version
|
|
id: marketing-version
|
|
run: echo "version=$(grep "IOS_MARKETING_VERSION" apps/mobile/ios/build-configs/ios-build.staging.xcconfig | awk -F'=' '{print $2}' | xargs)" >> $GITHUB_OUTPUT
|
|
|
|
- name: Get build number
|
|
id: build-number
|
|
run: echo "timestamp=$(($(date +%s) - 1774851180 ))" >> $GITHUB_OUTPUT
|
|
|
|
- name: Make staging xcconfig active
|
|
run: |
|
|
cd apps/mobile/ios/build-configs
|
|
./use-ios-build-config.sh staging --marketing-version ${{steps.marketing-version.outputs.version}} --build-number ${{steps.build-number.outputs.timestamp}}
|
|
|
|
# Archive unsigned: this job has no certs/profiles (secrets), and the iOS
|
|
# device SDK forbids ad-hoc signing, so real signing happens in the trusted
|
|
# publish workflow (ios.preview.publish.yml). Do NOT pass
|
|
# CODE_SIGN_ENTITLEMENTS="" -- each target must keep its own entitlements so
|
|
# the archive records them; blanking them dropped the App Group and crashed
|
|
# MMKV on launch.
|
|
- name: Archive (unsigned)
|
|
run: |
|
|
set -euo pipefail
|
|
xcodebuild \
|
|
-workspace apps/mobile/ios/Notesnook.xcworkspace \
|
|
-scheme Notesnook \
|
|
-configuration Release \
|
|
-sdk iphoneos \
|
|
-destination 'generic/platform=iOS' \
|
|
-archivePath "$RUNNER_TEMP/Notesnook.xcarchive" \
|
|
CODE_SIGNING_ALLOWED=NO \
|
|
CODE_SIGNING_REQUIRED=NO \
|
|
CODE_SIGN_IDENTITY="" \
|
|
archive
|
|
|
|
- name: Stage build artifact
|
|
run: |
|
|
set -euo pipefail
|
|
mkdir -p "$RUNNER_TEMP/artifact"
|
|
tar -czf "$RUNNER_TEMP/artifact/Notesnook.xcarchive.tar.gz" \
|
|
-C "$RUNNER_TEMP" Notesnook.xcarchive
|
|
# Carry the PR context forward; workflow_run cannot see it reliably for forks.
|
|
{
|
|
echo "PR_NUMBER=${{ github.event.pull_request.number }}"
|
|
echo "HEAD_SHA=${{ github.event.pull_request.head.sha }}"
|
|
} > "$RUNNER_TEMP/artifact/pr-meta.env"
|
|
|
|
- name: Upload build artifact
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: ios-preview-build
|
|
path: ${{ runner.temp }}/artifact
|
|
if-no-files-found: error
|
|
retention-days: 1
|