@hasna/recordings 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/helpers/installer-guard-execution.d.ts.map +1 -1
- package/dist/cli/index.js +18 -5
- package/dist/http/client.d.ts +9 -0
- package/dist/http/client.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/mcp/index.js +2 -2
- package/dist/server/index.js +2 -2
- package/dist/storage.js +2 -2
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/scripts/install_macos_app.sh +54 -7
- package/scripts/macos_artifact.ts +118 -10
- package/scripts/smoke_macos_app.sh +62 -16
- package/src/native/Recordings/App/MenuBarStatusView.swift +9 -4
- package/src/native/Recordings/App/RecordingsApp.swift +37 -1
- package/src/native/Recordings/RecordingsLib/Info.plist +2 -2
- package/src/native/Recordings/RecordingsLib/PermissionRequestLaunchPlan.swift +21 -1
- package/src/native/Recordings/RecordingsTests/BarOnlyLaunchPlanTests.swift +99 -0
- package/src/native/Recordings/build.sh +152 -12
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Testing
|
|
3
|
+
@testable import RecordingsLib
|
|
4
|
+
|
|
5
|
+
/// Regression coverage for the bar-only successor lane (task 4ee4ebbf-9a10-4181-8e43-9307d56e684b).
|
|
6
|
+
///
|
|
7
|
+
/// These lock the launch-plan control flow behind the terminated hasna/apps#269 lineage's P1
|
|
8
|
+
/// classes:
|
|
9
|
+
///
|
|
10
|
+
/// - Cycle-1 P1: real launches of the installed bar never passed `--bar-only`, so the bar
|
|
11
|
+
/// binary was behaviorally identical to the full app. Fixed by making bar builds bar-only by
|
|
12
|
+
/// construction (`#if RECORDINGS_BAR_ONLY` compile-time default); the argument is now only a
|
|
13
|
+
/// self-describing launch record.
|
|
14
|
+
/// - Cycle-2 P1: the windowless branch keyed on `declaresMainWindow`, which excludes EVERY
|
|
15
|
+
/// runtime smoke, so the FULL build's smoke failed deterministically. Fixed by splitting the
|
|
16
|
+
/// conditions: `declaresWindow` (window creation may happen) excludes only the helper and bar
|
|
17
|
+
/// launches, while `declaresMainWindow` (auto-open / reopen) additionally excludes runtime
|
|
18
|
+
/// smoke so the smoke controls window creation deterministically.
|
|
19
|
+
struct BarOnlyLaunchPlanTests {
|
|
20
|
+
@Test("a bare launch follows the build variant")
|
|
21
|
+
func bareLaunchFollowsBuildVariant() {
|
|
22
|
+
let plan = PermissionRequestLaunchPlan(arguments: [])
|
|
23
|
+
#if RECORDINGS_BAR_ONLY
|
|
24
|
+
#expect(plan.isBarOnly, "a bar build must be bar-only by construction on a bare launch")
|
|
25
|
+
#expect(!plan.declaresWindow)
|
|
26
|
+
#expect(!plan.declaresMainWindow)
|
|
27
|
+
#else
|
|
28
|
+
#expect(!plan.isBarOnly, "a full build must launch with the workspace window")
|
|
29
|
+
#expect(plan.declaresWindow)
|
|
30
|
+
#expect(plan.declaresMainWindow)
|
|
31
|
+
#endif
|
|
32
|
+
#expect(plan.declaresMenuBar)
|
|
33
|
+
#expect(plan.installsGlobalHandlers)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Test("the explicit bar argument makes any launch bar-only on a full build")
|
|
37
|
+
func explicitBarArgument() {
|
|
38
|
+
#if !RECORDINGS_BAR_ONLY
|
|
39
|
+
let plan = PermissionRequestLaunchPlan(arguments: ["--bar-only"])
|
|
40
|
+
#expect(plan.isBarOnly)
|
|
41
|
+
#expect(!plan.declaresWindow)
|
|
42
|
+
#expect(!plan.declaresMainWindow)
|
|
43
|
+
// The menu bar is still declared: the bar keeps the record controls, live
|
|
44
|
+
// transcription, paste delivery, and settings surfaces.
|
|
45
|
+
#expect(plan.declaresMenuBar)
|
|
46
|
+
#endif
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@Test("a full build's normal-mode runtime smoke keeps exercising the workspace window")
|
|
50
|
+
func fullBuildRuntimeSmokePlan() {
|
|
51
|
+
let plan = PermissionRequestLaunchPlan(arguments: [
|
|
52
|
+
"--runtime-smoke", "normal",
|
|
53
|
+
"--runtime-smoke-output", "/tmp/smoke.json",
|
|
54
|
+
])
|
|
55
|
+
#if RECORDINGS_BAR_ONLY
|
|
56
|
+
// On a bar build even the smoke is bar-only: the windowless branch keys on the
|
|
57
|
+
// build variant, not on the smoke mode.
|
|
58
|
+
#expect(plan.isBarOnly)
|
|
59
|
+
#expect(!plan.declaresWindow)
|
|
60
|
+
#else
|
|
61
|
+
// The cycle-2 P1 regression: a full build's smoke must still be able to create
|
|
62
|
+
// the workspace window, or every full build's smoke fails deterministically.
|
|
63
|
+
#expect(!plan.isBarOnly)
|
|
64
|
+
#expect(plan.declaresWindow, "the full-build smoke must exercise the workspace window")
|
|
65
|
+
#endif
|
|
66
|
+
// declaresMainWindow excludes runtime smoke in BOTH variants so the smoke controls
|
|
67
|
+
// window creation deterministically (no init auto-open, no reopen handler).
|
|
68
|
+
#expect(!plan.declaresMainWindow)
|
|
69
|
+
#expect(plan.isRuntimeSmoke)
|
|
70
|
+
#expect(plan.declaresMenuBar, "the smoke must observe the live menu bar surface")
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@Test("a bar plan keeps the menu bar and global handlers but never declares a window")
|
|
74
|
+
func barPlanKeepsMenuBarAndGlobalHandlers() {
|
|
75
|
+
let plan = PermissionRequestLaunchPlan(arguments: ["--bar-only"])
|
|
76
|
+
#expect(plan.installsGlobalHandlers)
|
|
77
|
+
#expect(plan.declaresMenuBar)
|
|
78
|
+
#expect(plan.isBarOnly)
|
|
79
|
+
#expect(!plan.declaresWindow)
|
|
80
|
+
#expect(!plan.declaresMainWindow)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@Test("declaresMainWindow excludes runtime smoke, helper, and bar launches")
|
|
84
|
+
func declaresMainWindowExcludesRuntimeSmoke() {
|
|
85
|
+
for arguments in [
|
|
86
|
+
["--runtime-smoke", "normal"],
|
|
87
|
+
["--runtime-smoke", "permission-helper"],
|
|
88
|
+
["--request-permissions"],
|
|
89
|
+
["--bar-only"],
|
|
90
|
+
] {
|
|
91
|
+
let plan = PermissionRequestLaunchPlan(arguments: arguments)
|
|
92
|
+
#expect(!plan.declaresMainWindow)
|
|
93
|
+
}
|
|
94
|
+
let plain = PermissionRequestLaunchPlan(arguments: [])
|
|
95
|
+
#if !RECORDINGS_BAR_ONLY
|
|
96
|
+
#expect(plain.declaresMainWindow)
|
|
97
|
+
#endif
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -83,7 +83,7 @@ fi
|
|
|
83
83
|
readonly RELEASE_SUBTYPE
|
|
84
84
|
RELEASE_ARCHITECTURES=(arm64 x86_64)
|
|
85
85
|
|
|
86
|
-
CODESIGN_IDENTITY="${RECORDINGS_CODESIGN_IDENTITY:-}"
|
|
86
|
+
CODESIGN_IDENTITY="${RECORDINGS_CODESIGN_IDENTITY:-${HASNA_CODESIGN_IDENTITY:-}}"
|
|
87
87
|
EXPECTED_TEAM_ID="${RECORDINGS_EXPECTED_TEAM_IDENTIFIER:-}"
|
|
88
88
|
NOTARY_PROFILE="${RECORDINGS_NOTARY_KEYCHAIN_PROFILE:-}"
|
|
89
89
|
INSTALLER_IDENTITY="${RECORDINGS_INSTALLER_CODESIGN_IDENTITY:-}"
|
|
@@ -96,6 +96,41 @@ COMPATIBLE_COHORT_MANIFEST="${RECORDINGS_RELEASE_COMPATIBLE_COHORT_MANIFEST:-}"
|
|
|
96
96
|
LOCAL_APPROVED_TARGET="${RECORDINGS_LOCAL_APPROVED_TARGET:-}"
|
|
97
97
|
LOCAL_APPROVED_TARGET_IDENTITY_KIND="${RECORDINGS_LOCAL_APPROVED_TARGET_IDENTITY_KIND:-}"
|
|
98
98
|
LOCAL_APPROVED_TARGET_IDENTITY_SHA256="${RECORDINGS_LOCAL_APPROVED_TARGET_IDENTITY_SHA256:-}"
|
|
99
|
+
VARIANT="${RECORDINGS_VARIANT:-full}"
|
|
100
|
+
case "$VARIANT" in
|
|
101
|
+
full|bar) ;;
|
|
102
|
+
*)
|
|
103
|
+
echo "RECORDINGS_VARIANT must be full or bar; got: $VARIANT" >&2
|
|
104
|
+
exit 2
|
|
105
|
+
;;
|
|
106
|
+
esac
|
|
107
|
+
if [ "$MODE" = "release" ] && [ "$VARIANT" = "bar" ]; then
|
|
108
|
+
# The bar variant is a deliberate product change (no workspace window, accessory
|
|
109
|
+
# launch); a release that carries it must be explicitly marked so a default release
|
|
110
|
+
# can never silently emit a bar artifact.
|
|
111
|
+
if [ "${RECORDINGS_RELEASE_BAR_VARIANT_MARKED:-0}" != "1" ]; then
|
|
112
|
+
echo "release-mode bar-variant builds require RECORDINGS_RELEASE_BAR_VARIANT_MARKED=1 to proceed explicitly." >&2
|
|
113
|
+
exit 2
|
|
114
|
+
fi
|
|
115
|
+
fi
|
|
116
|
+
readonly VARIANT
|
|
117
|
+
VARIANT_SWIFT_FLAGS=()
|
|
118
|
+
if [ "$VARIANT" = "bar" ]; then
|
|
119
|
+
VARIANT_SWIFT_FLAGS=(-Xswiftc -DRECORDINGS_BAR_ONLY)
|
|
120
|
+
fi
|
|
121
|
+
# Fleet naming rule (knowledge k_msxd5rz3_jfvl3i): every Hasna macOS app is
|
|
122
|
+
# Hasna<Name>.app with 'Hasna' at the beginning. The full app keeps its historical
|
|
123
|
+
# Recordings.app name (its rename is the rule's recorded follow-up decision); the
|
|
124
|
+
# bar-only artifact is named per the rule NOW — HasnaRecordings.app. The 'bar' is the
|
|
125
|
+
# variant, never a separate app name: bundle identifier stays com.hasna.recordings so
|
|
126
|
+
# TCC keeps keying on bundle id + signing identity, and the executable inside the
|
|
127
|
+
# bundle stays "Recordings".
|
|
128
|
+
APP_BUNDLE_NAME="Recordings.app"
|
|
129
|
+
if [ "$VARIANT" = "bar" ]; then
|
|
130
|
+
APP_BUNDLE_NAME="HasnaRecordings.app"
|
|
131
|
+
fi
|
|
132
|
+
readonly APP_BUNDLE_NAME
|
|
133
|
+
APP_BASENAME="${APP_BUNDLE_NAME%.app}"
|
|
99
134
|
PLIST_BUDDY="$(select_executable "/usr/libexec/PlistBuddy" "${RECORDINGS_TEST_PLIST_BUDDY_EXECUTABLE:-${PLIST_BUDDY:-}}")"
|
|
100
135
|
PLUTIL="$(select_executable "/usr/bin/plutil" "${RECORDINGS_TEST_PLUTIL_EXECUTABLE:-${PLUTIL:-}}")"
|
|
101
136
|
BUN_EXECUTABLE="${BUN_EXECUTABLE:-}"
|
|
@@ -134,6 +169,48 @@ LIPO_EXECUTABLE="$(select_executable "/usr/bin/lipo" "${RECORDINGS_TEST_LIPO_EXE
|
|
|
134
169
|
STAT_EXECUTABLE="$(select_executable "/usr/bin/stat" "${RECORDINGS_TEST_STAT_EXECUTABLE:-}")"
|
|
135
170
|
TEST_GIT_EXECUTABLE="$(select_executable "" "${RECORDINGS_TEST_GIT_EXECUTABLE:-}")"
|
|
136
171
|
TEST_SWIFT_EXECUTABLE="$(select_executable "" "${RECORDINGS_TEST_SWIFT_EXECUTABLE:-}")"
|
|
172
|
+
SECURITY_EXECUTABLE="$(select_executable "/usr/bin/security" "${RECORDINGS_TEST_SECURITY_EXECUTABLE:-}")"
|
|
173
|
+
|
|
174
|
+
# Developer ID signing identity support. The identity comes from RECORDINGS_CODESIGN_IDENTITY
|
|
175
|
+
# (legacy) or HASNA_CODESIGN_IDENTITY (canonical name), and when neither is supplied the
|
|
176
|
+
# keychain is consulted with `security find-identity -v -p codesigning` and the first
|
|
177
|
+
# "Developer ID Application:" identity is used. Signing NEVER silently falls back to ad-hoc
|
|
178
|
+
# when a Developer ID was requested: release builds always require one, and a local build
|
|
179
|
+
# with RECORDINGS_SIGNING_REQUIRED=1 fails loudly when none exists.
|
|
180
|
+
discover_developer_id_identity() {
|
|
181
|
+
local listing
|
|
182
|
+
listing="$("$SECURITY_EXECUTABLE" find-identity -v -p codesigning 2>/dev/null)" || return 0
|
|
183
|
+
printf '%s\n' "$listing" | "$AWK_EXECUTABLE" -F'"' '/Developer ID Application:/ { print $2; exit }'
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
derive_team_id() {
|
|
187
|
+
local identity="$1"
|
|
188
|
+
local team_id
|
|
189
|
+
team_id="$(printf '%s\n' "$identity" | "$SED_EXECUTABLE" -n 's/.*(\([A-Z0-9]\{10\}\))$/\1/p')"
|
|
190
|
+
if ! [[ "$team_id" =~ ^[A-Z0-9]{10}$ ]]; then
|
|
191
|
+
echo "Could not derive a 10-character Developer ID team from the signing identity: $identity" >&2
|
|
192
|
+
return 1
|
|
193
|
+
fi
|
|
194
|
+
printf '%s\n' "$team_id"
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
resolve_signing_identity() {
|
|
198
|
+
# Called when no explicit identity was supplied. Fails loudly when a Developer ID
|
|
199
|
+
# was requested but none can be found; the caller decides whether one was requested.
|
|
200
|
+
if [ "$HOST_PLATFORM" != "Darwin" ]; then
|
|
201
|
+
return 0
|
|
202
|
+
fi
|
|
203
|
+
local discovered
|
|
204
|
+
discovered="$(discover_developer_id_identity)"
|
|
205
|
+
if [ -z "$discovered" ]; then
|
|
206
|
+
echo "Developer ID signing was requested but no Developer ID Application identity found in the keychain; never silently ad-hoc when a Developer ID is requested." >&2
|
|
207
|
+
return 1
|
|
208
|
+
fi
|
|
209
|
+
CODESIGN_IDENTITY="$discovered"
|
|
210
|
+
if [ -z "$EXPECTED_TEAM_ID" ]; then
|
|
211
|
+
EXPECTED_TEAM_ID="$(derive_team_id "$CODESIGN_IDENTITY")" || return 1
|
|
212
|
+
fi
|
|
213
|
+
}
|
|
137
214
|
|
|
138
215
|
require_executable() {
|
|
139
216
|
local label="$1"
|
|
@@ -253,6 +330,7 @@ require_executable "ID_EXECUTABLE" "$ID_EXECUTABLE"
|
|
|
253
330
|
require_executable "STAT_EXECUTABLE" "$STAT_EXECUTABLE"
|
|
254
331
|
if [ "$HOST_PLATFORM" = "Darwin" ]; then
|
|
255
332
|
require_executable "LIPO_EXECUTABLE" "$LIPO_EXECUTABLE"
|
|
333
|
+
require_executable "SECURITY_EXECUTABLE" "$SECURITY_EXECUTABLE"
|
|
256
334
|
fi
|
|
257
335
|
require_bun_executable "$BUN_EXECUTABLE"
|
|
258
336
|
if [ "$MODE" = "release" ]; then
|
|
@@ -545,11 +623,23 @@ run_codesign() {
|
|
|
545
623
|
}
|
|
546
624
|
|
|
547
625
|
run_swift() {
|
|
626
|
+
# VARIANT_SWIFT_FLAGS is empty for every full build (the default). A bare
|
|
627
|
+
# "${arr[@]}" on an EMPTY array under `set -u` aborts bash < 4.4 — macOS
|
|
628
|
+
# /bin/bash is 3.2.57 — with `unbound variable`, which killed every build the
|
|
629
|
+
# moment the flags existed. The ${arr[0]+"${arr[@]}"} guard is the script-wide
|
|
630
|
+
# idiom (see run_bun, run_xcrun, run_release_sensitive_tool); do not reintroduce
|
|
631
|
+
# a bare expansion here.
|
|
632
|
+
#
|
|
633
|
+
# The flags are arguments TO swift (after the executable), never before it:
|
|
634
|
+
# placed before the executable they would be consumed by /usr/bin/env as its
|
|
635
|
+
# own options and the build would die with `env: '-Xswiftc': No such file`.
|
|
548
636
|
"$ENV_EXECUTABLE" -i \
|
|
549
637
|
HOME="$BUILD_HOME" \
|
|
550
638
|
PATH="$SANITIZED_PATH" \
|
|
551
639
|
TMPDIR="$BUILD_WORK_DIR" \
|
|
552
|
-
"$SWIFT_EXECUTABLE"
|
|
640
|
+
"$SWIFT_EXECUTABLE" \
|
|
641
|
+
${VARIANT_SWIFT_FLAGS[0]+"${VARIANT_SWIFT_FLAGS[@]}"} \
|
|
642
|
+
"$@"
|
|
553
643
|
}
|
|
554
644
|
|
|
555
645
|
run_lipo() {
|
|
@@ -939,8 +1029,19 @@ BUILDER_IDENTITY_KIND="none"
|
|
|
939
1029
|
BUILDER_IDENTITY_SHA256="none"
|
|
940
1030
|
if [ "$MODE" = "release" ]; then
|
|
941
1031
|
if [ -z "$CODESIGN_IDENTITY" ] || [ "$CODESIGN_IDENTITY" = "-" ]; then
|
|
942
|
-
|
|
943
|
-
|
|
1032
|
+
# No explicit identity: discover the Developer ID Application identity from the
|
|
1033
|
+
# keychain. Release signing is never optional, so "requested but not found" fails
|
|
1034
|
+
# loudly instead of degrading to an ad-hoc signature.
|
|
1035
|
+
if [ "$HOST_PLATFORM" = "Darwin" ]; then
|
|
1036
|
+
resolve_signing_identity || {
|
|
1037
|
+
echo "Release builds require a Developer ID Application identity in RECORDINGS_CODESIGN_IDENTITY or HASNA_CODESIGN_IDENTITY." >&2
|
|
1038
|
+
exit 1
|
|
1039
|
+
}
|
|
1040
|
+
fi
|
|
1041
|
+
if [ -z "$CODESIGN_IDENTITY" ] || [ "$CODESIGN_IDENTITY" = "-" ]; then
|
|
1042
|
+
echo "Release builds require RECORDINGS_CODESIGN_IDENTITY or HASNA_CODESIGN_IDENTITY for a Developer ID Application identity." >&2
|
|
1043
|
+
exit 1
|
|
1044
|
+
fi
|
|
944
1045
|
fi
|
|
945
1046
|
if [ -z "$EXPECTED_TEAM_ID" ]; then
|
|
946
1047
|
echo "Release builds require RECORDINGS_EXPECTED_TEAM_IDENTIFIER to pin the Developer ID team." >&2
|
|
@@ -1075,6 +1176,31 @@ elif [ "$MODE" = "local" ]; then
|
|
|
1075
1176
|
# a release is notarization, the single-target binding, and the builder attestation
|
|
1076
1177
|
# above, none of which are relaxed. With no identity supplied the old ad-hoc behaviour
|
|
1077
1178
|
# is kept verbatim, because a Mac without the signing key must still be able to build.
|
|
1179
|
+
if [ -z "$CODESIGN_IDENTITY" ] || [ "$CODESIGN_IDENTITY" = "-" ]; then
|
|
1180
|
+
if [ "${RECORDINGS_SIGNING_REQUIRED:-0}" = "1" ]; then
|
|
1181
|
+
# A Developer ID was explicitly requested for this local build: discover it
|
|
1182
|
+
# from the keychain and fail loudly when none exists.
|
|
1183
|
+
resolve_signing_identity || exit 1
|
|
1184
|
+
elif [ "$HOST_PLATFORM" = "Darwin" ]; then
|
|
1185
|
+
# The DEFAULT route is the keychain: `security find-identity` and use the
|
|
1186
|
+
# Developer ID Application identity when one exists. That is the stable
|
|
1187
|
+
# signing identity TCC grants key on — an ad-hoc signature has no identity
|
|
1188
|
+
# to key on beyond a CDHash that changes on every rebuild, which orphans
|
|
1189
|
+
# the Accessibility grant and breaks the Fn hold-to-talk path. A Mac
|
|
1190
|
+
# without the signing key still builds ad-hoc (the old behaviour), but the
|
|
1191
|
+
# fallback is LOUD, never silent, and RECORDINGS_SIGNING_REQUIRED=1 above
|
|
1192
|
+
# turns it into a hard failure.
|
|
1193
|
+
discovered_identity="$(discover_developer_id_identity)"
|
|
1194
|
+
if [ -n "$discovered_identity" ]; then
|
|
1195
|
+
CODESIGN_IDENTITY="$discovered_identity"
|
|
1196
|
+
if [ -z "$EXPECTED_TEAM_ID" ]; then
|
|
1197
|
+
EXPECTED_TEAM_ID="$(derive_team_id "$CODESIGN_IDENTITY")" || exit 1
|
|
1198
|
+
fi
|
|
1199
|
+
else
|
|
1200
|
+
echo "WARNING: no Developer ID Application identity found in the keychain; local build falls back to ad-hoc signing (set RECORDINGS_SIGNING_REQUIRED=1 to fail instead)." >&2
|
|
1201
|
+
fi
|
|
1202
|
+
fi
|
|
1203
|
+
fi
|
|
1078
1204
|
if [ -n "$CODESIGN_IDENTITY" ] && [ "$CODESIGN_IDENTITY" != "-" ]; then
|
|
1079
1205
|
if [[ "$CODESIGN_IDENTITY" != "Developer ID Application:"* ]]; then
|
|
1080
1206
|
echo "Local-station signing requires a Developer ID Application identity in RECORDINGS_CODESIGN_IDENTITY." >&2
|
|
@@ -1140,9 +1266,9 @@ if [ "$MODE" = "release" ]; then
|
|
|
1140
1266
|
else
|
|
1141
1267
|
OUTPUT_BUILD_DIR="$SCRIPT_DIR/.build/$BUILD_CONFIGURATION"
|
|
1142
1268
|
fi
|
|
1143
|
-
OUTPUT_APP_DIR="$OUTPUT_BUILD_DIR
|
|
1269
|
+
OUTPUT_APP_DIR="$OUTPUT_BUILD_DIR/$APP_BUNDLE_NAME"
|
|
1144
1270
|
SWIFT_PRODUCT_DIR="$SWIFT_SCRATCH_PATH/$BUILD_CONFIGURATION"
|
|
1145
|
-
APP_DIR="$BUILD_WORK_DIR
|
|
1271
|
+
APP_DIR="$BUILD_WORK_DIR/$APP_BUNDLE_NAME"
|
|
1146
1272
|
CONTENTS="$APP_DIR/Contents"
|
|
1147
1273
|
MACOS="$CONTENTS/MacOS"
|
|
1148
1274
|
RESOURCES="$CONTENTS/Resources"
|
|
@@ -1300,6 +1426,16 @@ if [ "$MODE" = "release" ] && [ "$HOST_PLATFORM" = "Darwin" ]; then
|
|
|
1300
1426
|
fi
|
|
1301
1427
|
fi
|
|
1302
1428
|
"$CP_EXECUTABLE" "$SOURCE_NATIVE_DIR/RecordingsLib/Info.plist" "$CONTENTS/Info.plist"
|
|
1429
|
+
if [ "$VARIANT" = "bar" ]; then
|
|
1430
|
+
# The bar is an accessory app: LSUIElement keeps it out of the Dock and the app
|
|
1431
|
+
# switcher, and the app's window-declaring control flow (RECORDINGS_BAR_ONLY)
|
|
1432
|
+
# keeps the workspace window absent. The bundle identifier stays com.hasna.recordings
|
|
1433
|
+
# so TCC grants continue to key on bundle id + signing identity, and the bundle is
|
|
1434
|
+
# named per the fleet rule (knowledge k_msxd5rz3_jfvl3i) — HasnaRecordings.app with
|
|
1435
|
+
# the display name "Hasna Recordings"; 'Hasna' at the beginning of the name.
|
|
1436
|
+
"$PLIST_BUDDY" -c 'Add :LSUIElement bool true' "$CONTENTS/Info.plist"
|
|
1437
|
+
"$PLIST_BUDDY" -c 'Set :CFBundleDisplayName Hasna Recordings' "$CONTENTS/Info.plist"
|
|
1438
|
+
fi
|
|
1303
1439
|
VERSION="$("$PLIST_BUDDY" -c 'Print :CFBundleShortVersionString' "$CONTENTS/Info.plist")"
|
|
1304
1440
|
|
|
1305
1441
|
compute_release_publication_identity() {
|
|
@@ -1313,6 +1449,7 @@ compute_release_publication_identity() {
|
|
|
1313
1449
|
--component "release_sequence=$RELEASE_SEQUENCE"
|
|
1314
1450
|
--component "key_epoch=$KEY_EPOCH"
|
|
1315
1451
|
--component "expires_at_utc=$ENVELOPE_EXPIRES_AT_UTC"
|
|
1452
|
+
--component "variant=$VARIANT"
|
|
1316
1453
|
)
|
|
1317
1454
|
identity_arguments+=(--component "envelope_public_key_sha256=$ENVELOPE_PUBLIC_KEY_SHA256")
|
|
1318
1455
|
if [ "$RELEASE_SUBTYPE" = "initial-bootstrap" ]; then
|
|
@@ -1331,7 +1468,7 @@ compute_release_publication_identity() {
|
|
|
1331
1468
|
|
|
1332
1469
|
reserve_release_output() {
|
|
1333
1470
|
local release_set_basename reserved_output
|
|
1334
|
-
release_set_basename="
|
|
1471
|
+
release_set_basename="${APP_BASENAME}-${VERSION}-macos-${RELEASE_SUBTYPE}"
|
|
1335
1472
|
compute_release_publication_identity
|
|
1336
1473
|
RELEASE_OUTPUT_ROOT="$OUTPUT_BUILD_DIR"
|
|
1337
1474
|
RELEASE_FINAL_DIR="$RELEASE_OUTPUT_ROOT/${release_set_basename}.release"
|
|
@@ -1398,7 +1535,7 @@ reserve_release_output() {
|
|
|
1398
1535
|
RELEASE_STAGING_DIR="$($MKTEMP_EXECUTABLE -d "$RELEASE_OUTPUT_ROOT/.${release_set_basename}.staging.XXXXXX")"
|
|
1399
1536
|
"$CHMOD_EXECUTABLE" 0700 "$RELEASE_STAGING_DIR"
|
|
1400
1537
|
OUTPUT_BUILD_DIR="$RELEASE_STAGING_DIR"
|
|
1401
|
-
OUTPUT_APP_DIR="$OUTPUT_BUILD_DIR
|
|
1538
|
+
OUTPUT_APP_DIR="$OUTPUT_BUILD_DIR/$APP_BUNDLE_NAME"
|
|
1402
1539
|
}
|
|
1403
1540
|
|
|
1404
1541
|
if [ "$MODE" = "release" ]; then
|
|
@@ -1586,6 +1723,7 @@ if [ "$MODE" != "debug" ]; then
|
|
|
1586
1723
|
--team-id "$EXPECTED_TEAM_ID" \
|
|
1587
1724
|
--package-root "$PACKAGE_ROOT" \
|
|
1588
1725
|
--artifact-policy "$ARTIFACT_POLICY" \
|
|
1726
|
+
--variant "$VARIANT" \
|
|
1589
1727
|
--approved-target "$APPROVED_TARGET" \
|
|
1590
1728
|
--approved-target-identity-kind "$APPROVED_TARGET_IDENTITY_KIND" \
|
|
1591
1729
|
--approved-target-identity-sha256 "$APPROVED_TARGET_IDENTITY_SHA256" \
|
|
@@ -1643,7 +1781,7 @@ run_codesign --verify --deep --strict --verbose=2 "$APP_DIR"
|
|
|
1643
1781
|
TMPDIR="$BUILD_WORK_DIR" \
|
|
1644
1782
|
SSH_CONNECTION="${SSH_CONNECTION:-}" \
|
|
1645
1783
|
${SMOKE_TEST_ENVIRONMENT[0]+"${SMOKE_TEST_ENVIRONMENT[@]}"} \
|
|
1646
|
-
"$BASH_EXECUTABLE" "$SMOKE_SCRIPT" "$APP_DIR" "$BUN_EXECUTABLE"
|
|
1784
|
+
"$BASH_EXECUTABLE" "$SMOKE_SCRIPT" "$APP_DIR" "$BUN_EXECUTABLE" --variant "$VARIANT"
|
|
1647
1785
|
|
|
1648
1786
|
publish_app_output() {
|
|
1649
1787
|
local source_tree_digest
|
|
@@ -1807,7 +1945,7 @@ publish_complete_release_set() {
|
|
|
1807
1945
|
RELEASE_DIRECTORY_PUBLISHED=1
|
|
1808
1946
|
RELEASE_STAGING_DIR=""
|
|
1809
1947
|
OUTPUT_BUILD_DIR="$RELEASE_FINAL_DIR"
|
|
1810
|
-
OUTPUT_APP_DIR="$OUTPUT_BUILD_DIR
|
|
1948
|
+
OUTPUT_APP_DIR="$OUTPUT_BUILD_DIR/$APP_BUNDLE_NAME"
|
|
1811
1949
|
run_bun "$SOURCE_PACKAGE_ROOT/scripts/macos_artifact.ts" complete-release-publication \
|
|
1812
1950
|
--destination "$RELEASE_FINAL_DIR" \
|
|
1813
1951
|
--reservation "$RELEASE_RESERVATION" \
|
|
@@ -1833,7 +1971,7 @@ if [ "$MODE" = "debug" ]; then
|
|
|
1833
1971
|
fi
|
|
1834
1972
|
|
|
1835
1973
|
if [ "$MODE" = "local" ]; then
|
|
1836
|
-
ARTIFACT_BASENAME="
|
|
1974
|
+
ARTIFACT_BASENAME="${APP_BASENAME}-${VERSION}-macos-${APPROVED_TARGET}-local-only"
|
|
1837
1975
|
FINAL_ARCHIVE="$OUTPUT_BUILD_DIR/${ARTIFACT_BASENAME}.zip"
|
|
1838
1976
|
FINAL_MANIFEST="$OUTPUT_BUILD_DIR/${ARTIFACT_BASENAME}.manifest.json"
|
|
1839
1977
|
"$RM_EXECUTABLE" -f "$FINAL_ARCHIVE" "$FINAL_MANIFEST"
|
|
@@ -1846,6 +1984,7 @@ if [ "$MODE" = "local" ]; then
|
|
|
1846
1984
|
--archive "$FINAL_ARCHIVE" \
|
|
1847
1985
|
--manifest "$FINAL_MANIFEST" \
|
|
1848
1986
|
--package-root "$PACKAGE_ROOT" \
|
|
1987
|
+
--variant "$VARIANT" \
|
|
1849
1988
|
--approved-target "$APPROVED_TARGET" \
|
|
1850
1989
|
--approved-target-identity-kind "$APPROVED_TARGET_IDENTITY_KIND" \
|
|
1851
1990
|
--approved-target-identity-sha256 "$APPROVED_TARGET_IDENTITY_SHA256" \
|
|
@@ -1860,7 +1999,7 @@ fi
|
|
|
1860
1999
|
|
|
1861
2000
|
verify_signed_code "$HELPERS/recordings" "Companion CLI"
|
|
1862
2001
|
verify_signed_code "$APP_DIR" "Recordings.app"
|
|
1863
|
-
ARTIFACT_BASENAME="
|
|
2002
|
+
ARTIFACT_BASENAME="${APP_BASENAME}-${VERSION}-macos-${RELEASE_SUBTYPE}"
|
|
1864
2003
|
NOTARY_ARCHIVE="$OUTPUT_BUILD_DIR/${ARTIFACT_BASENAME}-notarization.zip"
|
|
1865
2004
|
FINAL_ARCHIVE="$OUTPUT_BUILD_DIR/${ARTIFACT_BASENAME}.zip"
|
|
1866
2005
|
FINAL_MANIFEST="$OUTPUT_BUILD_DIR/${ARTIFACT_BASENAME}.manifest.json"
|
|
@@ -1923,6 +2062,7 @@ run_bun "$SOURCE_PACKAGE_ROOT/scripts/macos_artifact.ts" finalize \
|
|
|
1923
2062
|
--manifest "$FINAL_MANIFEST" \
|
|
1924
2063
|
--package-root "$PACKAGE_ROOT" \
|
|
1925
2064
|
--team-id "$EXPECTED_TEAM_ID" \
|
|
2065
|
+
--variant "$VARIANT" \
|
|
1926
2066
|
--notary-log "$NOTARY_LOG" \
|
|
1927
2067
|
--notary-submission-id "$NOTARY_ID" \
|
|
1928
2068
|
--submitted-archive-sha256 "$NOTARY_ARCHIVE_SHA256"
|