fix: recover workspace publication failures

This commit is contained in:
2026-08-04 01:10:35 +02:00
parent f95a18ab0d
commit 2573d87a0e
5 changed files with 207 additions and 11 deletions
+32 -6
View File
@@ -172,10 +172,17 @@ export class GitWorkspaceRepository {
if (paths.length === 0 || paths.some((path) => !this.isRegistryArtifactPath(path))) {
throw new WorkspaceRegistryError("workspace_invalid", "Workspace repository path is invalid");
}
await this.git(["add", "--", ...paths]);
await this.git(["commit", "-m", message]);
await this.git(["push", "origin", `HEAD:${this.config.branch}`]);
return await this.status();
try {
await this.git(["add", "--", ...paths]);
await this.git(["commit", "-m", message], this.publicationIdentity());
await this.git(["push", "origin", `HEAD:${this.config.branch}`]);
return await this.status();
} catch (error) {
// A failed commit leaves staged/working changes; a failed push leaves an ahead commit.
// Restore the last fetched remote revision so the next refresh or explicit retry starts clean.
await this.restoreFailedPublication();
throw error;
}
}
private async clone(): Promise<void> {
@@ -223,12 +230,31 @@ export class GitWorkspaceRepository {
}
}
private async git(args: string[]): Promise<string> {
private publicationIdentity(): NodeJS.ProcessEnv {
return {
GIT_AUTHOR_NAME: this.config.gitAuthorName,
GIT_AUTHOR_EMAIL: this.config.gitAuthorEmail,
GIT_COMMITTER_NAME: this.config.gitAuthorName,
GIT_COMMITTER_EMAIL: this.config.gitAuthorEmail,
};
}
private async restoreFailedPublication(): Promise<void> {
try {
await this.git(["reset", "--hard", `refs/remotes/origin/${this.config.branch}`]);
await this.git(["clean", "-fd", "--", "workspaces", "workspace-docs"]);
} catch {
// Keep the original sanitized publish failure. A future refresh will surface any recovery
// problem without leaking the Git failure details through the API.
}
}
private async git(args: string[], env: NodeJS.ProcessEnv = {}): Promise<string> {
try {
const { stdout } = await execFileAsync(
"git",
["-c", `core.hooksPath=${this.hooksPath}`, ...args],
{ cwd: this.repoPath, env: { ...process.env, GIT_TERMINAL_PROMPT: "0" } },
{ cwd: this.repoPath, env: { ...process.env, GIT_TERMINAL_PROMPT: "0", ...env } },
);
return stdout;
} catch (error) {