Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 17 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,24 @@ jobs:
# adds /opt/homebrew/bin to PATH, which is where brew installs go. The shared
# required jobs and the signed macOS build all link WireGuardKitGo.
brew-packages: go
# Import the Apple Distribution certificate into the runner keychain and hand
# its SHA-1 to swift-mk as CODE_SIGN_IDENTITY. swift-mk builds the signing
# xcconfig (the identity + Manual style + team) and exports XCODE_XCCONFIG_FILE
# so it wins over every target. The macOS agent and tunnel provider use the
# app-extension NetworkExtension entitlement (packet-tunnel-provider), which
# Developer ID cannot authorize on macOS; App Store distribution profiles do,
# and they enumerate no devices, so the build signs on an unregistered runner.
# Sign every product in one Verify job. SWIFT_VERIFY_BUILD_CMD (`build all`)
# builds the Mac agent and tunnel, the Catalyst app, the iPhone simulator app,
# the iPhone device app, and the daemon. These targets carry App Groups and
# Network Extension entitlements, so each needs a provisioning profile. The CI
# runner is not a registered device, so development provisioning cannot work;
# only App Store distribution profiles, which carry no device list, sign there.
#
# import-signing-cert imports the Apple Distribution certificate that manual
# signing uses. The ci-provision setup step runs fastlane before the build to
# create or renew one App Store profile per target through the App Store Connect
# API key (APPLE_NOTARY_*), so profiles never expire out from under CI;
# Project.swift pins each profile by name. TUIST_DEVELOPER_ID_SIGNING selects the
# project's distribution signing mode. install-provisioning-profile is not set,
# because fastlane provisions instead. SWIFT_MK_VERIFY_SIGNING_ROOTS verifies each
# runnable product is signed with the team and is not ad-hoc.
import-signing-cert: true
signing-identity-name: "Apple Distribution: Alex Goodkind (H3BMXM4W7H)"
apple-team-id: H3BMXM4W7H
# The agent and tunnel-provider targets carry App Groups + Network Extensions
# entitlements, so each needs its own provisioning profile. Two Mac App Store
# provisioning profiles are installed from the newline-separated
# APPLE_DEVELOPER_ID_PROFILE_BASE64 secret; Project.swift maps each NE target to
# its profile by name when the engine signals provisioning (a non-empty
# PROVISIONING_PROFILE_SPECIFIER), so local builds that install no profile are
# unaffected.
install-provisioning-profile: true
# Signed Build job runs `make build`, which SWIFT_BUILD_CMD wires to
# CellTunnelDev `build all` (Apple Distribution on the Mac products). Do not
# set CODE_SIGN_IDENTITY or CODE_SIGN_STYLE in make-args: that would beat
# swift-mk's signing override and force failing development signing.
setup-target: ci-provision
make-args: TUIST_DEVELOPER_ID_SIGNING=1
secrets: inherit
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,12 @@ Sources/CellTunnelCore/Generated/
*.xcworkspace/
xcuserdata/
.config/mise/conf.d/swift-mk.toml

# Ruby / fastlane
/vendor/
/.bundle/
/fastlane/report.xml
# fastlane downloads a copy of each provisioning profile into the working dir; the
# authoritative copy is installed into Xcode's profiles folder.
/AppStore_*.mobileprovision
/AppStore_*.provisionprofile
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Targets reference the xcconfig values rather than literal identifiers. A make ta

## Build and install

`README.md` is the user-facing build, install, and run quickstart, and `make help` lists every target. Prefer a named platform target (`make build-mac`, `make build-iphone`, and the rest) when you need one product. `make build` and `make build-all` compile every platform for the engine and CI path. The `install` targets deploy a prebuilt bundle, so build the target first. `make install-mac` copies the agent app to `/Applications/CellTunnel/CellTunnelAgent.app`, then always restarts the launchd service so the freshly built binary is the one running.
`README.md` is the user-facing build, install, and run quickstart, and `make help` lists every target. Use the named build targets (`make build-mac`, `make build-iphone`, and the rest) for normal platform builds. `make build` and `make build-all` compile every platform. CI builds every platform in one Verify job, signs each product, and verifies each runnable product's signature. The `install` targets deploy a prebuilt bundle, so build the target first. `make install-mac` copies the agent app to `/Applications/CellTunnel/CellTunnelAgent.app`, then always restarts the launchd service so the freshly built binary is the one running.

`Products/celltunnelctl` is built alongside the daemon target and is the agent control client; run `celltunnelctl --help` for the current command set. The agent owns one config library, exposed both there (`celltunnelctl configs`) and in the Mac Catalyst app. The library model (UUID identity, profile stamping, and the non-mutating boot assertion) lives in `docs/architecture.md` under "Configuration and routes".

Expand Down
7 changes: 7 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
source "https://rubygems.org"

