@ricsam/r5d-worker 0.0.46 → 0.0.47
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/cjs/main.cjs +245 -33
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/workspace-sync.cjs +619 -57
- package/dist/mjs/main.mjs +244 -34
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/workspace-sync.mjs +616 -56
- package/dist/types/main.d.ts +40 -3
- package/dist/types/workspace-sync.d.ts +30 -3
- package/package.json +1 -1
package/dist/mjs/main.mjs
CHANGED
|
@@ -21,7 +21,8 @@ import {
|
|
|
21
21
|
WORKSPACE_PERIODIC_SCAN_INTERVAL_MS,
|
|
22
22
|
WorkspaceSyncSingleFlight,
|
|
23
23
|
calculateWorkspaceDiffFingerprint,
|
|
24
|
-
synchronizeWorkspace
|
|
24
|
+
synchronizeWorkspace,
|
|
25
|
+
workspaceProjectsForSync
|
|
25
26
|
} from "./workspace-sync.mjs";
|
|
26
27
|
class WorkerServerUnavailableError extends Error {
|
|
27
28
|
name = "WorkerServerUnavailableError";
|
|
@@ -578,6 +579,14 @@ function validatePlanId(planId) {
|
|
|
578
579
|
throw new Error(`Invalid plan id from server: ${planId}`);
|
|
579
580
|
}
|
|
580
581
|
}
|
|
582
|
+
const NON_RECURSIVE_GIT_CONFIG_ARGS = [
|
|
583
|
+
"-c",
|
|
584
|
+
"submodule.recurse=false",
|
|
585
|
+
"-c",
|
|
586
|
+
"fetch.recurseSubmodules=false",
|
|
587
|
+
"-c",
|
|
588
|
+
"push.recurseSubmodules=false"
|
|
589
|
+
];
|
|
581
590
|
function gitExtraHeaderConfigKey(extraHeaderUrl) {
|
|
582
591
|
return `http.${normalizeBaseUrl(extraHeaderUrl)}/.extraHeader`;
|
|
583
592
|
}
|
|
@@ -585,10 +594,23 @@ function gitAuthArgs(auth) {
|
|
|
585
594
|
if (!auth) {
|
|
586
595
|
return [];
|
|
587
596
|
}
|
|
588
|
-
|
|
597
|
+
const scopedKey = gitExtraHeaderConfigKey(auth.extraHeaderUrl);
|
|
598
|
+
return ["-c", "http.extraHeader=", "-c", `${scopedKey}=`, "-c", `${scopedKey}=${auth.header}`];
|
|
599
|
+
}
|
|
600
|
+
const visibleCheckoutGitTestHarness = {
|
|
601
|
+
gitAuthArgs,
|
|
602
|
+
commandArgs: (args, auth) => ["git", ...NON_RECURSIVE_GIT_CONFIG_ARGS, ...gitAuthArgs(auth), ...args],
|
|
603
|
+
cloneArgs: (remoteUrl, branchPath) => ["clone", "--no-recurse-submodules", "--origin", "origin", remoteUrl, branchPath],
|
|
604
|
+
fetchArgs: (...args) => ["fetch", "--no-recurse-submodules", ...args]
|
|
605
|
+
};
|
|
606
|
+
function visibleCheckoutCloneArgs(remoteUrl, branchPath) {
|
|
607
|
+
return visibleCheckoutGitTestHarness.cloneArgs(remoteUrl, branchPath);
|
|
608
|
+
}
|
|
609
|
+
function visibleCheckoutFetchArgs(...args) {
|
|
610
|
+
return visibleCheckoutGitTestHarness.fetchArgs(...args);
|
|
589
611
|
}
|
|
590
612
|
function runGit(args, options = {}) {
|
|
591
|
-
const command =
|
|
613
|
+
const command = visibleCheckoutGitTestHarness.commandArgs(args, options.auth);
|
|
592
614
|
const result = Bun.spawnSync(command, {
|
|
593
615
|
cwd: options.cwd,
|
|
594
616
|
stdout: "pipe",
|
|
@@ -732,8 +754,28 @@ function resolveWorkerFilePath(branchPath, inputPath, builtInPaths) {
|
|
|
732
754
|
function fallbackInternalRemoteUrl(baseUrl, projectId) {
|
|
733
755
|
return new URL(`/git/${projectId}.git`, baseUrl).toString();
|
|
734
756
|
}
|
|
735
|
-
function
|
|
736
|
-
|
|
757
|
+
function visibleCheckoutRemoteFor(input) {
|
|
758
|
+
const canonicalCheckout = input.manifest?.canonicalCheckouts?.find((checkout) => checkout.branchName === input.branchName);
|
|
759
|
+
const isCanonicalManifestBranch = Boolean(canonicalCheckout);
|
|
760
|
+
const usesCanonicalRemote = isCanonicalManifestBranch || !input.manifest?.repoHttpUrl;
|
|
761
|
+
if (usesCanonicalRemote) {
|
|
762
|
+
return {
|
|
763
|
+
remoteUrl: fallbackInternalRemoteUrl(input.baseUrl, input.projectId),
|
|
764
|
+
authHeader: `Authorization: Bearer ${input.token}`,
|
|
765
|
+
persistAuth: false,
|
|
766
|
+
reconcileExistingOrigin: isCanonicalManifestBranch,
|
|
767
|
+
requireRemoteBranch: isCanonicalManifestBranch,
|
|
768
|
+
requiredBaseCommit: canonicalCheckout?.scaffoldCommitHash ?? null
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
return {
|
|
772
|
+
remoteUrl: input.manifest?.repoHttpUrl ?? fallbackInternalRemoteUrl(input.baseUrl, input.projectId),
|
|
773
|
+
authHeader: input.manifest?.repoAuthHeader ?? null,
|
|
774
|
+
persistAuth: true,
|
|
775
|
+
reconcileExistingOrigin: Boolean(input.manifest?.repoHttpUrl),
|
|
776
|
+
requireRemoteBranch: false,
|
|
777
|
+
requiredBaseCommit: null
|
|
778
|
+
};
|
|
737
779
|
}
|
|
738
780
|
function gitExtraHeaderUrlForRemote(remoteUrl) {
|
|
739
781
|
try {
|
|
@@ -762,6 +804,10 @@ function ensureOriginRemote(branchPath, remoteUrl) {
|
|
|
762
804
|
runGit(["remote", "add", "origin", remoteUrl], { cwd: branchPath });
|
|
763
805
|
}
|
|
764
806
|
}
|
|
807
|
+
function originRemoteUrl(branchPath) {
|
|
808
|
+
if (!tryGit(["remote", "get-url", "origin"], { cwd: branchPath })) return null;
|
|
809
|
+
return runGit(["remote", "get-url", "origin"], { cwd: branchPath });
|
|
810
|
+
}
|
|
765
811
|
function shellQuote(value) {
|
|
766
812
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
767
813
|
}
|
|
@@ -830,6 +876,18 @@ function configureVisibleGitHubAuth(branchPath, remoteUrl, authHeader) {
|
|
|
830
876
|
}
|
|
831
877
|
runGit(["config", `${gitExtraHeaderConfigKey(gitExtraHeaderUrlForRemote(remoteUrl))}`, authHeader], { cwd: branchPath });
|
|
832
878
|
}
|
|
879
|
+
function clearVisibleGitAuthentication(branchPath) {
|
|
880
|
+
let extraHeaderKeys = [];
|
|
881
|
+
try {
|
|
882
|
+
extraHeaderKeys = runGit(["config", "--local", "--name-only", "--get-regexp", "^http\\..*extraheader$"], { cwd: branchPath }).split(/\r?\n/).filter(Boolean);
|
|
883
|
+
} catch {
|
|
884
|
+
}
|
|
885
|
+
for (const key of extraHeaderKeys) {
|
|
886
|
+
tryGit(["config", "--local", "--unset-all", key], { cwd: branchPath });
|
|
887
|
+
}
|
|
888
|
+
runGit(["config", "--local", "--replace-all", "credential.helper", ""], { cwd: branchPath });
|
|
889
|
+
tryGit(["config", "--local", "--unset-all", "credential.useHttpPath"], { cwd: branchPath });
|
|
890
|
+
}
|
|
833
891
|
function dockerConfigPath() {
|
|
834
892
|
return path.join(os.homedir(), ".docker", "config.json");
|
|
835
893
|
}
|
|
@@ -918,18 +976,58 @@ function checkoutVisibleBranch(input) {
|
|
|
918
976
|
});
|
|
919
977
|
const clean = !hasWorktreeChanges(input.branchPath);
|
|
920
978
|
if (remoteBranchExists && clean) {
|
|
921
|
-
runGit(["checkout", "-B", input.branchName, `origin/${input.branchName}`], {
|
|
979
|
+
runGit(["checkout", "--no-recurse-submodules", "-B", input.branchName, `origin/${input.branchName}`], {
|
|
980
|
+
cwd: input.branchPath
|
|
981
|
+
});
|
|
922
982
|
return;
|
|
923
983
|
}
|
|
924
984
|
if (branchExists) {
|
|
925
|
-
runGit(["checkout", input.branchName], { cwd: input.branchPath });
|
|
985
|
+
runGit(["checkout", "--no-recurse-submodules", input.branchName], { cwd: input.branchPath });
|
|
926
986
|
return;
|
|
927
987
|
}
|
|
928
988
|
if (defaultRemoteExists) {
|
|
929
|
-
runGit(["checkout", "-B", input.branchName, `origin/${input.defaultBranch}`], {
|
|
989
|
+
runGit(["checkout", "--no-recurse-submodules", "-B", input.branchName, `origin/${input.defaultBranch}`], {
|
|
990
|
+
cwd: input.branchPath
|
|
991
|
+
});
|
|
930
992
|
return;
|
|
931
993
|
}
|
|
932
|
-
runGit(["checkout", "-B", input.branchName], { cwd: input.branchPath });
|
|
994
|
+
runGit(["checkout", "--no-recurse-submodules", "-B", input.branchName], { cwd: input.branchPath });
|
|
995
|
+
}
|
|
996
|
+
function migrateExistingCheckoutToRequiredRemote(input) {
|
|
997
|
+
if (originRemoteUrl(input.branchPath) === input.remoteUrl) return;
|
|
998
|
+
if (hasWorktreeChanges(input.branchPath)) {
|
|
999
|
+
throw new Error(`Cannot migrate dirty checkout for ${input.branchName} to its canonical remote`);
|
|
1000
|
+
}
|
|
1001
|
+
runGit(
|
|
1002
|
+
visibleCheckoutFetchArgs("--no-tags", input.remoteUrl, `+refs/heads/${input.branchName}:refs/remotes/origin/${input.branchName}`),
|
|
1003
|
+
{
|
|
1004
|
+
cwd: input.branchPath,
|
|
1005
|
+
auth: input.remoteAuth
|
|
1006
|
+
}
|
|
1007
|
+
);
|
|
1008
|
+
const canonicalRemoteRef = `refs/remotes/origin/${input.branchName}`;
|
|
1009
|
+
if (!tryGit(["show-ref", "--verify", "--quiet", canonicalRemoteRef], { cwd: input.branchPath })) {
|
|
1010
|
+
throw new Error(`Canonical branch ${input.branchName} is unavailable during checkout migration`);
|
|
1011
|
+
}
|
|
1012
|
+
if (input.requiredBaseCommit && (!tryGit(["cat-file", "-e", `${input.requiredBaseCommit}^{commit}`], { cwd: input.branchPath }) || !tryGit(["merge-base", "--is-ancestor", input.requiredBaseCommit, canonicalRemoteRef], { cwd: input.branchPath }))) {
|
|
1013
|
+
throw new Error(`Canonical branch ${input.branchName} is not derived from required scaffold ${input.requiredBaseCommit}`);
|
|
1014
|
+
}
|
|
1015
|
+
if (tryGit(["rev-parse", "--verify", "HEAD"], { cwd: input.branchPath })) {
|
|
1016
|
+
const previousHead = runGit(["rev-parse", "HEAD"], { cwd: input.branchPath });
|
|
1017
|
+
runGit(["update-ref", `refs/r5d/pre-canonical-checkout/${previousHead}`, previousHead], { cwd: input.branchPath });
|
|
1018
|
+
}
|
|
1019
|
+
ensureOriginRemote(input.branchPath, input.remoteUrl);
|
|
1020
|
+
runGit(["checkout", "--no-recurse-submodules", "-B", input.branchName, `origin/${input.branchName}`], {
|
|
1021
|
+
cwd: input.branchPath
|
|
1022
|
+
});
|
|
1023
|
+
}
|
|
1024
|
+
function assertCheckoutDerivedFromRequiredBase(input) {
|
|
1025
|
+
const remoteRevision = `refs/remotes/origin/${input.branchName}`;
|
|
1026
|
+
for (const revision of [remoteRevision, "HEAD"]) {
|
|
1027
|
+
if (!tryGit(["cat-file", "-e", `${input.requiredBaseCommit}^{commit}`], { cwd: input.branchPath }) || !tryGit(["merge-base", "--is-ancestor", input.requiredBaseCommit, revision], { cwd: input.branchPath })) {
|
|
1028
|
+
throw new Error(`Canonical checkout ${input.branchName} is not derived from required scaffold ${input.requiredBaseCommit}`);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
933
1031
|
}
|
|
934
1032
|
function ensureVisibleGitCheckout(input) {
|
|
935
1033
|
validateBranchName(input.branchName);
|
|
@@ -939,40 +1037,114 @@ function ensureVisibleGitCheckout(input) {
|
|
|
939
1037
|
if (createdCheckout) {
|
|
940
1038
|
fs.rmSync(branchPath, { recursive: true, force: true });
|
|
941
1039
|
fs.mkdirSync(path.dirname(branchPath), { recursive: true });
|
|
942
|
-
|
|
1040
|
+
const cloned = tryGit(visibleCheckoutCloneArgs(input.remoteUrl, branchPath), {
|
|
1041
|
+
auth: input.remoteAuth
|
|
1042
|
+
});
|
|
1043
|
+
if (!cloned && input.requireRemoteBranch) {
|
|
1044
|
+
fs.rmSync(branchPath, { recursive: true, force: true });
|
|
1045
|
+
throw new Error(`Failed to clone canonical checkout for branch ${input.branchName}`);
|
|
1046
|
+
}
|
|
1047
|
+
if (!cloned) {
|
|
943
1048
|
fs.mkdirSync(branchPath, { recursive: true });
|
|
944
1049
|
runGit(["init"], { cwd: branchPath });
|
|
945
1050
|
}
|
|
946
|
-
ensureOriginRemote(branchPath, input.
|
|
947
|
-
|
|
1051
|
+
ensureOriginRemote(branchPath, input.remoteUrl);
|
|
1052
|
+
if (input.clearPersistentAuth) clearVisibleGitAuthentication(branchPath);
|
|
1053
|
+
else configureVisibleGitHubAuth(branchPath, input.remoteUrl, input.persistentAuthHeader);
|
|
948
1054
|
configureVisibleGitIdentity(branchPath, visibleGitIdentity, runGit);
|
|
949
|
-
tryGit(
|
|
1055
|
+
tryGit(visibleCheckoutFetchArgs("origin", "--prune"), { cwd: branchPath, auth: input.remoteAuth });
|
|
1056
|
+
if (input.requireRemoteBranch && !tryGit(["show-ref", "--verify", "--quiet", `refs/remotes/origin/${input.branchName}`], { cwd: branchPath })) {
|
|
1057
|
+
fs.rmSync(branchPath, { recursive: true, force: true });
|
|
1058
|
+
throw new Error(`Canonical branch ${input.branchName} is unavailable after clone`);
|
|
1059
|
+
}
|
|
950
1060
|
checkoutVisibleBranch({ branchPath, branchName: input.branchName, defaultBranch: input.defaultBranch });
|
|
1061
|
+
if (input.requiredBaseCommit) {
|
|
1062
|
+
try {
|
|
1063
|
+
assertCheckoutDerivedFromRequiredBase({
|
|
1064
|
+
branchPath,
|
|
1065
|
+
branchName: input.branchName,
|
|
1066
|
+
requiredBaseCommit: input.requiredBaseCommit
|
|
1067
|
+
});
|
|
1068
|
+
} catch (error) {
|
|
1069
|
+
fs.rmSync(branchPath, { recursive: true, force: true });
|
|
1070
|
+
throw error;
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
951
1073
|
return branchPath;
|
|
952
1074
|
}
|
|
1075
|
+
if (input.requireRemoteBranch) {
|
|
1076
|
+
if (input.allowRequiredRemoteMigration === false && originRemoteUrl(branchPath) !== input.remoteUrl) {
|
|
1077
|
+
throw new Error(`Canonical checkout ${input.branchName} no longer uses its required remote`);
|
|
1078
|
+
}
|
|
1079
|
+
migrateExistingCheckoutToRequiredRemote({
|
|
1080
|
+
branchPath,
|
|
1081
|
+
branchName: input.branchName,
|
|
1082
|
+
remoteUrl: input.remoteUrl,
|
|
1083
|
+
remoteAuth: input.remoteAuth,
|
|
1084
|
+
requiredBaseCommit: input.requiredBaseCommit
|
|
1085
|
+
});
|
|
1086
|
+
runGit(
|
|
1087
|
+
visibleCheckoutFetchArgs("--no-tags", input.remoteUrl, `+refs/heads/${input.branchName}:refs/remotes/origin/${input.branchName}`),
|
|
1088
|
+
{
|
|
1089
|
+
cwd: branchPath,
|
|
1090
|
+
auth: input.remoteAuth
|
|
1091
|
+
}
|
|
1092
|
+
);
|
|
1093
|
+
}
|
|
953
1094
|
if (input.reconcileExistingOrigin) {
|
|
954
|
-
ensureOriginRemote(branchPath, input.
|
|
1095
|
+
ensureOriginRemote(branchPath, input.remoteUrl);
|
|
1096
|
+
}
|
|
1097
|
+
if (input.requireRemoteBranch && !tryGit(["show-ref", "--verify", "--quiet", `refs/remotes/origin/${input.branchName}`], { cwd: branchPath })) {
|
|
1098
|
+
throw new Error(`Existing checkout for ${input.branchName} does not contain its canonical remote branch`);
|
|
1099
|
+
}
|
|
1100
|
+
if (input.requiredBaseCommit) {
|
|
1101
|
+
assertCheckoutDerivedFromRequiredBase({
|
|
1102
|
+
branchPath,
|
|
1103
|
+
branchName: input.branchName,
|
|
1104
|
+
requiredBaseCommit: input.requiredBaseCommit
|
|
1105
|
+
});
|
|
955
1106
|
}
|
|
956
|
-
|
|
1107
|
+
if (input.clearPersistentAuth) clearVisibleGitAuthentication(branchPath);
|
|
1108
|
+
else configureVisibleGitHubAuth(branchPath, input.remoteUrl, input.persistentAuthHeader);
|
|
957
1109
|
configureVisibleGitIdentity(branchPath, visibleGitIdentity, runGit);
|
|
958
1110
|
return branchPath;
|
|
959
1111
|
}
|
|
960
1112
|
function ensureBranchWorkspace(input) {
|
|
961
1113
|
const defaultBranch = input.manifest?.defaultBranch || "main";
|
|
962
|
-
const
|
|
963
|
-
const githubAuth = gitAuthForRemote(githubRemoteUrl, input.manifest?.repoAuthHeader);
|
|
1114
|
+
const remote = visibleCheckoutRemoteFor(input);
|
|
964
1115
|
return {
|
|
965
1116
|
branchPath: ensureVisibleGitCheckout({
|
|
966
1117
|
projectRoot: input.projectRoot,
|
|
967
1118
|
branchName: input.branchName,
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
1119
|
+
remoteUrl: remote.remoteUrl,
|
|
1120
|
+
remoteAuth: gitAuthForRemote(remote.remoteUrl, remote.authHeader),
|
|
1121
|
+
persistentAuthHeader: remote.persistAuth ? remote.authHeader : null,
|
|
971
1122
|
defaultBranch,
|
|
972
|
-
reconcileExistingOrigin:
|
|
1123
|
+
reconcileExistingOrigin: remote.reconcileExistingOrigin,
|
|
1124
|
+
requireRemoteBranch: remote.requireRemoteBranch,
|
|
1125
|
+
requiredBaseCommit: remote.requiredBaseCommit,
|
|
1126
|
+
clearPersistentAuth: !remote.persistAuth
|
|
973
1127
|
})
|
|
974
1128
|
};
|
|
975
1129
|
}
|
|
1130
|
+
function workspaceSyncCheckoutTargets(input) {
|
|
1131
|
+
const selected = /* @__PURE__ */ new Map();
|
|
1132
|
+
const add = (target) => {
|
|
1133
|
+
selected.set(`${target.projectId}\0${target.branchName}`, target);
|
|
1134
|
+
};
|
|
1135
|
+
if (input.canonicalCheckoutOnly) {
|
|
1136
|
+
add(input.canonicalCheckoutOnly);
|
|
1137
|
+
} else if (input.includeAllManifestCheckouts) {
|
|
1138
|
+
for (const project of input.projects) {
|
|
1139
|
+
for (const branchName of project.branches) add({ projectId: project.projectId, branchName });
|
|
1140
|
+
}
|
|
1141
|
+
} else {
|
|
1142
|
+
for (const target of input.pendingTargets) add(target);
|
|
1143
|
+
}
|
|
1144
|
+
return [...selected.values()].sort(
|
|
1145
|
+
(left, right) => left.projectId.localeCompare(right.projectId) || left.branchName.localeCompare(right.branchName)
|
|
1146
|
+
);
|
|
1147
|
+
}
|
|
976
1148
|
function resolveCommandCwd(branchPath, cwd) {
|
|
977
1149
|
if (!cwd) {
|
|
978
1150
|
return branchPath;
|
|
@@ -2196,6 +2368,7 @@ async function startWorker(options) {
|
|
|
2196
2368
|
let reloadAfterClose = false;
|
|
2197
2369
|
const workspaceSyncInput = (trigger, overrides = {}) => {
|
|
2198
2370
|
if (!workspaceRemoteUrl) throw new Error("Worker workspace manifest has not been received");
|
|
2371
|
+
const projects = workspaceProjectsForSync([...manifestByProjectId.values()], trigger);
|
|
2199
2372
|
return {
|
|
2200
2373
|
workerLabel: label,
|
|
2201
2374
|
remoteUrl: workspaceRemoteUrl,
|
|
@@ -2203,7 +2376,7 @@ async function startWorker(options) {
|
|
|
2203
2376
|
projectsRoot,
|
|
2204
2377
|
plansRoot: planRoot,
|
|
2205
2378
|
shadowRoot: workspaceShadowRoot,
|
|
2206
|
-
projects
|
|
2379
|
+
projects,
|
|
2207
2380
|
trigger,
|
|
2208
2381
|
...overrides
|
|
2209
2382
|
};
|
|
@@ -2215,7 +2388,7 @@ async function startWorker(options) {
|
|
|
2215
2388
|
const allManifestCheckouts = () => [...manifestByProjectId.values()].flatMap(
|
|
2216
2389
|
(manifest) => manifest.branches.map((branchName) => ({ projectId: manifest.projectId, branchName }))
|
|
2217
2390
|
);
|
|
2218
|
-
const ensureVisibleWorkspaceCheckouts = (targets) => {
|
|
2391
|
+
const ensureVisibleWorkspaceCheckouts = (targets, options2 = {}) => {
|
|
2219
2392
|
const created = [];
|
|
2220
2393
|
for (const target of targets) {
|
|
2221
2394
|
const manifest = manifestByProjectId.get(target.projectId);
|
|
@@ -2227,15 +2400,25 @@ async function startWorker(options) {
|
|
|
2227
2400
|
const projectRoot = projectRootFor(projectsRoot, manifest.projectId, manifestByProjectId);
|
|
2228
2401
|
const branchPath = path.join(projectRoot, target.branchName);
|
|
2229
2402
|
const existed = hasNormalVisibleGitDir(branchPath);
|
|
2230
|
-
const
|
|
2403
|
+
const remote = visibleCheckoutRemoteFor({
|
|
2404
|
+
baseUrl,
|
|
2405
|
+
token,
|
|
2406
|
+
projectId: manifest.projectId,
|
|
2407
|
+
branchName: target.branchName,
|
|
2408
|
+
manifest
|
|
2409
|
+
});
|
|
2231
2410
|
ensureVisibleGitCheckout({
|
|
2232
2411
|
projectRoot,
|
|
2233
2412
|
branchName: target.branchName,
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2413
|
+
remoteUrl: remote.remoteUrl,
|
|
2414
|
+
remoteAuth: gitAuthForRemote(remote.remoteUrl, remote.authHeader),
|
|
2415
|
+
persistentAuthHeader: remote.persistAuth ? remote.authHeader : null,
|
|
2237
2416
|
defaultBranch: manifest.defaultBranch || "main",
|
|
2238
|
-
reconcileExistingOrigin:
|
|
2417
|
+
reconcileExistingOrigin: remote.reconcileExistingOrigin,
|
|
2418
|
+
requireRemoteBranch: remote.requireRemoteBranch,
|
|
2419
|
+
requiredBaseCommit: remote.requiredBaseCommit,
|
|
2420
|
+
allowRequiredRemoteMigration: !(options2.strictCanonicalRevalidation && remote.requireRemoteBranch),
|
|
2421
|
+
clearPersistentAuth: !remote.persistAuth
|
|
2239
2422
|
});
|
|
2240
2423
|
if (!existed) created.push(target);
|
|
2241
2424
|
}
|
|
@@ -2247,15 +2430,30 @@ async function startWorker(options) {
|
|
|
2247
2430
|
let pendingTargets = [];
|
|
2248
2431
|
const result = await workspaceSyncSingleFlight.runPrepared(() => {
|
|
2249
2432
|
const shouldEnsureCheckouts = !overrides.skipVisibleMirror && !overrides.resetToCanonical;
|
|
2433
|
+
const syncProjects = workspaceProjectsForSync([...manifestByProjectId.values()], trigger);
|
|
2434
|
+
const allowedCheckoutKeys = new Set(
|
|
2435
|
+
syncProjects.flatMap((project) => project.branches.map((branchName) => manifestCheckoutKey(project.projectId, branchName)))
|
|
2436
|
+
);
|
|
2437
|
+
const scopedPendingTargets = [...pendingManifestCheckouts.values()].filter(
|
|
2438
|
+
(target) => allowedCheckoutKeys.has(manifestCheckoutKey(target.projectId, target.branchName))
|
|
2439
|
+
);
|
|
2250
2440
|
let checkoutTargets = [];
|
|
2251
2441
|
if (shouldEnsureCheckouts) {
|
|
2252
|
-
checkoutTargets =
|
|
2442
|
+
checkoutTargets = workspaceSyncCheckoutTargets({
|
|
2443
|
+
projects: syncProjects,
|
|
2444
|
+
pendingTargets: scopedPendingTargets,
|
|
2445
|
+
includeAllManifestCheckouts: trigger.type === "connect",
|
|
2446
|
+
...trigger.canonicalCheckoutOnly && trigger.projectId && trigger.branchName ? { canonicalCheckoutOnly: { projectId: trigger.projectId, branchName: trigger.branchName } } : {}
|
|
2447
|
+
});
|
|
2253
2448
|
}
|
|
2254
|
-
pendingTargets = shouldEnsureCheckouts ?
|
|
2255
|
-
const createdCheckouts = ensureVisibleWorkspaceCheckouts(checkoutTargets
|
|
2449
|
+
pendingTargets = shouldEnsureCheckouts ? scopedPendingTargets : [];
|
|
2450
|
+
const createdCheckouts = ensureVisibleWorkspaceCheckouts(checkoutTargets, {
|
|
2451
|
+
strictCanonicalRevalidation: true
|
|
2452
|
+
});
|
|
2256
2453
|
const newVisibleCheckoutByKey = /* @__PURE__ */ new Map();
|
|
2257
2454
|
for (const target of [...overrides.newVisibleCheckouts ?? [], ...createdCheckouts, ...pendingTargets]) {
|
|
2258
|
-
|
|
2455
|
+
const key = manifestCheckoutKey(target.projectId, target.branchName);
|
|
2456
|
+
if (allowedCheckoutKeys.has(key)) newVisibleCheckoutByKey.set(key, target);
|
|
2259
2457
|
}
|
|
2260
2458
|
const newVisibleCheckouts = [...newVisibleCheckoutByKey.values()];
|
|
2261
2459
|
return workspaceSyncInput(trigger, {
|
|
@@ -2331,7 +2529,8 @@ async function startWorker(options) {
|
|
|
2331
2529
|
version: getWorkerVersion(),
|
|
2332
2530
|
r5dctlVersion: readInstalledCliVersion("r5dctl"),
|
|
2333
2531
|
capabilities: {
|
|
2334
|
-
updateClis: true
|
|
2532
|
+
updateClis: true,
|
|
2533
|
+
canonicalResolverCheckout: true
|
|
2335
2534
|
},
|
|
2336
2535
|
projectRoot: projectsRoot,
|
|
2337
2536
|
artifactRoot,
|
|
@@ -2391,7 +2590,15 @@ async function startWorker(options) {
|
|
|
2391
2590
|
if (!workspaceRemoteUrl || activeWorkspaceIncidentId || cliUpdateInProgress || periodicWorkspaceScanInFlight) return;
|
|
2392
2591
|
periodicWorkspaceScanInFlight = true;
|
|
2393
2592
|
void (async () => {
|
|
2394
|
-
|
|
2593
|
+
const genericCheckoutKeys = new Set(
|
|
2594
|
+
workspaceProjectsForSync([...manifestByProjectId.values()], { type: "periodic" }).flatMap(
|
|
2595
|
+
(project) => project.branches.map((branchName) => manifestCheckoutKey(project.projectId, branchName))
|
|
2596
|
+
)
|
|
2597
|
+
);
|
|
2598
|
+
const hasPendingGenericCheckout = [...pendingManifestCheckouts.values()].some(
|
|
2599
|
+
(target) => genericCheckoutKeys.has(manifestCheckoutKey(target.projectId, target.branchName))
|
|
2600
|
+
);
|
|
2601
|
+
if (hasPendingGenericCheckout) {
|
|
2395
2602
|
previousPeriodicFingerprint = null;
|
|
2396
2603
|
await runRequestedWorkspaceSync(crypto.randomUUID(), {
|
|
2397
2604
|
type: "periodic",
|
|
@@ -2808,5 +3015,8 @@ export {
|
|
|
2808
3015
|
resolveHostShell,
|
|
2809
3016
|
resolveWorkerFilePath,
|
|
2810
3017
|
syncSessionArtifacts,
|
|
3018
|
+
visibleCheckoutGitTestHarness,
|
|
3019
|
+
visibleCheckoutRemoteFor,
|
|
3020
|
+
workspaceSyncCheckoutTargets,
|
|
2811
3021
|
writeWorkerTextFile
|
|
2812
3022
|
};
|
package/dist/mjs/package.json
CHANGED