Skip to content

fix(build): switch to pkg based installer #92

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 7, 2025
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
7 changes: 5 additions & 2 deletions .env
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Build a release locally using: op run --env-file="./.env" -- make release
APPLE_CERT="op://Apple/Apple DeveloperID PKCS12 base64/notesPlain"
CERT_PASSWORD="op://Apple/DeveloperID p12 password/password"
APPLE_CERT="op://Apple/Apple DeveloperID Application PKCS12 base64/notesPlain"
CERT_PASSWORD="op://Apple/DeveloperID Application p12 password/password"

APPLE_INSTALLER_CERT="op://Apple/Developer ID Installer PKCS12 base64/notesPlain"
INSTALLER_CERT_PASSWORD="op://Apple/DeveloperID Installer Password/password"

APPLE_ID="op://Apple/3apcadvvcojjbpxnd7m5fgh5wm/username"
APPLE_ID_PASSWORD="op://Apple/3apcadvvcojjbpxnd7m5fgh5wm/password"
Expand Down
1 change: 1 addition & 0 deletions .ignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
!.github
!.ignore
3 changes: 2 additions & 1 deletion Coder Desktop/Coder Desktop/NetworkExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ extension CoderVPNService {
logger.debug("saving new tunnel")
do {
try await tm.saveToPreferences()
neState = .disabled
} catch {
logger.error("save tunnel failed: \(error)")
neState = .failed(error.localizedDescription)
}
neState = .disabled
}