# fastlane provisions the App Store distribution profiles CI signs with. The CI
# runner and unregistered machines cannot use development provisioning (it requires
# a registered device), so `fastlane sigh` creates and renews device-less App Store
# profiles for each target through the App Store Connect API key. See fastlane/Fastfile.
gem "fastlane"
245 changes: 245 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.8)
abbrev (0.1.2)
addressable (2.9.0)
public_suffix (>= 2.0.2, < 8.0)
artifactory (3.0.17)
atomos (0.1.3)
aws-eventstream (1.4.0)
aws-partitions (1.1273.0)
aws-sdk-core (3.254.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
base64
bigdecimal
jmespath (~> 1, >= 1.6.1)
logger
aws-sdk-kms (1.130.0)
aws-sdk-core (~> 3, >= 3.254.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.228.1)
aws-sdk-core (~> 3, >= 3.254.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.12.1)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
base64 (0.3.0)
benchmark (0.5.0)
bigdecimal (4.1.2)
claide (1.1.0)
colored (1.2)
colored2 (3.1.2)
commander (4.6.0)
highline (~> 2.0.0)
csv (3.3.5)
declarative (0.0.20)
digest-crc (0.7.0)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.6.20240107)
dotenv (2.8.1)
emoji_regex (3.2.3)
excon (1.6.0)
logger
faraday (1.10.6)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0)
faraday-multipart (~> 1.0)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.0)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
faraday-retry (~> 1.0)
ruby2_keywords (>= 0.0.4)
faraday-cookie_jar (0.0.8)
faraday (>= 0.8.0)
http-cookie (>= 1.0.0)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.1)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.2.0)
multipart-post (~> 2.0)
faraday-net_http (1.0.2)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.4)
faraday_middleware (1.2.1)
faraday (~> 1.0)
fastimage (2.4.1)
fastlane (2.237.0)
CFPropertyList (>= 2.3, < 5.0.0)
abbrev (~> 0.1)
addressable (>= 2.9.0, < 3.0.0)
artifactory (~> 3.0)
aws-sdk-s3 (~> 1.197)
babosa (>= 1.0.3, < 2.0.0)
base64 (~> 0.2)
benchmark (>= 0.1.0)
bundler (>= 2.4.0, < 5.0.0)
colored (~> 1.2)
commander (~> 4.6)
csv (~> 3.3)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 4.0)
excon (>= 0.71.0, < 2.0.0)
faraday (~> 1.0)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 1.0)
fastimage (>= 2.1.0, < 3.0.0)
fastlane-sirp (>= 1.1.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-apis-androidpublisher_v3 (~> 0.3)
google-apis-playcustomapp_v1 (~> 0.1)
google-cloud-env (>= 1.6.0, < 2.3.0)
google-cloud-storage (~> 1.31)
highline (~> 2.0)
http-cookie (~> 1.0.5)
json (< 3.0.0)
jwt (>= 2.10.3, < 4)
logger (>= 1.6, < 2.0)
mini_magick (>= 4.9.4, < 5.0.0)
multi_json (~> 1.12)
multipart-post (>= 2.0.0, < 3.0.0)
mutex_m (~> 0.3)
naturally (~> 2.2)
nkf (~> 0.2)
optparse (>= 0.1.1, < 1.0.0)
ostruct (>= 0.1.0)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.5)
simctl (~> 1.6.3)
terminal-notifier (>= 2.0.0, < 3.0.0)
terminal-table (~> 3)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.4.1)
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
fastlane-sirp (1.1.0)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.105.0)
google-apis-core (>= 0.15.0, < 2.a)
google-apis-core (0.18.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (~> 1.9)
httpclient (>= 2.8.3, < 3.a)
mini_mime (~> 1.0)
mutex_m
representable (~> 3.0)
retriable (>= 2.0, < 4.a)
google-apis-iamcredentials_v1 (0.28.0)
google-apis-core (>= 0.15.0, < 2.a)
google-apis-playcustomapp_v1 (0.18.0)
google-apis-core (>= 0.15.0, < 2.a)
google-apis-storage_v1 (0.65.0)
google-apis-core (>= 0.15.0, < 2.a)
google-cloud-core (1.9.0)
google-cloud-env (>= 1.0, < 3.a)
google-cloud-errors (~> 1.0)
google-cloud-env (2.2.2)
base64 (~> 0.2)
faraday (>= 1.0, < 3.a)
google-cloud-errors (1.7.0)
google-cloud-storage (1.62.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-core (>= 0.18, < 2)
google-apis-iamcredentials_v1 (~> 0.18)
google-apis-storage_v1 (>= 0.42)
google-cloud-core (~> 1.6)
googleauth (~> 1.9)
mini_mime (~> 1.0)
google-logging-utils (0.2.0)
googleauth (1.17.2)
faraday (>= 1.0, < 3.a)
google-cloud-env (~> 2.2)
google-logging-utils (~> 0.1)
jwt (>= 1.4, < 4.0)
os (>= 0.9, < 2.0)
pstore (~> 0.1)
signet (>= 0.16, < 2.a)
highline (2.0.3)
http-cookie (1.0.8)
domain_name (~> 0.5)
httpclient (2.9.0)
mutex_m
jmespath (1.6.2)
json (2.21.1)
jwt (3.2.0)
base64
logger (1.7.0)
mini_magick (4.13.2)
mini_mime (1.1.5)
multi_json (1.21.1)
multipart-post (2.4.1)
mutex_m (0.3.0)
nanaimo (0.4.0)
naturally (2.3.0)
nkf (0.3.0)
optparse (0.8.1)
os (1.1.4)
ostruct (0.6.3)
plist (3.7.2)
pstore (0.2.1)
public_suffix (7.0.5)
rake (13.4.2)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.8.0)
rexml (3.4.4)
rouge (3.28.0)
ruby2_keywords (0.0.5)
rubyzip (2.4.1)
security (0.1.5)
signet (0.22.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 4.0)
simctl (1.6.10)
CFPropertyList
naturally
terminal-notifier (2.0.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
trailblazer-option (0.1.2)
tty-cursor (0.7.1)
tty-screen (0.8.2)
tty-spinner (0.9.3)
tty-cursor (~> 0.7)
uber (0.1.0)
unicode-display_width (2.6.0)
word_wrap (1.0.0)
xcodeproj (1.28.1)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
base64
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.4.0)
nkf
rexml (>= 3.3.6, < 4.0)
xcpretty (0.4.1)
rouge (~> 3.28.0)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)

