Skip to content

Commit e3287b2

Browse files
committed
chore(ci): build for distribution
1 parent caf84f1 commit e3287b2

File tree

17 files changed

+9930
-79
lines changed

17 files changed

+9930
-79
lines changed

.env

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Build a release locally using: op run --env-file="./.env" -- make release
2+
APPLE_CERT="op://Apple/Apple DeveloperID PKCS12 base64/notesPlain"
3+
CERT_PASSWORD="op://Apple/DeveloperID p12 password/password"
4+
5+
APPLE_ID="op://Apple/3apcadvvcojjbpxnd7m5fgh5wm/username"
6+
APPLE_ID_PASSWORD="op://Apple/3apcadvvcojjbpxnd7m5fgh5wm/password"
7+
8+
APP_PROF="op://Apple/Provisioning Profiles/profiles/application_base64"
9+
EXT_PROF="op://Apple/Provisioning Profiles/profiles/extension_base64"

.github/actions/nix-devshell/action.yaml

-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,5 @@ runs:
66
- name: Setup Nix
77
uses: DeterminateSystems/nix-installer-action@e50d5f73bfe71c2dd0aa4218de8f4afa59f8f81d # v16
88

9-
- name: Setup GHA Nix cache
10-
uses: DeterminateSystems/magic-nix-cache-action@6221693898146dc97e38ad0e013488a16477a4c4 # v9
11-
129
- name: Enter devshell
1310
uses: nicknovitski/nix-develop@9be7cfb4b10451d3390a75dc18ad0465bed4932a # v1.2.1

.github/dependabot.yaml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
time: "06:00"
8+
timezone: "America/Chicago"
9+
labels: []
10+
commit-message:
11+
prefix: "ci"
12+
groups:
13+
github-actions:
14+
patterns:
15+
- "*"

.github/workflows/ci.yml

+3-15
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,11 @@ jobs:
1818
name: test
1919
runs-on: ${{ github.repository_owner == 'coder' && 'depot-macos-latest' || 'macos-latest'}}
2020
steps:
21-
- name: Harden Runner
22-
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
23-
with:
24-
egress-policy: audit
25-
2621
- name: Checkout
2722
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
2823
with:
2924
fetch-depth: 1
25+
persist-credentials: false
3026

3127
- name: Switch XCode Version
3228
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
@@ -44,15 +40,11 @@ jobs:
4440
name: fmt
4541
runs-on: ${{ github.repository_owner == 'coder' && 'depot-macos-latest' || 'macos-latest'}}
4642
steps:
47-
- name: Harden Runner
48-
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
49-
with:
50-
egress-policy: audit
51-
5243
- name: Checkout
5344
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
5445
with:
5546
fetch-depth: 1
47+
persist-credentials: false
5648

5749
- name: Switch XCode Version
5850
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
@@ -70,15 +62,11 @@ jobs:
7062
name: lint
7163
runs-on: ${{ github.repository_owner == 'coder' && 'depot-macos-latest' || 'macos-latest'}}
7264
steps:
73-
- name: Harden Runner
74-
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
75-
with:
76-
egress-policy: audit
77-
7865
- name: Checkout
7966
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
8067
with:
8168
fetch-depth: 1
69+
persist-credentials: false
8270

8371
- name: Setup Nix
8472
uses: ./.github/actions/nix-devshell

.github/workflows/release.yml

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: release
2+
3+
on:
4+
# TODO: Switch to on `v*` tag push
5+
pull_request:
6+
7+
permissions: {}
8+
9+
jobs:
10+
build:
11+
runs-on: ${{ github.repository_owner == 'coder' && 'depot-macos-latest' || 'macos-latest'}}
12+
if: ${{ github.repository_owner == 'coder' }}
13+
permissions:
14+
# To upload assets to the release
15+
contents: write
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
19+
with:
20+
fetch-depth: 1
21+
persist-credentials: false
22+
23+
- name: Switch XCode Version
24+
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
25+
with:
26+
xcode-version: "16.0.0"
27+
28+
- name: Setup Nix
29+
uses: ./.github/actions/nix-devshell
30+
31+
- name: Build
32+
env:
33+
APPLE_CERT: ${{ secrets.APPLE_DEVELOPER_ID_PKCS12_B64 }}
34+
APPLE_ID: ${{ secrets.APPLE_NOTARYTOOL_USERNAME }}
35+
APPLE_ID_PASSWORD: ${{ secrets.APPLE_NOTARYTOOL_PASSWORD }}
36+
APP_PROF: ${{ secrets.CODER_DESKTOP_APP_PROVISIONPROFILE_B64 }}
37+
CERT_PASSWORD: ${{ secrets.APPLE_DEVELOPER_ID_PKCS12_PASSWORD }}
38+
EXT_PROF: ${{ secrets.CODER_DESKTOP_EXTENSION_PROVISIONPROFILE_B64 }}
39+
run: make release
40+
41+
- name: Upload Build Artifacts
42+
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
43+
with:
44+
name: app
45+
path: |
46+
./build
47+
retention-days: 7

