Skip to content

Commit 9fe515d

Browse files
committed
set up cross-platform shell and working macos binary
wip
1 parent 045d362 commit 9fe515d

39 files changed

Lines changed: 3541 additions & 121 deletions

.env.schema

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# @defaultSensitive=false @defaultRequired=infer
2+
# ---
3+
4+
FOO=foo-val

.github/workflows/binary-release.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,30 @@ jobs:
2424
run: |
2525
echo "$GITHUB_CONTEXT"
2626
27+
# Build and sign the macOS native binary (cache hit if already built in CI)
28+
build-native-macos:
29+
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref_name, 'varlock@')
30+
uses: ./.github/workflows/build-native-macos.yaml
31+
with:
32+
mode: release
33+
version: ${{ github.event_name == 'workflow_dispatch' && inputs.version || github.ref_name }}
34+
artifact-name: native-bin-macos-signed
35+
secrets:
36+
OP_CI_TOKEN: ${{ secrets.OP_CI_TOKEN }}
37+
38+
# Notarize the signed binary for production distribution
39+
notarize-native-macos:
40+
needs: build-native-macos
41+
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref_name, 'varlock@')
42+
uses: ./.github/workflows/notarize-native-macos.yaml
43+
with:
44+
source-artifact-name: native-bin-macos-signed
45+
artifact-name: native-bin-macos-release
46+
secrets:
47+
OP_CI_TOKEN: ${{ secrets.OP_CI_TOKEN }}
48+
2749
release-binaries:
50+
needs: notarize-native-macos
2851
# was using github.ref.tag_name, but it seems that when publishing multiple tags at once, it was behaving weirdly
2952
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref_name, 'varlock@')
3053
runs-on: ubuntu-latest
@@ -63,6 +86,13 @@ jobs:
6386
echo "RELEASE_TAG=varlock@${{ inputs.version }}" >> $GITHUB_ENV
6487
echo "RELEASE_VERSION=${{ inputs.version }}" >> $GITHUB_ENV
6588
89+
# Download the signed macOS native binary
90+
- name: Download macOS native binary
91+
uses: actions/download-artifact@v8
92+
with:
93+
name: native-bin-macos-release
94+
path: packages/varlock/native-bins/darwin/VarlockEnclave.app
95+
6696
- name: build libs
6797
run: bun run build:libs
6898
env:
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
name: Build macOS native binary
2+
3+
# Reusable workflow that compiles, bundles, and Developer ID signs the
4+
# VarlockEnclave Swift binary on a macOS runner.
5+
#
6+
# The Swift .build directory is cached by source hash, so the compile
7+
# step (~minutes) is near-instant on cache hit. The .app bundle wrapping
8+
# (plist, icon, signing) always runs since it varies by mode/version.
9+
#
10+
# Notarization is intentionally NOT included here — it's a separate
11+
# workflow for production releases.
12+
13+
on:
14+
workflow_call:
15+
inputs:
16+
mode:
17+
description: 'Build mode: dev, preview, or release (affects bundle metadata)'
18+
type: string
19+
default: 'preview'
20+
version:
21+
description: 'Bundle version string (e.g. 1.2.3)'
22+
type: string
23+
default: '0.0.0-preview'
24+
artifact-name:
25+
description: 'Name for the uploaded artifact'
26+
type: string
27+
default: 'native-bin-macos'
28+
secrets:
29+
OP_CI_TOKEN:
30+
required: true
31+
32+
jobs:
33+
build:
34+
runs-on: macos-latest
35+
steps:
36+
- uses: actions/checkout@v6
37+
38+
- name: Setup Bun
39+
uses: oven-sh/setup-bun@v2
40+
41+
- name: Cache bun dependencies
42+
uses: actions/cache@v5
43+
with:
44+
path: ~/.bun/install/cache
45+
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
46+
restore-keys: |
47+
bun-${{ runner.os }}-
48+
49+
- name: Install node deps
50+
run: bun install
51+
52+
# Cache the Swift .build directory so compilation is fast on unchanged source
53+
- name: Compute Swift source hash
54+
id: swift-hash
55+
run: |
56+
HASH=$(find packages/encryption-binary-swift/swift -type f | sort | xargs shasum -a 256 | shasum -a 256 | cut -d' ' -f1)
57+
echo "hash=$HASH" >> $GITHUB_OUTPUT
58+
echo "Swift source hash: $HASH"
59+
60+
- name: Cache Swift build artifacts
61+
uses: actions/cache@v5
62+
with:
63+
path: packages/encryption-binary-swift/swift/.build
64+
key: varlock-swift-build-${{ steps.swift-hash.outputs.hash }}
65+
66+
# Build varlock JS so we can use it to resolve secrets from 1Password
67+
- name: Build varlock libs
68+
run: bun run build:libs
69+
70+
# Import signing certificate from 1Password (secrets scoped to the Swift package)
71+
- name: Import signing certificate
72+
working-directory: packages/encryption-binary-swift
73+
run: |
74+
eval "$(bunx varlock load --format shell)"
75+
76+
KEYCHAIN_PATH=$RUNNER_TEMP/signing.keychain-db
77+
KEYCHAIN_PASSWORD=$(openssl rand -base64 24)
78+
79+
echo "$APPLE_CERTIFICATE_BASE64" | base64 --decode > $RUNNER_TEMP/certificate.p12
80+
81+
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
82+
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
83+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
84+
85+
security import $RUNNER_TEMP/certificate.p12 \
86+
-P "$APPLE_CERTIFICATE_PASSWORD" \
87+
-A -t cert -f pkcs12 \
88+
-k "$KEYCHAIN_PATH"
89+
90+
security set-key-partition-list -S apple-tool:,apple:,codesign: \
91+
-s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
92+
93+
security list-keychains -d user -s "$KEYCHAIN_PATH" login.keychain-db
94+
95+
echo "APPLE_SIGNING_IDENTITY=$APPLE_SIGNING_IDENTITY" >> $GITHUB_ENV
96+
env:
97+
OP_CI_TOKEN: ${{ secrets.OP_CI_TOKEN }}
98+
99+
# Compile (cached), bundle with mode-specific metadata, and sign
100+
- name: Build, bundle, and sign
101+
run: |
102+
bun run --filter @varlock/encryption-binary-swift build:swift \
103+
-- --mode ${{ inputs.mode }} --version ${{ inputs.version }} --sign "$APPLE_SIGNING_IDENTITY"
104+
105+
- name: Verify binary
106+
run: |
107+
APP_PATH="packages/varlock/native-bins/darwin/VarlockEnclave.app"
108+
echo "=== App bundle contents ==="
109+
ls -la "$APP_PATH/Contents/MacOS/"
110+
echo "=== Binary architectures ==="
111+
lipo -info "$APP_PATH/Contents/MacOS/varlock-local-encrypt"
112+
echo "=== Code signature ==="
113+
codesign -dvv "$APP_PATH" 2>&1 || true
114+
echo "=== Info.plist ==="
115+
cat "$APP_PATH/Contents/Info.plist"
116+
117+
- name: Upload native binary artifact
118+
uses: actions/upload-artifact@v7
119+
with:
120+
name: ${{ inputs.artifact-name }}
121+
path: packages/varlock/native-bins/darwin/VarlockEnclave.app
122+
retention-days: 7
123+
124+
- name: Cleanup signing keychain
125+
if: always()
126+
run: |
127+
KEYCHAIN_PATH=$RUNNER_TEMP/signing.keychain-db
128+
if [ -f "$KEYCHAIN_PATH" ]; then
129+
security delete-keychain "$KEYCHAIN_PATH" || true
130+
fi
131+
rm -f $RUNNER_TEMP/certificate.p12
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: Notarize macOS native binary
2+
3+
# Reusable workflow that takes an already-signed .app bundle artifact,
4+
# submits it to Apple for notarization, and staples the ticket.
5+
# Requires a macOS runner for xcrun.
6+
7+
on:
8+
workflow_call:
9+
inputs:
10+
source-artifact-name:
11+
description: 'Name of the signed .app artifact to notarize'
12+
type: string
13+
required: true
14+
artifact-name:
15+
description: 'Name for the notarized artifact'
16+
type: string
17+
default: 'native-bin-macos-notarized'
18+
secrets:
19+
OP_CI_TOKEN:
20+
required: true
21+
22+
jobs:
23+
notarize:
24+
runs-on: macos-latest
25+
steps:
26+
- uses: actions/checkout@v6
27+
28+
- name: Setup Bun
29+
uses: oven-sh/setup-bun@v2
30+
31+
- name: Cache bun dependencies
32+
uses: actions/cache@v5
33+
with:
34+
path: ~/.bun/install/cache
35+
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
36+
restore-keys: |
37+
bun-${{ runner.os }}-
38+
39+
- name: Install node deps
40+
run: bun install
41+
42+
- name: Build varlock libs
43+
run: bun run build:libs
44+
45+
- name: Download signed .app bundle
46+
uses: actions/download-artifact@v8
47+
with:
48+
name: ${{ inputs.source-artifact-name }}
49+
path: VarlockEnclave.app
50+
51+
- name: Notarize and staple
52+
working-directory: packages/encryption-binary-swift
53+
run: |
54+
eval "$(bunx varlock load --format shell)"
55+
56+
APP_PATH="$GITHUB_WORKSPACE/VarlockEnclave.app"
57+
58+
# Create a zip for notarization submission
59+
ditto -c -k --keepParent "$APP_PATH" $RUNNER_TEMP/VarlockEnclave.zip
60+
61+
# Submit for notarization and wait
62+
xcrun notarytool submit $RUNNER_TEMP/VarlockEnclave.zip \
63+
--apple-id "$APPLE_ID" \
64+
--password "$APPLE_APP_PASSWORD" \
65+
--team-id "$APPLE_TEAM_ID" \
66+
--wait
67+
68+
# Staple the notarization ticket to the app bundle
69+
xcrun stapler staple "$APP_PATH"
70+
env:
71+
OP_CI_TOKEN: ${{ secrets.OP_CI_TOKEN }}
72+
73+
- name: Verify notarization
74+
run: |
75+
echo "=== Code signature ==="
76+
codesign -dvv VarlockEnclave.app 2>&1 || true
77+
echo "=== Notarization staple ==="
78+
xcrun stapler validate VarlockEnclave.app
79+
80+
- name: Upload notarized artifact
81+
uses: actions/upload-artifact@v7
82+
with:
83+
name: ${{ inputs.artifact-name }}
84+
path: VarlockEnclave.app
85+
retention-days: 7