PLATFORMS
arm64-darwin-25
ruby

DEPENDENCIES
fastlane

BUNDLED WITH
2.7.2
26 changes: 25 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ XCCONFIG_EXPORTED_VARS := \
# exports that command into child environments.
SWIFT_NAMED_RUN_HINT := use make run-catalyst|run-iphone|run-iphone-sim
SWIFT_BUILD_CMD ?= $(CELL_TUNNEL_DEV) build all $(CONFIG)
SWIFT_VERIFY_BUILD_CMD ?= $(CELL_TUNNEL_DEV) build all $(CONFIG)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
SWIFT_TEST_CMD ?= $(CELL_TUNNEL_DEV) test
SWIFT_RUN_CMD ?= printf 'run: use a named target (%s)\n' '$(SWIFT_NAMED_RUN_HINT)'; exit 1
# The dev tool's `generate` installs Tuist dependencies and renders the project; it is
Expand Down Expand Up @@ -70,6 +71,19 @@ ifneq ($(strip $(PROVISIONING_PROFILE_SPECIFIER)),)
export TUIST_DEVELOPER_ID_SIGNING := 1
endif

# The Verify gate builds every platform through SWIFT_VERIFY_BUILD_CMD and verifies
# the actual signed output. SWIFT_MK_VERIFY_SIGNING_ROOTS makes the engine discover
# every runnable .app the build dropped under Products and check each one's signature,
# so the Mac agent, the Catalyst app, and the iPhone device app are all confirmed
# signed with the team and not ad-hoc, without listing paths. The engine skips the
# iPhone simulator app, which is ad-hoc by design.
#
# The pre-build settings check (SWIFT_MK_VERIFY_WORKSPACE/SCHEME) is intentionally
# unset: under automatic App Store Connect API-key signing the identity resolves at
# build time, so static xcodebuild -showBuildSettings reports CODE_SIGN_IDENTITY = -
# for targets that Xcode signs at build time. The signed identity is knowable only
# after the build, which the products check inspects directly.
SWIFT_MK_VERIFY_SIGNING_ROOTS := Products
SWIFT_SOURCE_ROOTS := Apps Sources Tests Tools/CellTunnelCtl Tools/CellTunnelDev
SWIFT_OWNED_SWIFT_FILES := $(shell find $(SWIFT_SOURCE_ROOTS) -path '*/.build/*' -prune -o -name '*.swift' -print)
SWIFT_PACKAGE_MANIFESTS := Package.swift Project.swift Tuist.swift Tuist/Package.swift Tools/Package.swift Tools/cell-tunnel-dev.swift
Expand All @@ -87,12 +101,22 @@ include bootstrap.mk

.DEFAULT_GOAL := check

.PHONY: format iphone-install install-mac smoke logs \
.PHONY: format iphone-install install-mac smoke logs ci-provision \
build-all build-mac build-catalyst build-iphone build-iphone-sim build-daemon \
run-catalyst run-iphone run-iphone-sim \
relay-up relay-reload relay-status relay-down \
mac-logs iphone-logs

# CI signing provisioning. CI and unregistered machines cannot use development
# provisioning (it requires a registered device), so this creates or renews one App
# Store distribution profile per target with the App Store Connect API key and installs
# it, for a manual-signed build. The engine runs this as the Verify job's setup step,
# before the build, with APPLE_NOTARY_* in the environment. See fastlane/Fastfile.
ci-provision:
@command -v bundle >/dev/null 2>&1 || gem install bundler --no-document
@bundle install --quiet
@bundle exec fastlane ios ci_provision

help::
@printf '\n%s\n' 'Cell Tunnel:'
@printf ' %-40s %s\n' 'build-all' 'build every platform (same as make build)'
Expand Down
Loading
Loading