.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -295,3 +295,10 @@ xcuserdata
295295
buildServer.json
296296

297297
# End of https://www.toptal.com/developers/gitignore/api/xcode,jetbrains,macos,direnv,swift,swiftpm,objective-c
298+
299+
*.entitlements
300+
301+
app/
302+
303+
# Make marker file
304+
app-signing.keychain-db

Coder Desktop/Coder Desktop/Coder_Desktop.entitlements

-16
This file was deleted.

Coder Desktop/Coder Desktop/Views/LoginForm.swift

+6-4
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,9 @@ enum LoginField: Hashable {
194194
case sessionToken
195195
}
196196

197-
#Preview {
198-
LoginForm<PreviewSession>()
199-
.environmentObject(PreviewSession())
200-
}
197+
#if DEBUG
198+
#Preview {
199+
LoginForm<PreviewSession>()
200+
.environmentObject(PreviewSession())
201+
}
202+
#endif

Coder Desktop/Coder Desktop/Views/Settings/NetworkTab.swift

+5-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ struct NetworkTab<VPN: VPNService>: View {
99
}
1010
}
1111

12-
#Preview {
13-
NetworkTab<PreviewVPN>()
14-
}
12+
#if DEBUG
13+
#Preview {
14+
NetworkTab<PreviewVPN>()
15+
}
16+
#endif

Coder Desktop/Coder Desktop/Views/VPNMenu.swift

+7-5
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,10 @@ func openSystemExtensionSettings() {
9898
NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.ExtensionsPreferences?extensionPointIdentifier=com.apple.system_extension.network_extension.extension-point")!)
9999
}
100100

101-
#Preview {
102-
VPNMenu<PreviewVPN, PreviewSession>().frame(width: 256)
103-
.environmentObject(PreviewVPN())
104-
.environmentObject(PreviewSession())
105-
}
101+
#if DEBUG
102+
#Preview {
103+
VPNMenu<PreviewVPN, PreviewSession>().frame(width: 256)
104+
.environmentObject(PreviewVPN())
105+
.environmentObject(PreviewSession())
106+
}
107+
#endif

Coder Desktop/VPN/Manager.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,13 @@ actor Manager {
4848
}
4949

5050
// HACK: The downloaded dylib may be quarantined, but we've validated it's signature
51-
// so it's safe to execute. However, this SE must be sandboxed, so we defer to the app.
51+
// so it's safe to execute. However, the SE must be sandboxed, so we defer to the app.
5252
try await removeQuarantine(dest)
5353

