@hasna/recordings 0.3.1 → 0.3.8
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/README.md +38 -34
- package/bun.lock +96 -36
- package/dist/__tests__/helpers/installer-guard-execution.d.ts.map +1 -1
- package/dist/__tests__/helpers/source-assertions.d.ts +6 -4
- package/dist/__tests__/helpers/source-assertions.d.ts.map +1 -1
- package/dist/cli/index.js +197 -95
- package/dist/cli/macos-shortcut.d.ts +2 -2
- package/dist/db/pg-migrations.d.ts +1 -1
- package/dist/http/client.d.ts +0 -1
- package/dist/http/client.d.ts.map +1 -1
- package/dist/index.js +162 -73
- package/dist/lib/capture-probe.d.ts +3 -3
- package/dist/lib/capture-probe.d.ts.map +1 -1
- package/dist/lib/macos-bundle.d.ts +1 -1
- package/dist/lib/release-install-policy.d.ts +21 -0
- package/dist/lib/release-install-policy.d.ts.map +1 -1
- package/dist/mcp/index.js +144 -59
- package/dist/sdk/index.d.ts +2 -2
- package/dist/sdk/index.js +7 -3
- package/dist/sdk/v1.generated.d.ts.map +1 -1
- package/dist/server/cloud-config.d.ts +4 -19
- package/dist/server/cloud-config.d.ts.map +1 -1
- package/dist/server/cloud.d.ts +1 -1
- package/dist/server/cloud.d.ts.map +1 -1
- package/dist/server/index.js +168 -110
- package/dist/server/serve.d.ts.map +1 -1
- package/dist/storage.d.ts +1 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +144 -60
- package/dist/store.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/package.json +4 -3
- package/packaging/macos/build_release_pkg.sh +10 -4
- package/packaging/macos/managed_bootstrap.sh +4 -4
- package/packaging/macos/scripts/postinstall +2 -2
- package/packaging/macos/scripts/preinstall +2 -0
- package/scripts/generate-sdk.ts +17 -16
- package/scripts/install_macos_app.sh +75 -28
- package/scripts/macos_artifact.ts +162 -45
- package/scripts/migrate.ts +2 -2
- package/scripts/release-suite-gate.ts +181 -0
- package/scripts/set-version.ts +5 -5
- package/scripts/smoke_macos_app.sh +80 -34
- package/scripts/vacuity-manifests/version-sites.tsv +8 -4
- 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 +3 -3
- package/src/native/Recordings/RecordingsLib/PermissionRequestLaunchPlan.swift +21 -1
- package/src/native/Recordings/RecordingsTests/BarOnlyLaunchPlanTests.swift +99 -0
- package/src/native/Recordings/RecordingsTests/CLIRunnerTests.swift +2 -2
- package/src/native/Recordings/RecordingsTests/RecordingStartGateTests.swift +1 -1
- package/src/native/Recordings/Updater/BootstrapPreflight/BootstrapPreflightMain.swift +1 -1
- package/src/native/Recordings/Updater/Broker/ApplicationNamespace.swift +2 -2
- package/src/native/Recordings/Updater/Broker/BrokerMain.swift +1 -1
- package/src/native/Recordings/Updater/Broker/CanonicalTreeCopy.swift +1 -1
- package/src/native/Recordings/Updater/Broker/InstallJournal.swift +1 -1
- package/src/native/Recordings/Updater/BrokerTests/ActivationRecoveryPolicyTests.swift +2 -2
- package/src/native/Recordings/Updater/Protocol/UpdateProtocol.swift +1 -1
- package/src/native/Recordings/Updater/VerifierLauncher/RecordingsVerifierLauncher.c +2 -2
- package/src/native/Recordings/build.sh +152 -18
- package/dist/lib/retired-deployment-modes.d.ts +0 -24
- package/dist/lib/retired-deployment-modes.d.ts.map +0 -1
|
@@ -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
|
+
}
|
|
@@ -8,7 +8,7 @@ struct CLIRunnerTests {
|
|
|
8
8
|
func bundledCLIIsPreferred() throws {
|
|
9
9
|
let root = FileManager.default.temporaryDirectory
|
|
10
10
|
.appendingPathComponent("recordings-bundled-cli-\(UUID().uuidString)")
|
|
11
|
-
let app = root.appendingPathComponent("
|
|
11
|
+
let app = root.appendingPathComponent("HasnaRecordings.app")
|
|
12
12
|
let helper = app.appendingPathComponent("Contents/Helpers/recordings")
|
|
13
13
|
let home = root.appendingPathComponent("home")
|
|
14
14
|
let external = home.appendingPathComponent(".bun/bin/recordings")
|
|
@@ -34,7 +34,7 @@ struct CLIRunnerTests {
|
|
|
34
34
|
func packagedAppDoesNotUseGlobalFallback() throws {
|
|
35
35
|
let root = FileManager.default.temporaryDirectory
|
|
36
36
|
.appendingPathComponent("recordings-missing-companion-\(UUID().uuidString)")
|
|
37
|
-
let app = root.appendingPathComponent("
|
|
37
|
+
let app = root.appendingPathComponent("HasnaRecordings.app")
|
|
38
38
|
let home = root.appendingPathComponent("home")
|
|
39
39
|
let external = home.appendingPathComponent(".bun/bin/recordings")
|
|
40
40
|
try FileManager.default.createDirectory(at: app, withIntermediateDirectories: true)
|
|
@@ -6,7 +6,7 @@ struct RecordingStartGateTests {
|
|
|
6
6
|
@Test("permission-only launch skips global handlers and terminates after handling")
|
|
7
7
|
func permissionHelperLaunchPlan() {
|
|
8
8
|
let plan = PermissionRequestLaunchPlan(arguments: [
|
|
9
|
-
"/Applications/
|
|
9
|
+
"/Applications/HasnaRecordings.app/Contents/MacOS/Recordings",
|
|
10
10
|
"--request-permissions",
|
|
11
11
|
"--open-permission-settings",
|
|
12
12
|
])
|
|
@@ -51,7 +51,7 @@ enum RecordingsBootstrapPreflight {
|
|
|
51
51
|
let manifest = try JSONDecoder().decode(ReleaseManifest.self, from: manifestData)
|
|
52
52
|
try validateManifest(manifest, payload: payload)
|
|
53
53
|
|
|
54
|
-
let app = arguments.payloadRoot + "/Applications/
|
|
54
|
+
let app = arguments.payloadRoot + "/Applications/HasnaRecordings.app"
|
|
55
55
|
let client = app + "/" + RecordingsUpdateConstants.updateClientRelativePath
|
|
56
56
|
let broker = arguments.payloadRoot + "/Library/PrivilegedHelperTools/com.hasna.recordings.updater"
|
|
57
57
|
let artifactVerifier = arguments.payloadRoot
|
|
@@ -7,7 +7,7 @@ import RecordingsUpdateProtocol
|
|
|
7
7
|
/// operation; first installs use exclusive rename semantics and can never replace a
|
|
8
8
|
/// leaf created concurrently in `/Applications`.
|
|
9
9
|
final class ApplicationNamespace {
|
|
10
|
-
private static let liveLeaf = "
|
|
10
|
+
private static let liveLeaf = "HasnaRecordings.app"
|
|
11
11
|
private static let previousLeaf = "previous.app"
|
|
12
12
|
private static let failedCandidateLeaf = "failed-candidate.app"
|
|
13
13
|
|
|
@@ -22,7 +22,7 @@ final class ApplicationNamespace {
|
|
|
22
22
|
.deletingLastPathComponent
|
|
23
23
|
guard journal.applicationPath == RecordingsUpdateConstants.applicationPath,
|
|
24
24
|
journal.candidateApplicationPath == expectedTransactionDirectory
|
|
25
|
-
+ "/candidate/
|
|
25
|
+
+ "/candidate/HasnaRecordings.app",
|
|
26
26
|
journal.previousApplicationPath == nil ||
|
|
27
27
|
journal.previousApplicationPath == expectedTransactionDirectory + "/previous.app"
|
|
28
28
|
else {
|
|
@@ -276,7 +276,7 @@ final class UpdateBrokerSession: NSObject, RecordingsUpdateXPCProtocol {
|
|
|
276
276
|
guard mkdir(candidateRoot, 0o700) == 0 else {
|
|
277
277
|
throw BrokerOperationError.candidateRejected
|
|
278
278
|
}
|
|
279
|
-
let candidateApplication = candidateRoot + "/
|
|
279
|
+
let candidateApplication = candidateRoot + "/HasnaRecordings.app"
|
|
280
280
|
let verifierIDs = try verifierAccountIDs()
|
|
281
281
|
try CanonicalTreeCopier.copyApplication(
|
|
282
282
|
from: verifierOutput,
|
|
@@ -22,7 +22,7 @@ enum CanonicalTreeCopier {
|
|
|
22
22
|
}
|
|
23
23
|
defer { Darwin.close(source) }
|
|
24
24
|
let destinationRoot = URL(fileURLWithPath: rootCandidatePath).deletingLastPathComponent().path
|
|
25
|
-
guard URL(fileURLWithPath: rootCandidatePath).lastPathComponent == "
|
|
25
|
+
guard URL(fileURLWithPath: rootCandidatePath).lastPathComponent == "HasnaRecordings.app" else {
|
|
26
26
|
throw CanonicalCopyError.nonCanonicalRoot
|
|
27
27
|
}
|
|
28
28
|
let destination = Darwin.open(
|
|
@@ -253,7 +253,7 @@ struct DurableInstallJournal {
|
|
|
253
253
|
let leaf = URL(fileURLWithPath: transactionDirectory).lastPathComponent
|
|
254
254
|
guard leaf.hasPrefix("transaction-") else { throw InstallJournalError.invalidJournal }
|
|
255
255
|
let transactionID = String(leaf.dropFirst("transaction-".count))
|
|
256
|
-
let expectedCandidate = transactionDirectory + "/candidate/
|
|
256
|
+
let expectedCandidate = transactionDirectory + "/candidate/HasnaRecordings.app"
|
|
257
257
|
let activationPhases: Set<String> = [
|
|
258
258
|
"prepared", "launch-barrier-pending", "launch-barrier-held",
|
|
259
259
|
"swap-pending", "swapped", "previous-retaining",
|
|
@@ -201,8 +201,8 @@ struct ActivationRecoveryPolicyTests {
|
|
|
201
201
|
"Contents/Helpers/recordings": 493,
|
|
202
202
|
"Contents/Helpers/recordings-update-client": 493
|
|
203
203
|
},
|
|
204
|
-
"candidate_application_path": "/Library/Application Support/Hasna/Recordings/Updates/transaction-00000000-0000-0000-0000-000000000001/candidate/
|
|
205
|
-
"application_path": "/Applications/
|
|
204
|
+
"candidate_application_path": "/Library/Application Support/Hasna/Recordings/Updates/transaction-00000000-0000-0000-0000-000000000001/candidate/HasnaRecordings.app",
|
|
205
|
+
"application_path": "/Applications/HasnaRecordings.app"
|
|
206
206
|
}
|
|
207
207
|
"""#.utf8)
|
|
208
208
|
let journal = try JSONDecoder().decode(BrokerInstallJournal.self, from: legacyJSON)
|
|
@@ -7,7 +7,7 @@ public enum RecordingsUpdateConstants {
|
|
|
7
7
|
public static let rootMaintenanceSupported = false
|
|
8
8
|
public static let keyRotationSupported = false
|
|
9
9
|
public static let machServiceName = "com.hasna.recordings.updater"
|
|
10
|
-
public static let applicationPath = "/Applications/
|
|
10
|
+
public static let applicationPath = "/Applications/HasnaRecordings.app"
|
|
11
11
|
public static let brokerExecutablePath = "/Library/PrivilegedHelperTools/com.hasna.recordings.updater"
|
|
12
12
|
public static let stateRoot = "/Library/Application Support/Hasna/Recordings/Updates"
|
|
13
13
|
public static let trustRoot = "/Library/Application Support/Hasna/Recordings/Trust"
|
|
@@ -729,7 +729,7 @@ int recordings_copy_canonical_application_tree(
|
|
|
729
729
|
if (entry == NULL) break;
|
|
730
730
|
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
|
|
731
731
|
visible_entries += 1;
|
|
732
|
-
if (strcmp(entry->d_name, "
|
|
732
|
+
if (strcmp(entry->d_name, "HasnaRecordings.app") != 0) only_application = false;
|
|
733
733
|
}
|
|
734
734
|
int status = errno;
|
|
735
735
|
closedir(directory);
|
|
@@ -739,7 +739,7 @@ int recordings_copy_canonical_application_tree(
|
|
|
739
739
|
status = copy_directory_at(
|
|
740
740
|
verifier_output_directory_descriptor,
|
|
741
741
|
root_candidate_directory_descriptor,
|
|
742
|
-
"
|
|
742
|
+
"HasnaRecordings.app",
|
|
743
743
|
verifier_user_id,
|
|
744
744
|
&budget
|
|
745
745
|
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# Build, sign, notarize, and finalize a
|
|
2
|
+
# Build, sign, notarize, and finalize a HasnaRecordings.app artifact.
|
|
3
3
|
# Usage: ./build.sh [debug|local] | ./build.sh release <initial-bootstrap|app-update>
|
|
4
4
|
|
|
5
5
|
set -euo pipefail
|
|
@@ -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,37 @@ 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 bundle is named
|
|
123
|
+
# HasnaRecordings.app for BOTH variants (full and bar); the 'bar' is a variant, never
|
|
124
|
+
# a separate app name. Bundle identifier stays com.hasna.recordings so TCC keeps
|
|
125
|
+
# keying on bundle id + signing identity, and the executable inside the bundle stays
|
|
126
|
+
# "Recordings".
|
|
127
|
+
APP_BUNDLE_NAME="HasnaRecordings.app"
|
|
128
|
+
readonly APP_BUNDLE_NAME
|
|
129
|
+
APP_BASENAME="${APP_BUNDLE_NAME%.app}"
|
|
99
130
|
PLIST_BUDDY="$(select_executable "/usr/libexec/PlistBuddy" "${RECORDINGS_TEST_PLIST_BUDDY_EXECUTABLE:-${PLIST_BUDDY:-}}")"
|
|
100
131
|
PLUTIL="$(select_executable "/usr/bin/plutil" "${RECORDINGS_TEST_PLUTIL_EXECUTABLE:-${PLUTIL:-}}")"
|
|
101
132
|
BUN_EXECUTABLE="${BUN_EXECUTABLE:-}"
|
|
@@ -134,6 +165,48 @@ LIPO_EXECUTABLE="$(select_executable "/usr/bin/lipo" "${RECORDINGS_TEST_LIPO_EXE
|
|
|
134
165
|
STAT_EXECUTABLE="$(select_executable "/usr/bin/stat" "${RECORDINGS_TEST_STAT_EXECUTABLE:-}")"
|
|
135
166
|
TEST_GIT_EXECUTABLE="$(select_executable "" "${RECORDINGS_TEST_GIT_EXECUTABLE:-}")"
|
|
136
167
|
TEST_SWIFT_EXECUTABLE="$(select_executable "" "${RECORDINGS_TEST_SWIFT_EXECUTABLE:-}")"
|
|
168
|
+
SECURITY_EXECUTABLE="$(select_executable "/usr/bin/security" "${RECORDINGS_TEST_SECURITY_EXECUTABLE:-}")"
|
|
169
|
+
|
|
170
|
+
# Developer ID signing identity support. The identity comes from RECORDINGS_CODESIGN_IDENTITY
|
|
171
|
+
# (legacy) or HASNA_CODESIGN_IDENTITY (canonical name), and when neither is supplied the
|
|
172
|
+
# keychain is consulted with `security find-identity -v -p codesigning` and the first
|
|
173
|
+
# "Developer ID Application:" identity is used. Signing NEVER silently falls back to ad-hoc
|
|
174
|
+
# when a Developer ID was requested: release builds always require one, and a local build
|
|
175
|
+
# with RECORDINGS_SIGNING_REQUIRED=1 fails loudly when none exists.
|
|
176
|
+
discover_developer_id_identity() {
|
|
177
|
+
local listing
|
|
178
|
+
listing="$("$SECURITY_EXECUTABLE" find-identity -v -p codesigning 2>/dev/null)" || return 0
|
|
179
|
+
printf '%s\n' "$listing" | "$AWK_EXECUTABLE" -F'"' '/Developer ID Application:/ { print $2; exit }'
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
derive_team_id() {
|
|
183
|
+
local identity="$1"
|
|
184
|
+
local team_id
|
|
185
|
+
team_id="$(printf '%s\n' "$identity" | "$SED_EXECUTABLE" -n 's/.*(\([A-Z0-9]\{10\}\))$/\1/p')"
|
|
186
|
+
if ! [[ "$team_id" =~ ^[A-Z0-9]{10}$ ]]; then
|
|
187
|
+
echo "Could not derive a 10-character Developer ID team from the signing identity: $identity" >&2
|
|
188
|
+
return 1
|
|
189
|
+
fi
|
|
190
|
+
printf '%s\n' "$team_id"
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
resolve_signing_identity() {
|
|
194
|
+
# Called when no explicit identity was supplied. Fails loudly when a Developer ID
|
|
195
|
+
# was requested but none can be found; the caller decides whether one was requested.
|
|
196
|
+
if [ "$HOST_PLATFORM" != "Darwin" ]; then
|
|
197
|
+
return 0
|
|
198
|
+
fi
|
|
199
|
+
local discovered
|
|
200
|
+
discovered="$(discover_developer_id_identity)"
|
|
201
|
+
if [ -z "$discovered" ]; then
|
|
202
|
+
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
|
|
203
|
+
return 1
|
|
204
|
+
fi
|
|
205
|
+
CODESIGN_IDENTITY="$discovered"
|
|
206
|
+
if [ -z "$EXPECTED_TEAM_ID" ]; then
|
|
207
|
+
EXPECTED_TEAM_ID="$(derive_team_id "$CODESIGN_IDENTITY")" || return 1
|
|
208
|
+
fi
|
|
209
|
+
}
|
|
137
210
|
|
|
138
211
|
require_executable() {
|
|
139
212
|
local label="$1"
|
|
@@ -253,6 +326,7 @@ require_executable "ID_EXECUTABLE" "$ID_EXECUTABLE"
|
|
|
253
326
|
require_executable "STAT_EXECUTABLE" "$STAT_EXECUTABLE"
|
|
254
327
|
if [ "$HOST_PLATFORM" = "Darwin" ]; then
|
|
255
328
|
require_executable "LIPO_EXECUTABLE" "$LIPO_EXECUTABLE"
|
|
329
|
+
require_executable "SECURITY_EXECUTABLE" "$SECURITY_EXECUTABLE"
|
|
256
330
|
fi
|
|
257
331
|
require_bun_executable "$BUN_EXECUTABLE"
|
|
258
332
|
if [ "$MODE" = "release" ]; then
|
|
@@ -545,11 +619,23 @@ run_codesign() {
|
|
|
545
619
|
}
|
|
546
620
|
|
|
547
621
|
run_swift() {
|
|
622
|
+
# VARIANT_SWIFT_FLAGS is empty for every full build (the default). A bare
|
|
623
|
+
# "${arr[@]}" on an EMPTY array under `set -u` aborts bash < 4.4 — macOS
|
|
624
|
+
# /bin/bash is 3.2.57 — with `unbound variable`, which killed every build the
|
|
625
|
+
# moment the flags existed. The ${arr[0]+"${arr[@]}"} guard is the script-wide
|
|
626
|
+
# idiom (see run_bun, run_xcrun, run_release_sensitive_tool); do not reintroduce
|
|
627
|
+
# a bare expansion here.
|
|
628
|
+
#
|
|
629
|
+
# The flags are arguments TO swift (after the executable), never before it:
|
|
630
|
+
# placed before the executable they would be consumed by /usr/bin/env as its
|
|
631
|
+
# own options and the build would die with `env: '-Xswiftc': No such file`.
|
|
548
632
|
"$ENV_EXECUTABLE" -i \
|
|
549
633
|
HOME="$BUILD_HOME" \
|
|
550
634
|
PATH="$SANITIZED_PATH" \
|
|
551
635
|
TMPDIR="$BUILD_WORK_DIR" \
|
|
552
|
-
"$SWIFT_EXECUTABLE"
|
|
636
|
+
"$SWIFT_EXECUTABLE" \
|
|
637
|
+
${VARIANT_SWIFT_FLAGS[0]+"${VARIANT_SWIFT_FLAGS[@]}"} \
|
|
638
|
+
"$@"
|
|
553
639
|
}
|
|
554
640
|
|
|
555
641
|
run_lipo() {
|
|
@@ -939,8 +1025,19 @@ BUILDER_IDENTITY_KIND="none"
|
|
|
939
1025
|
BUILDER_IDENTITY_SHA256="none"
|
|
940
1026
|
if [ "$MODE" = "release" ]; then
|
|
941
1027
|
if [ -z "$CODESIGN_IDENTITY" ] || [ "$CODESIGN_IDENTITY" = "-" ]; then
|
|
942
|
-
|
|
943
|
-
|
|
1028
|
+
# No explicit identity: discover the Developer ID Application identity from the
|
|
1029
|
+
# keychain. Release signing is never optional, so "requested but not found" fails
|
|
1030
|
+
# loudly instead of degrading to an ad-hoc signature.
|
|
1031
|
+
if [ "$HOST_PLATFORM" = "Darwin" ]; then
|
|
1032
|
+
resolve_signing_identity || {
|
|
1033
|
+
echo "Release builds require a Developer ID Application identity in RECORDINGS_CODESIGN_IDENTITY or HASNA_CODESIGN_IDENTITY." >&2
|
|
1034
|
+
exit 1
|
|
1035
|
+
}
|
|
1036
|
+
fi
|
|
1037
|
+
if [ -z "$CODESIGN_IDENTITY" ] || [ "$CODESIGN_IDENTITY" = "-" ]; then
|
|
1038
|
+
echo "Release builds require RECORDINGS_CODESIGN_IDENTITY or HASNA_CODESIGN_IDENTITY for a Developer ID Application identity." >&2
|
|
1039
|
+
exit 1
|
|
1040
|
+
fi
|
|
944
1041
|
fi
|
|
945
1042
|
if [ -z "$EXPECTED_TEAM_ID" ]; then
|
|
946
1043
|
echo "Release builds require RECORDINGS_EXPECTED_TEAM_IDENTIFIER to pin the Developer ID team." >&2
|
|
@@ -1075,6 +1172,31 @@ elif [ "$MODE" = "local" ]; then
|
|
|
1075
1172
|
# a release is notarization, the single-target binding, and the builder attestation
|
|
1076
1173
|
# above, none of which are relaxed. With no identity supplied the old ad-hoc behaviour
|
|
1077
1174
|
# is kept verbatim, because a Mac without the signing key must still be able to build.
|
|
1175
|
+
if [ -z "$CODESIGN_IDENTITY" ] || [ "$CODESIGN_IDENTITY" = "-" ]; then
|
|
1176
|
+
if [ "${RECORDINGS_SIGNING_REQUIRED:-0}" = "1" ]; then
|
|
1177
|
+
# A Developer ID was explicitly requested for this local build: discover it
|
|
1178
|
+
# from the keychain and fail loudly when none exists.
|
|
1179
|
+
resolve_signing_identity || exit 1
|
|
1180
|
+
elif [ "$HOST_PLATFORM" = "Darwin" ]; then
|
|
1181
|
+
# The DEFAULT route is the keychain: `security find-identity` and use the
|
|
1182
|
+
# Developer ID Application identity when one exists. That is the stable
|
|
1183
|
+
# signing identity TCC grants key on — an ad-hoc signature has no identity
|
|
1184
|
+
# to key on beyond a CDHash that changes on every rebuild, which orphans
|
|
1185
|
+
# the Accessibility grant and breaks the Fn hold-to-talk path. A Mac
|
|
1186
|
+
# without the signing key still builds ad-hoc (the old behaviour), but the
|
|
1187
|
+
# fallback is LOUD, never silent, and RECORDINGS_SIGNING_REQUIRED=1 above
|
|
1188
|
+
# turns it into a hard failure.
|
|
1189
|
+
discovered_identity="$(discover_developer_id_identity)"
|
|
1190
|
+
if [ -n "$discovered_identity" ]; then
|
|
1191
|
+
CODESIGN_IDENTITY="$discovered_identity"
|
|
1192
|
+
if [ -z "$EXPECTED_TEAM_ID" ]; then
|
|
1193
|
+
EXPECTED_TEAM_ID="$(derive_team_id "$CODESIGN_IDENTITY")" || exit 1
|
|
1194
|
+
fi
|
|
1195
|
+
else
|
|
1196
|
+
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
|
|
1197
|
+
fi
|
|
1198
|
+
fi
|
|
1199
|
+
fi
|
|
1078
1200
|
if [ -n "$CODESIGN_IDENTITY" ] && [ "$CODESIGN_IDENTITY" != "-" ]; then
|
|
1079
1201
|
if [[ "$CODESIGN_IDENTITY" != "Developer ID Application:"* ]]; then
|
|
1080
1202
|
echo "Local-station signing requires a Developer ID Application identity in RECORDINGS_CODESIGN_IDENTITY." >&2
|
|
@@ -1134,15 +1256,15 @@ fi
|
|
|
1134
1256
|
|
|
1135
1257
|
generate_and_verify_native_fs_guard
|
|
1136
1258
|
|
|
1137
|
-
echo "Building
|
|
1259
|
+
echo "Building HasnaRecordings.app ($MODE)..."
|
|
1138
1260
|
if [ "$MODE" = "release" ]; then
|
|
1139
1261
|
OUTPUT_BUILD_DIR="$BUILD_ROOT/release-output"
|
|
1140
1262
|
else
|
|
1141
1263
|
OUTPUT_BUILD_DIR="$SCRIPT_DIR/.build/$BUILD_CONFIGURATION"
|
|
1142
1264
|
fi
|
|
1143
|
-
OUTPUT_APP_DIR="$OUTPUT_BUILD_DIR
|
|
1265
|
+
OUTPUT_APP_DIR="$OUTPUT_BUILD_DIR/$APP_BUNDLE_NAME"
|
|
1144
1266
|
SWIFT_PRODUCT_DIR="$SWIFT_SCRATCH_PATH/$BUILD_CONFIGURATION"
|
|
1145
|
-
APP_DIR="$BUILD_WORK_DIR
|
|
1267
|
+
APP_DIR="$BUILD_WORK_DIR/$APP_BUNDLE_NAME"
|
|
1146
1268
|
CONTENTS="$APP_DIR/Contents"
|
|
1147
1269
|
MACOS="$CONTENTS/MacOS"
|
|
1148
1270
|
RESOURCES="$CONTENTS/Resources"
|
|
@@ -1300,6 +1422,16 @@ if [ "$MODE" = "release" ] && [ "$HOST_PLATFORM" = "Darwin" ]; then
|
|
|
1300
1422
|
fi
|
|
1301
1423
|
fi
|
|
1302
1424
|
"$CP_EXECUTABLE" "$SOURCE_NATIVE_DIR/RecordingsLib/Info.plist" "$CONTENTS/Info.plist"
|
|
1425
|
+
# Bundle display name per the fleet naming rule (knowledge k_msxd5rz3_jfvl3i):
|
|
1426
|
+
# "Hasna Recordings" with 'Hasna' at the beginning, for both variants.
|
|
1427
|
+
"$PLIST_BUDDY" -c 'Set :CFBundleDisplayName Hasna Recordings' "$CONTENTS/Info.plist"
|
|
1428
|
+
if [ "$VARIANT" = "bar" ]; then
|
|
1429
|
+
# The bar is an accessory app: LSUIElement keeps it out of the Dock and the app
|
|
1430
|
+
# switcher, and the app's window-declaring control flow (RECORDINGS_BAR_ONLY)
|
|
1431
|
+
# keeps the workspace window absent. The bundle identifier stays com.hasna.recordings
|
|
1432
|
+
# so TCC grants continue to key on bundle id + signing identity.
|
|
1433
|
+
"$PLIST_BUDDY" -c 'Add :LSUIElement bool true' "$CONTENTS/Info.plist"
|
|
1434
|
+
fi
|
|
1303
1435
|
VERSION="$("$PLIST_BUDDY" -c 'Print :CFBundleShortVersionString' "$CONTENTS/Info.plist")"
|
|
1304
1436
|
|
|
1305
1437
|
compute_release_publication_identity() {
|
|
@@ -1313,6 +1445,7 @@ compute_release_publication_identity() {
|
|
|
1313
1445
|
--component "release_sequence=$RELEASE_SEQUENCE"
|
|
1314
1446
|
--component "key_epoch=$KEY_EPOCH"
|
|
1315
1447
|
--component "expires_at_utc=$ENVELOPE_EXPIRES_AT_UTC"
|
|
1448
|
+
--component "variant=$VARIANT"
|
|
1316
1449
|
)
|
|
1317
1450
|
identity_arguments+=(--component "envelope_public_key_sha256=$ENVELOPE_PUBLIC_KEY_SHA256")
|
|
1318
1451
|
if [ "$RELEASE_SUBTYPE" = "initial-bootstrap" ]; then
|
|
@@ -1331,7 +1464,7 @@ compute_release_publication_identity() {
|
|
|
1331
1464
|
|
|
1332
1465
|
reserve_release_output() {
|
|
1333
1466
|
local release_set_basename reserved_output
|
|
1334
|
-
release_set_basename="
|
|
1467
|
+
release_set_basename="${APP_BASENAME}-${VERSION}-macos-${RELEASE_SUBTYPE}"
|
|
1335
1468
|
compute_release_publication_identity
|
|
1336
1469
|
RELEASE_OUTPUT_ROOT="$OUTPUT_BUILD_DIR"
|
|
1337
1470
|
RELEASE_FINAL_DIR="$RELEASE_OUTPUT_ROOT/${release_set_basename}.release"
|
|
@@ -1398,7 +1531,7 @@ reserve_release_output() {
|
|
|
1398
1531
|
RELEASE_STAGING_DIR="$($MKTEMP_EXECUTABLE -d "$RELEASE_OUTPUT_ROOT/.${release_set_basename}.staging.XXXXXX")"
|
|
1399
1532
|
"$CHMOD_EXECUTABLE" 0700 "$RELEASE_STAGING_DIR"
|
|
1400
1533
|
OUTPUT_BUILD_DIR="$RELEASE_STAGING_DIR"
|
|
1401
|
-
OUTPUT_APP_DIR="$OUTPUT_BUILD_DIR
|
|
1534
|
+
OUTPUT_APP_DIR="$OUTPUT_BUILD_DIR/$APP_BUNDLE_NAME"
|
|
1402
1535
|
}
|
|
1403
1536
|
|
|
1404
1537
|
if [ "$MODE" = "release" ]; then
|
|
@@ -1533,8 +1666,6 @@ run_signed_helper_contract() {
|
|
|
1533
1666
|
HOME="$contract_home"
|
|
1534
1667
|
PATH="/usr/bin:/bin:/usr/sbin:/sbin"
|
|
1535
1668
|
TMPDIR="$contract_home"
|
|
1536
|
-
HASNA_RECORDINGS_CLIENT_STORE="sqlite"
|
|
1537
|
-
RECORDINGS_CLIENT_STORE="sqlite"
|
|
1538
1669
|
HASNA_RECORDINGS_DB_PATH="$contract_home/recordings.db"
|
|
1539
1670
|
RECORDINGS_AUDIO_DIR="$contract_home/audio"
|
|
1540
1671
|
)
|
|
@@ -1586,6 +1717,7 @@ if [ "$MODE" != "debug" ]; then
|
|
|
1586
1717
|
--team-id "$EXPECTED_TEAM_ID" \
|
|
1587
1718
|
--package-root "$PACKAGE_ROOT" \
|
|
1588
1719
|
--artifact-policy "$ARTIFACT_POLICY" \
|
|
1720
|
+
--variant "$VARIANT" \
|
|
1589
1721
|
--approved-target "$APPROVED_TARGET" \
|
|
1590
1722
|
--approved-target-identity-kind "$APPROVED_TARGET_IDENTITY_KIND" \
|
|
1591
1723
|
--approved-target-identity-sha256 "$APPROVED_TARGET_IDENTITY_SHA256" \
|
|
@@ -1643,7 +1775,7 @@ run_codesign --verify --deep --strict --verbose=2 "$APP_DIR"
|
|
|
1643
1775
|
TMPDIR="$BUILD_WORK_DIR" \
|
|
1644
1776
|
SSH_CONNECTION="${SSH_CONNECTION:-}" \
|
|
1645
1777
|
${SMOKE_TEST_ENVIRONMENT[0]+"${SMOKE_TEST_ENVIRONMENT[@]}"} \
|
|
1646
|
-
"$BASH_EXECUTABLE" "$SMOKE_SCRIPT" "$APP_DIR" "$BUN_EXECUTABLE"
|
|
1778
|
+
"$BASH_EXECUTABLE" "$SMOKE_SCRIPT" "$APP_DIR" "$BUN_EXECUTABLE" --variant "$VARIANT"
|
|
1647
1779
|
|
|
1648
1780
|
publish_app_output() {
|
|
1649
1781
|
local source_tree_digest
|
|
@@ -1807,7 +1939,7 @@ publish_complete_release_set() {
|
|
|
1807
1939
|
RELEASE_DIRECTORY_PUBLISHED=1
|
|
1808
1940
|
RELEASE_STAGING_DIR=""
|
|
1809
1941
|
OUTPUT_BUILD_DIR="$RELEASE_FINAL_DIR"
|
|
1810
|
-
OUTPUT_APP_DIR="$OUTPUT_BUILD_DIR
|
|
1942
|
+
OUTPUT_APP_DIR="$OUTPUT_BUILD_DIR/$APP_BUNDLE_NAME"
|
|
1811
1943
|
run_bun "$SOURCE_PACKAGE_ROOT/scripts/macos_artifact.ts" complete-release-publication \
|
|
1812
1944
|
--destination "$RELEASE_FINAL_DIR" \
|
|
1813
1945
|
--reservation "$RELEASE_RESERVATION" \
|
|
@@ -1833,7 +1965,7 @@ if [ "$MODE" = "debug" ]; then
|
|
|
1833
1965
|
fi
|
|
1834
1966
|
|
|
1835
1967
|
if [ "$MODE" = "local" ]; then
|
|
1836
|
-
ARTIFACT_BASENAME="
|
|
1968
|
+
ARTIFACT_BASENAME="${APP_BASENAME}-${VERSION}-macos-${APPROVED_TARGET}-local-only"
|
|
1837
1969
|
FINAL_ARCHIVE="$OUTPUT_BUILD_DIR/${ARTIFACT_BASENAME}.zip"
|
|
1838
1970
|
FINAL_MANIFEST="$OUTPUT_BUILD_DIR/${ARTIFACT_BASENAME}.manifest.json"
|
|
1839
1971
|
"$RM_EXECUTABLE" -f "$FINAL_ARCHIVE" "$FINAL_MANIFEST"
|
|
@@ -1846,6 +1978,7 @@ if [ "$MODE" = "local" ]; then
|
|
|
1846
1978
|
--archive "$FINAL_ARCHIVE" \
|
|
1847
1979
|
--manifest "$FINAL_MANIFEST" \
|
|
1848
1980
|
--package-root "$PACKAGE_ROOT" \
|
|
1981
|
+
--variant "$VARIANT" \
|
|
1849
1982
|
--approved-target "$APPROVED_TARGET" \
|
|
1850
1983
|
--approved-target-identity-kind "$APPROVED_TARGET_IDENTITY_KIND" \
|
|
1851
1984
|
--approved-target-identity-sha256 "$APPROVED_TARGET_IDENTITY_SHA256" \
|
|
@@ -1859,8 +1992,8 @@ if [ "$MODE" = "local" ]; then
|
|
|
1859
1992
|
fi
|
|
1860
1993
|
|
|
1861
1994
|
verify_signed_code "$HELPERS/recordings" "Companion CLI"
|
|
1862
|
-
verify_signed_code "$APP_DIR" "
|
|
1863
|
-
ARTIFACT_BASENAME="
|
|
1995
|
+
verify_signed_code "$APP_DIR" "HasnaRecordings.app"
|
|
1996
|
+
ARTIFACT_BASENAME="${APP_BASENAME}-${VERSION}-macos-${RELEASE_SUBTYPE}"
|
|
1864
1997
|
NOTARY_ARCHIVE="$OUTPUT_BUILD_DIR/${ARTIFACT_BASENAME}-notarization.zip"
|
|
1865
1998
|
FINAL_ARCHIVE="$OUTPUT_BUILD_DIR/${ARTIFACT_BASENAME}.zip"
|
|
1866
1999
|
FINAL_MANIFEST="$OUTPUT_BUILD_DIR/${ARTIFACT_BASENAME}.manifest.json"
|
|
@@ -1911,7 +2044,7 @@ run_xcrun stapler validate "$APP_DIR"
|
|
|
1911
2044
|
run_release_sensitive_tool "$SPCTL_EXECUTABLE" --assess --type execute --verbose=2 "$APP_DIR"
|
|
1912
2045
|
run_release_sensitive_tool "$SYSPOLICY_CHECK_EXECUTABLE" distribution "$APP_DIR"
|
|
1913
2046
|
verify_signed_code "$HELPERS/recordings" "Companion CLI"
|
|
1914
|
-
verify_signed_code "$APP_DIR" "
|
|
2047
|
+
verify_signed_code "$APP_DIR" "HasnaRecordings.app"
|
|
1915
2048
|
run_codesign --verify --deep --strict --verbose=2 "$APP_DIR"
|
|
1916
2049
|
|
|
1917
2050
|
run_release_sensitive_tool "$DITTO_EXECUTABLE" -c -k --sequesterRsrc --keepParent "$APP_DIR" "$FINAL_ARCHIVE"
|
|
@@ -1923,6 +2056,7 @@ run_bun "$SOURCE_PACKAGE_ROOT/scripts/macos_artifact.ts" finalize \
|
|
|
1923
2056
|
--manifest "$FINAL_MANIFEST" \
|
|
1924
2057
|
--package-root "$PACKAGE_ROOT" \
|
|
1925
2058
|
--team-id "$EXPECTED_TEAM_ID" \
|
|
2059
|
+
--variant "$VARIANT" \
|
|
1926
2060
|
--notary-log "$NOTARY_LOG" \
|
|
1927
2061
|
--notary-submission-id "$NOTARY_ID" \
|
|
1928
2062
|
--submitted-archive-sha256 "$NOTARY_ARCHIVE_SHA256"
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export declare const RETIRED_DEPLOYMENT_MODES: readonly ["local", "self_hosted", "cloud", "remote", "hybrid"];
|
|
2
|
-
export type RetiredDeploymentMode = (typeof RETIRED_DEPLOYMENT_MODES)[number];
|
|
3
|
-
/** Fold case, surrounding space, and the `self-hosted`/`self_hosted` spelling split. */
|
|
4
|
-
export declare function normalizeModeToken(value: string): string;
|
|
5
|
-
/** The retired mode this value names, or null if it names something else. */
|
|
6
|
-
export declare function asRetiredDeploymentMode(value: string): RetiredDeploymentMode | null;
|
|
7
|
-
export interface RetiredModeReplacement {
|
|
8
|
-
/** The variable the caller should set instead. */
|
|
9
|
-
envKey: string;
|
|
10
|
-
/** Value that replaces `local` — the on-this-box arm. */
|
|
11
|
-
onBox: string;
|
|
12
|
-
/** Value that replaces `self_hosted` / `cloud` / `remote` / `hybrid`. */
|
|
13
|
-
offBox: string;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* The error a retired mode word must produce.
|
|
17
|
-
*
|
|
18
|
-
* It names three things a bare "unknown value" error does not: the variable that
|
|
19
|
-
* carried the retired word, the variable to set instead, and the exact value —
|
|
20
|
-
* because the operator reading this cannot be assumed to know the collapse
|
|
21
|
-
* happened.
|
|
22
|
-
*/
|
|
23
|
-
export declare function retiredDeploymentModeError(rawValue: string, sourceEnvKey: string, replacement: RetiredModeReplacement): Error;
|
|
24
|
-
//# sourceMappingURL=retired-deployment-modes.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"retired-deployment-modes.d.ts","sourceRoot":"","sources":["../../src/lib/retired-deployment-modes.ts"],"names":[],"mappings":"AA8BA,eAAO,MAAM,wBAAwB,gEAM3B,CAAC;AAEX,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9E,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,6EAA6E;AAC7E,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAKnF;AAED,MAAM,WAAW,sBAAsB;IACrC,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,sBAAsB,GAClC,KAAK,CASP"}
|