func removeNetworkExtension() async throws(VPNServiceError) {
Expand Down Expand Up @@ -105,6 +105,7 @@ extension CoderVPNService {
var tunnels: [NETunnelProviderManager] = []
do {
tunnels = try await NETunnelProviderManager.loadAllFromPreferences()
logger.debug("loaded \(tunnels.count) tunnel(s)")
} catch {
throw .internalError("couldn't load tunnels: \(error)")
}
Expand Down
1 change: 1 addition & 0 deletions Coder Desktop/Coder Desktop/SystemExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ protocol SystemExtensionAsyncRecorder: Sendable {
extension CoderVPNService: SystemExtensionAsyncRecorder {
func recordSystemExtensionState(_ state: SystemExtensionState) async {
sysExtnState = state
logger.info("system extension state: \(state.description)")
if state == .installed {
// system extension was successfully installed, so we don't need the delegate any more
systemExtnDelegate = nil
Expand Down
4 changes: 2 additions & 2 deletions Coder Desktop/Coder Desktop/VPNService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ enum VPNServiceError: Error, Equatable {
case let .internalError(description):
"Internal Error: \(description)"
case let .systemExtensionError(state):
state.description
"SystemExtensionError: \(state.description)"
case let .networkExtensionError(state):
state.description
"NetworkExtensionError: \(state.description)"
}
}

Expand Down
6 changes: 6 additions & 0 deletions Coder Desktop/Coder Desktop/XPCInterface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import VPNLib
}

func connect() {
logger.debug("xpc connect called")
guard xpc == nil else {
logger.debug("xpc already exists")
return
}
let networkExtDict = Bundle.main.object(forInfoDictionaryKey: "NetworkExtension") as? [String: Any]
Expand All @@ -27,17 +29,21 @@ import VPNLib
}
xpc = proxy

logger.debug("connecting to machServiceName: \(machServiceName!)")

xpcConn.exportedObject = self
xpcConn.invalidationHandler = { [logger] in
Task { @MainActor in
logger.error("XPC connection invalidated.")
self.xpc = nil
self.connect()
}
}
xpcConn.interruptionHandler = { [logger] in
Task { @MainActor in
logger.error("XPC connection interrupted.")
self.xpc = nil
self.connect()
}
}
xpcConn.resume()
Expand Down
6 changes: 4 additions & 2 deletions Coder Desktop/VPN/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSSystemExtensionUsageDescription</key>
<string></string>
<key>NSSystemExtensionUsageDescription</key>
<string>Extends the networking capabilities of macOS to connect this Mac to your workspaces.</string>
<key>CFBundleDisplayName</key>
<string>Coder Desktop Network Extension</string>
<key>NetworkExtension</key>
<dict>
<key>NEMachServiceName</key>
Expand Down
14 changes: 10 additions & 4 deletions Coder Desktop/VPN/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ final class XPCListenerDelegate: NSObject, NSXPCListenerDelegate, @unchecked Sen
logger.info("active connection dead")
self?.setActiveConnection(nil)
}
newConnection.interruptionHandler = { [weak self] in
logger.debug("connection interrupted")
self?.setActiveConnection(nil)
}
logger.info("new active connection")
setActiveConnection(newConnection)

Expand All @@ -47,13 +51,15 @@ else {
fatalError("Missing NEMachServiceName in Info.plist")
}

let globalXPCListenerDelegate = XPCListenerDelegate()
let xpcListener = NSXPCListener(machServiceName: serviceName)
xpcListener.delegate = globalXPCListenerDelegate
xpcListener.resume()
logger.debug("listening on machServiceName: \(serviceName)")

autoreleasepool {
NEProvider.startSystemExtensionMode()
}

let globalXPCListenerDelegate = XPCListenerDelegate()
let xpcListener = NSXPCListener(machServiceName: serviceName)
xpcListener.delegate = globalXPCListenerDelegate
xpcListener.resume()

dispatchMain()
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ $(KEYCHAIN_FILE):
echo "$$APPLE_CERT" | base64 -d > $$tempfile; \
security import $$tempfile -P '$(CERT_PASSWORD)' -A -t cert -f pkcs12 -k "$(APP_SIGNING_KEYCHAIN)"; \
rm $$tempfile
@tempfile=$$(mktemp); \
echo "$$APPLE_INSTALLER_CERT" | base64 -d > $$tempfile; \
security import $$tempfile -P '$(INSTALLER_CERT_PASSWORD)' -A -t cert -f pkcs12 -k "$(APP_SIGNING_KEYCHAIN)"; \
rm $$tempfile
security list-keychains -d user -s $$(security list-keychains -d user | tr -d '\"') "$(APP_SIGNING_KEYCHAIN)"

.PHONY: release
Expand All @@ -67,6 +71,7 @@ release: $(KEYCHAIN_FILE) ## Create a release build of Coder Desktop
./scripts/build.sh \
--app-prof-path "$$APP_PROF_PATH" \
--ext-prof-path "$$EXT_PROF_PATH" \
--version $(MARKETING_VERSION) \
--keychain "$(APP_SIGNING_KEYCHAIN)"; \
rm "$$APP_PROF_PATH" "$$EXT_PROF_PATH"

Expand Down
25 changes: 0 additions & 25 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,6 @@
};

formatter = pkgs.nixfmt-rfc-style;

create-dmg = pkgs.buildNpmPackage rec {
pname = "create-dmg";
version = "7.0.0";

src = pkgs.fetchFromGitHub {
owner = "sindresorhus";
repo = pname;
rev = "v${version}";
hash = "sha256-+GxKfhVDmtgEh9NOAzGexgfj1qAb0raC8AmrrnJ2vNA=";
};

npmDepsHash = "sha256-48r9v0sTlHbyH4RjynClfC/QsFAlgMTtXCbleuMSM80=";

# create-dmg author does not want to include a lockfile in their releases,
# thus we need to vendor it in ourselves.
postPatch = ''
cp ${./nix/create-dmg/package-lock.json} package-lock.json
'';

# Plain JS, so nothing to build
dontNpmBuild = true;
dontNpmPrune = true;
};
in
{
inherit formatter;
Expand All @@ -60,7 +36,6 @@
actionlint
clang
coreutils
create-dmg
gh
git
gnumake
Expand Down
Loading
Loading