build-nym-vpn-apple #55
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: build-nym-vpn-apple | |
on: | |
pull_request: | |
types: [opened, synchronize, reopened, ready_for_review] | |
paths: | |
- ".github/workflows/build-nym-vpn-apple.yml" | |
- "nym-vpn-apple/**" | |
workflow_dispatch: | |
inputs: | |
release_type: | |
description: "Select build mode" | |
type: choice | |
options: | |
- "pr — Pull Request (unsigned debug build)" | |
- "qa — QA Release (signed, automatic, TestFlight/App Store export)" | |
- "ship — Ship Release (signed, automatic, App Store distribution)" | |
default: "pr — Pull Request (unsigned debug build)" | |
workflow_call: | |
inputs: | |
release_type: | |
description: "Build type: pr | qa | ship (raw or labeled)" | |
type: string | |
default: "pr" | |
outputs: | |
RUST_VERSION: | |
value: ${{ jobs.build-apple.outputs.RUST_VERSION }} | |
env: | |
CARGO_TERM_COLOR: always | |
UPLOAD_DIR_IOS: ios_artifacts | |
RAW_RELEASE_TYPE: ${{ (github.event_name == 'pull_request' && 'pr') || inputs.release_type || 'pr' }} | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
cancel-in-progress: true | |
jobs: | |
build-apple: | |
if: github.actor != 'dependabot[bot]' | |
runs-on: AppleSilicon | |
timeout-minutes: 60 | |
outputs: | |
UPLOAD_DIR_IOS: ${{ env.UPLOAD_DIR_IOS }} | |
RUST_VERSION: ${{ steps.rust-version.outputs.rustc }} | |
steps: | |
- name: Checkout repo | |
uses: actions/checkout@v4 | |
- name: Normalize release_type | |
run: | | |
sel="${{ env.RAW_RELEASE_TYPE }}" | |
case "$sel" in | |
pr*|PR*) mode=pr ;; | |
qa*|QA*) mode=qa ;; | |
ship*|SHIP*) mode=ship ;; | |
*) mode=pr ;; | |
esac | |
echo "RELEASE_TYPE=$mode" >> "$GITHUB_ENV" | |
- name: Show selected release type | |
run: echo "RELEASE_TYPE=${{ env.RELEASE_TYPE }}" | |
- name: Install rust toolchain | |
uses: dtolnay/rust-toolchain@master | |
with: | |
toolchain: ${{ vars.REQUIRED_RUSTC_VERSION }} | |
components: rustfmt, clippy | |
targets: x86_64-apple-darwin aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim | |
- name: Install cargo-swift | |
run: | | |
cargo install \ | |
--git https://github.com/antoniusnaumann/cargo-swift \ | |
--rev 53b948e8f37dd018300ae3fee2d0fd5ece59e2cd \ | |
cargo-swift | |
- name: Install cargo-license | |
if: ${{ env.RELEASE_TYPE == 'qa' || env.RELEASE_TYPE == 'ship' }} | |
run: | | |
cargo install cargo-license | |
- name: Install Protoc | |
uses: arduino/setup-protoc@v3 | |
with: | |
repo-token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Install Go | |
uses: actions/setup-go@v5 | |
with: | |
go-version: ${{ vars.REQUIRED_GOLANG_VERSION }} | |
cache: false | |
- name: Get workspace version | |
id: workspace-version | |
uses: nicolaiunrein/cargo-get@master | |
with: | |
subcommand: workspace.package.version --entry nym-vpn-core | |
- name: Install cargo-edit | |
uses: baptiste0928/cargo-install@v3 | |
with: | |
crate: cargo-edit | |
- name: Add existing Homebrew to PATH (no install) | |
run: | | |
set -euxo pipefail | |
for HB in /opt/homebrew/bin/brew /usr/local/bin/brew; do | |
if [ -x "$HB" ]; then | |
echo "$(dirname "$HB")" >> "$GITHUB_PATH" # future steps | |
export PATH="$(dirname "$HB"):$PATH" # this step | |
eval "$("$HB" shellenv)" # set Homebrew env vars | |
{ | |
echo "HOMEBREW_PREFIX=$HOMEBREW_PREFIX" | |
echo "HOMEBREW_CELLAR=$HOMEBREW_CELLAR" | |
echo "HOMEBREW_REPOSITORY=$HOMEBREW_REPOSITORY" | |
} >> "$GITHUB_ENV" | |
"$HB" --version | |
exit 0 | |
fi | |
done | |
echo "❌ Homebrew binary not found at /opt/homebrew/bin/brew or /usr/local/bin/brew" >&2 | |
exit 1 | |
- name: Update prebundled servers | |
if: ${{ env.RELEASE_TYPE == 'qa' || env.RELEASE_TYPE == 'ship' }} | |
working-directory: nym-vpn-apple/scripts | |
run: | | |
sh UpdatePrebundledServers.sh | |
- name: Enable QA mode | |
if: env.RELEASE_TYPE == 'qa' | |
working-directory: nym-vpn-apple | |
run: | | |
sed -E ':a;N;$!ba; s|(</dict>[[:space:]]*</plist>)| <key>EnvironmentVariables</key>\n <dict>\n <key>RUST_LOG</key>\n <string>debug</string>\n </dict>\n\1|' "Daemon/net.nymtech.vpn.helper.plist" | |
- name: Update licences | |
if: ${{ env.RELEASE_TYPE == 'qa' || env.RELEASE_TYPE == 'ship' }} | |
run: | | |
cargo license -j --avoid-dev-deps --current-dir ./nym-vpn-core --filter-platform x86_64-apple-darwin --avoid-build-deps > ./nym-vpn-apple/NymVPN/Resources/LibLicences.json | |
- name: Install Fastlane | |
if: ${{ env.RELEASE_TYPE == 'qa' || env.RELEASE_TYPE == 'ship' }} | |
run: | | |
brew install fastlane | |
- name: Build core | |
working-directory: nym-vpn-apple/scripts | |
env: | |
VPNLIB_SENTRY_DSN: ${{ secrets.VPND_SENTRY_DSN }} | |
run: | | |
sh BuildCore.sh | |
- name: Build iOS (PR, unsigned Debug) | |
if: env.RELEASE_TYPE == 'pr' | |
working-directory: nym-vpn-apple | |
env: | |
IPHONEOS_DEPLOYMENT_TARGET: 16.0 | |
run: | | |
set -euxo pipefail | |
DERIVED_DATA="$PWD/.DerivedData-iOS" | |
xcodebuild \ | |
-workspace NymVPN.xcworkspace \ | |
-scheme NymVPN \ | |
-configuration Debug \ | |
-destination 'generic/platform=iOS' \ | |
-sdk iphoneos \ | |
-derivedDataPath "$DERIVED_DATA" \ | |
CODE_SIGNING_ALLOWED=NO \ | |
DEVELOPMENT_TEAM= \ | |
build | |
find "$DERIVED_DATA/Build/Products" -maxdepth 3 -name '*.app' -print || true | |
- name: Prepare App Store Connect API key | |
if: env.RELEASE_TYPE != 'pr' | |
id: asc-key | |
working-directory: nym-vpn-apple | |
env: | |
ASC_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY }} | |
ASC_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_ISSUER_ID }} | |
ASC_KEY_BASE64: ${{ secrets.APP_STORE_CONNECT_API_PRIVATE_KEY_BASE64 }} | |
run: | | |
set -euo pipefail | |
KEY_PATH="$RUNNER_TEMP/AuthKey_${ASC_KEY_ID}.p8" | |
echo "$ASC_KEY_BASE64" | base64 --decode > "$KEY_PATH" | |
chmod 600 "$KEY_PATH" | |
echo "key_path=$KEY_PATH" >> "$GITHUB_OUTPUT" | |
- name: Archive iOS (QA/Ship, Distribution, Automatic, ASC auth) | |
if: env.RELEASE_TYPE != 'pr' | |
id: ios-archive | |
working-directory: nym-vpn-apple | |
env: | |
IPHONEOS_DEPLOYMENT_TARGET: 16.0 | |
DEVELOPMENT_TEAM: ${{ secrets.APPLE_TEAM_ID }} | |
run: | | |
set -euxo pipefail | |
ARCHIVE_PATH="$PWD/build/NymVPN-iOS.xcarchive" | |
xcrun xcodebuild \ | |
-workspace NymVPN.xcworkspace \ | |
-scheme NymVPN \ | |
-configuration Release \ | |
-destination 'generic/platform=iOS' \ | |
-sdk iphoneos \ | |
-archivePath "$ARCHIVE_PATH" \ | |
CODE_SIGN_STYLE=Automatic \ | |
CODE_SIGNING_ALLOWED=YES \ | |
DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \ | |
-allowProvisioningUpdates \ | |
-authenticationKeyIssuerID "${{ secrets.APP_STORE_CONNECT_API_ISSUER_ID }}" \ | |
-authenticationKeyID "${{ secrets.APP_STORE_CONNECT_API_KEY }}" \ | |
-authenticationKeyPath "${{ steps.asc-key.outputs.key_path }}" \ | |
clean archive | |
echo "archive_path=$ARCHIVE_PATH" >> "$GITHUB_OUTPUT" | |
- name: Export IPA (QA/Ship – App Store Connect, ASC auth) | |
if: env.RELEASE_TYPE != 'pr' | |
working-directory: nym-vpn-apple | |
run: | | |
set -euxo pipefail | |
EXPORT_DIR="$PWD/build/export-${{ env.RELEASE_TYPE }}" | |
mkdir -p "$EXPORT_DIR" | |
cat > exportOptions.plist <<'EOF' | |
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>method</key><string>app-store-connect</string> | |
<key>signingStyle</key><string>automatic</string> | |
<key>destination</key><string>export</string> | |
<key>stripSwiftSymbols</key><true/> | |
<key>compileBitcode</key><false/> | |
</dict> | |
</plist> | |
EOF | |
xcrun xcodebuild -exportArchive \ | |
-archivePath "${{ steps.ios-archive.outputs.archive_path }}" \ | |
-exportOptionsPlist exportOptions.plist \ | |
-exportPath "$EXPORT_DIR" \ | |
-allowProvisioningUpdates \ | |
-authenticationKeyIssuerID "${{ secrets.APP_STORE_CONNECT_API_ISSUER_ID }}" \ | |
-authenticationKeyID "${{ secrets.APP_STORE_CONNECT_API_KEY }}" \ | |
-authenticationKeyPath "${{ steps.asc-key.outputs.key_path }}" | |
echo "Exported files:"; ls -lah "$EXPORT_DIR" | |
- name: Upload to TestFlight (QA) | |
if: env.RELEASE_TYPE == 'qa' | |
working-directory: nym-vpn-apple | |
env: | |
ASC_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY }} | |
ASC_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_ISSUER_ID }} | |
ASC_KEY_BASE64: ${{ secrets.APP_STORE_CONNECT_API_PRIVATE_KEY }} | |
run: | | |
set -euxo pipefail | |
IPA="$(ls build/export-qa/*.ipa | head -n1)" | |
fastlane ios upload_testflight ipa_path:"$IPA" changelog:"QA build ${GITHUB_SHA}" | |
- name: Archive macOS (QA/Ship, signed Release, automatic) | |
if: ${{ env.RELEASE_TYPE == 'qa' || env.RELEASE_TYPE == 'ship' }} | |
id: mac-archive | |
working-directory: nym-vpn-apple | |
env: | |
MACOSX_DEPLOYMENT_TARGET: 13.0 | |
DEVELOPMENT_TEAM: ${{ secrets.APPLE_TEAM_ID }} | |
run: | | |
set -euxo pipefail | |
ARCHIVE_PATH="$PWD/build/NymVPNDaemon-macOS.xcarchive" | |
xcodebuild \ | |
-workspace NymVPN.xcworkspace \ | |
-scheme NymVPNDaemon \ | |
-configuration Release \ | |
-destination 'generic/platform=macOS' \ | |
-archivePath "$ARCHIVE_PATH" \ | |
DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \ | |
CODE_SIGN_STYLE=Automatic \ | |
CODE_SIGNING_ALLOWED=YES \ | |
-allowProvisioningUpdates \ | |
clean archive | |
echo "archive_path=$ARCHIVE_PATH" >> "$GITHUB_OUTPUT" | |
- name: Build macOS (PR, unsigned Debug) | |
if: env.RELEASE_TYPE == 'pr' | |
working-directory: nym-vpn-apple | |
env: | |
MACOSX_DEPLOYMENT_TARGET: 13.0 | |
run: | | |
set -euxo pipefail | |
DERIVED_DATA="$PWD/.DerivedData-macOS" | |
xcodebuild \ | |
-workspace NymVPN.xcworkspace \ | |
-scheme NymVPNDaemon \ | |
-configuration Debug \ | |
-destination 'generic/platform=macOS' \ | |
-derivedDataPath "$DERIVED_DATA" \ | |
CODE_SIGNING_ALLOWED=NO \ | |
DEVELOPMENT_TEAM= \ | |
build | |
find "$DERIVED_DATA/Build/Products" -maxdepth 3 -name '*.app' -print || true | |
# # ---------- Artifacts (helpful for QA/Ship) ---------- | |
# - name: Upload artifacts | |
# if: always() | |
# uses: actions/upload-artifact@v4 | |
# with: | |
# name: apple-builds-${{ env.RELEASE_TYPE }}-${{ github.run_id }} | |
# path: | | |
# nym-vpn-apple/build/**/*.xcarchive | |
# nym-vpn-apple/build/**/export-qa/*.ipa | |
# nym-vpn-apple/build/**/export-ship/*.ipa | |
# nym-vpn-apple/.DerivedData*/Build/Products/**/*.app | |
# if-no-files-found: ignore | |
# retention-days: 5 |