5454
do {
5555
try tunnelHandle = TunnelHandle(dylibPath: dest)
5656
} catch {
57+
logger.error("couldn't open dylib \(error, privacy: .public)")
5758
throw .tunnelSetup(error)
5859
}
5960
speaker = await Speaker<Vpn_ManagerMessage, Vpn_TunnelMessage>(

Coder Desktop/VPN/VPN.entitlements

-20
This file was deleted.

Coder Desktop/project.yml

+12-5
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,15 @@ targets:
114114
path: Coder Desktop/Coder_Desktop.entitlements
115115
properties:
116116
com.apple.developer.networking.networkextension:
117-
- packet-tunnel-provider
117+
- packet-tunnel-provider${PTP_SUFFIX}
118118
com.apple.developer.system-extension.install: true
119119
com.apple.security.application-groups:
120120
- $(TeamIdentifierPrefix)com.coder.Coder-Desktop
121121
settings:
122122
base:
123123
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon # Sets the app icon to "AppIcon".
124124
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME: AccentColor
125+
# `CODE_SIGN_*` options are overriden during a release build
125126
CODE_SIGN_IDENTITY: "Apple Development"
126127
CODE_SIGN_STYLE: Automatic
127128
COMBINE_HIDPI_IMAGES: YES
@@ -132,6 +133,8 @@ targets:
132133
INFOPLIST_KEY_NSHumanReadableCopyright: ""
133134
SWIFT_EMIT_LOC_STRINGS: YES
134135
PRODUCT_BUNDLE_IDENTIFIER: "com.coder.Coder-Desktop"
136+
# Empty outside of release builds
137+
PROVISIONING_PROFILE_SPECIFIER: ${APP_PROVISIONING_PROFILE_ID}
135138

136139
# (ThomasK33): Install the application into the /Applications folder
137140
# so that macOS stops complaining about the app being run from an
@@ -197,7 +200,8 @@ targets:
197200
path: VPN/VPN.entitlements
198201
properties:
199202
com.apple.developer.networking.networkextension:
200-
- packet-tunnel-provider
203+
# PTP_SUFFIX is populated at `xcodegen` time.
204+
- packet-tunnel-provider${PTP_SUFFIX}
201205
com.apple.security.app-sandbox: true
202206
com.apple.security.application-groups:
203207
- $(TeamIdentifierPrefix)com.coder.Coder-Desktop
@@ -212,6 +216,11 @@ targets:
212216
PRODUCT_NAME: "$(PRODUCT_BUNDLE_IDENTIFIER)"
213217
SWIFT_EMIT_LOC_STRINGS: YES
214218
SWIFT_OBJC_BRIDGING_HEADER: "VPN/com_coder_Coder_Desktop_VPN-Bridging-Header.h"
219+
# `CODE_SIGN_*` are overriden during a release build
220+
CODE_SIGN_IDENTITY: "Apple Development"
221+
CODE_SIGN_STYLE: Automatic
222+
# Empty outside of release builds
223+
PROVISIONING_PROFILE_SPECIFIER: ${EXT_PROVISIONING_PROFILE_ID}
215224
dependencies:
216225
- target: VPNLib
217226
embed: true
@@ -232,8 +241,6 @@ targets:
232241
DYLIB_COMPATIBILITY_VERSION: 1
233242
DYLIB_CURRENT_VERSION: 1
234243
DYLIB_INSTALL_NAME_BASE: "@rpath"
235-
CODE_SIGN_IDENTITY: "Apple Development"
236-
CODE_SIGN_STYLE: Automatic
237244
LD_RUNPATH_SEARCH_PATHS:
238245
- "@executable_path/../Frameworks"
239246
- "@loader_path/Frameworks"
@@ -294,4 +301,4 @@ targets:
294301
settings:
295302
base:
296303
TEST_HOST: "$(BUILT_PRODUCTS_DIR)/Coder Desktop.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Coder Desktop"
297-
PRODUCT_BUNDLE_IDENTIFIER: com.coder.Coder-Desktop.CoderSDKTests
304+
PRODUCT_BUNDLE_IDENTIFIER: com.coder.Coder-Desktop.CoderSDKTests

Makefile

+59-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ PROJECT := Coder\ Desktop
1010
XCPROJECT := Coder\ Desktop/Coder\ Desktop.xcodeproj
1111
SCHEME := Coder\ Desktop
1212
SWIFT_VERSION := 6.0
13+
APP_SIGNING_KEYCHAIN := /tmp/app-signing.keychain-db
1314

1415
.PHONY: setup
1516
setup: \
@@ -18,11 +19,37 @@ setup: \
1819

1920
$(XCPROJECT): $(PROJECT)/project.yml
2021
cd $(PROJECT); \
21-
SWIFT_VERSION=$(SWIFT_VERSION) xcodegen
22+
SWIFT_VERSION=$(SWIFT_VERSION) \
23+
PTP_SUFFIX=${PTP_SUFFIX} \
24+
APP_PROVISIONING_PROFILE_ID=${APP_PROVISIONING_PROFILE_ID} \
25+
EXT_PROVISIONING_PROFILE_ID=${EXT_PROVISIONING_PROFILE_ID} \
26+
xcodegen
2227

2328
$(PROJECT)/VPNLib/vpn.pb.swift: $(PROJECT)/VPNLib/vpn.proto
2429
protoc --swift_opt=Visibility=public --swift_out=. 'Coder Desktop/VPNLib/vpn.proto'
2530

31+
$(APP_SIGNING_KEYCHAIN):
32+
security create-keychain -p "" "$(APP_SIGNING_KEYCHAIN)"
33+
security set-keychain-settings -lut 21600 "$(APP_SIGNING_KEYCHAIN)"
34+
security unlock-keychain -p "" "$(APP_SIGNING_KEYCHAIN)"
35+
@tempfile=$$(mktemp); \
36+
echo "$$APPLE_CERT" | base64 -d > $$tempfile; \
37+
security import $$tempfile -P '$(CERT_PASSWORD)' -A -t cert -f pkcs12 -k "$(APP_SIGNING_KEYCHAIN)"; \
38+
rm $$tempfile
39+
security list-keychains -d user -s $$(security list-keychains -d user | tr -d '\"') "$(APP_SIGNING_KEYCHAIN)"
40+
41+
.PHONY: release
42+
release: $(APP_SIGNING_KEYCHAIN) ## Create a release build of Coder Desktop
43+
@APP_PROF_PATH="$$(mktemp)"; \
44+
EXT_PROF_PATH="$$(mktemp)"; \
45+
echo -n "$$APP_PROF" | base64 -d > "$$APP_PROF_PATH"; \
46+
echo -n "$$EXT_PROF" | base64 -d > "$$EXT_PROF_PATH"; \
47+
./scripts/build.sh \
48+
--app-prof-path "$$APP_PROF_PATH" \
49+
--ext-prof-path "$$EXT_PROF_PATH" \
50+
--keychain "$(APP_SIGNING_KEYCHAIN)"; \
51+
rm "$$APP_PROF_PATH" "$$EXT_PROF_PATH"
52+
2653
.PHONY: fmt
2754
fmt: ## Run Swift file formatter
2855
swiftformat \
@@ -40,16 +67,42 @@ test: $(XCPROJECT) ## Run all tests
4067
CODE_SIGNING_ALLOWED=NO | xcbeautify
4168

4269
.PHONY: lint
43-
lint: ## Lint swift files
70+
lint: lint/swift lint/actions ## Lint all files in the repo
71+
72+
.PHONY: lint/swift
73+
lint/swift: ## Lint Swift files
4474
swiftlint \
4575
--strict \
4676
--quiet $(LINTFLAGS)
4777

78+
.PHONY: lint/actions
79+
lint/actions: ## Lint GitHub Actions
80+
actionlint
81+
zizmor .
82+
4883
.PHONY: clean
49-
clean: ## Clean Xcode project
50-
xcodebuild clean \
51-
-project $(XCPROJECT)
52-
rm -rf $(XCPROJECT)
84+
clean: clean/project clean/keychain clean/build ## Clean project and artifacts
85+
86+
.PHONY: clean/project
87+
clean/project:
88+
@if [ -d $(XCPROJECT) ]; then \
89+
echo "Cleaning project: '$(XCPROJECT)'"; \
90+
xcodebuild clean -project $(XCPROJECT); \
91+
rm -rf $(XCPROJECT); \
92+
fi
93+
find . -name "*.entitlements" -type f -delete
94+
95+
.PHONY: clean/keychain
96+
clean/keychain:
97+
@if [ -e "$(APP_SIGNING_KEYCHAIN)" ]; then \
98+
echo "Cleaning keychain: '$(APP_SIGNING_KEYCHAIN)'"; \
99+
security delete-keychain "$(APP_SIGNING_KEYCHAIN)"; \
100+
rm -f "$(APP_SIGNING_KEYCHAIN)"; \
101+
fi
102+
103+
.PHONY: clean/build
104+
clean/build:
105+
rm -rf build/ app/
53106

54107
.PHONY: proto
55108
proto: $(PROJECT)/VPNLib/vpn.pb.swift ## Generate Swift files from protobufs

0 commit comments

Comments
 (0)