.github/workflows/release-preview.yaml

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,74 @@ on:
77

88

99
jobs:
10+
# Check if varlock itself has changes that will be published
11+
check-varlock-changed:
12+
runs-on: ubuntu-latest
13+
outputs:
14+
varlock-changed: ${{ steps.check.outputs.varlock-changed }}
15+
steps:
16+
- uses: actions/checkout@v6
17+
with:
18+
fetch-depth: 0
19+
- name: Setup Bun
20+
uses: oven-sh/setup-bun@v2
21+
- name: Cache bun dependencies
22+
uses: actions/cache@v5
23+
with:
24+
path: ~/.bun/install/cache
25+
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
26+
restore-keys: |
27+
bun-${{ runner.os }}-
28+
- name: Install node deps
29+
run: bun install
30+
31+
- name: Check if varlock has changes
32+
id: check
33+
run: |
34+
CURRENT_BRANCH="${GITHUB_HEAD_REF:-$(git branch --show-current)}"
35+
if [[ "$CURRENT_BRANCH" == "changeset-release/main" ]]; then
36+
# On release branch, check if varlock's package.json was modified
37+
if git diff origin/main --name-only | grep -q '^packages/varlock/package.json$'; then
38+
echo "varlock-changed=true" >> $GITHUB_OUTPUT
39+
else
40+
echo "varlock-changed=false" >> $GITHUB_OUTPUT
41+
fi
42+
else
43+
# Normal PR — check changesets
44+
bunx changeset status --output=changesets-summary.json 2>/dev/null || true
45+
if [ -f changesets-summary.json ]; then
46+
if jq -e '.releases[] | select(.name == "varlock" and .newVersion != .oldVersion)' changesets-summary.json > /dev/null 2>&1; then
47+
echo "varlock-changed=true" >> $GITHUB_OUTPUT
48+
else
49+
echo "varlock-changed=false" >> $GITHUB_OUTPUT
50+
fi
51+
rm -f changesets-summary.json
52+
else
53+
echo "varlock-changed=false" >> $GITHUB_OUTPUT
54+
fi
55+
fi
56+
echo "varlock-changed=$(cat $GITHUB_OUTPUT | grep varlock-changed | cut -d= -f2)"
57+
58+
# Build + sign native binary only if varlock is being published
59+
# (no notarization for preview — just signed)
60+
build-native-macos:
61+
needs: check-varlock-changed
62+
if: needs.check-varlock-changed.outputs.varlock-changed == 'true'
63+
uses: ./.github/workflows/build-native-macos.yaml
64+
with:
65+
artifact-name: native-bin-macos-preview
66+
secrets:
67+
OP_CI_TOKEN: ${{ secrets.OP_CI_TOKEN }}
68+
1069
build:
70+
needs: [check-varlock-changed, build-native-macos]
71+
# Run even if build-native-macos was skipped (varlock not changed)
72+
if: always() && !failure() && !cancelled()
1173
runs-on: ubuntu-latest
1274

1375
steps:
1476
- uses: actions/checkout@v6
1577
with:
16-
# by default only the current commit is fetched
17-
# but we need more history to be able to compare to main
18-
# TODO: ideally we would just fetch the history between origin/main and the current commit
1978
fetch-depth: 0
2079
- name: Setup Bun
2180
uses: oven-sh/setup-bun@v2
@@ -35,6 +94,14 @@ jobs:
3594
- name: Enable turborepo build cache
3695
uses: rharkor/caching-for-turbo@v2.3.11
3796

97+
# Download signed macOS native binary if it was built
98+
- name: Download macOS native binary
99+
if: needs.check-varlock-changed.outputs.varlock-changed == 'true'
100+
uses: actions/download-artifact@v8
101+
with:
102+
name: native-bin-macos-preview
103+
path: packages/varlock/native-bins/darwin/VarlockEnclave.app
104+
38105
# ------------------------------------------------------------
39106
- name: Build publishable npm packages
40107
run: bun run build:libs

0 commit comments

Comments
 (0)