From db96494daf505527c98bafdf1e19e57d57028c83 Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Mon, 14 Apr 2025 14:25:19 +0200 Subject: [PATCH 1/4] Add a prefix to worktree so that cleanup lefovers from past deploy is possible --- src/publish/gh-pages/gh-pages.ts | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/publish/gh-pages/gh-pages.ts b/src/publish/gh-pages/gh-pages.ts index 3644aa22794..12f8c3849b8 100644 --- a/src/publish/gh-pages/gh-pages.ts +++ b/src/publish/gh-pages/gh-pages.ts @@ -4,7 +4,7 @@ * Copyright (C) 2020-2022 Posit Software, PBC */ -import { info } from "../../deno_ral/log.ts"; +import { debug, info } from "../../deno_ral/log.ts"; import { dirname, join, relative } from "../../deno_ral/path.ts"; import { copy } from "../../deno_ral/fs.ts"; import * as colors from "fmt/colors"; @@ -190,11 +190,33 @@ async function publish( ); // allocate worktree dir - const tempDir = Deno.makeTempDirSync({ dir: input }); + const tempDir = Deno.makeTempDirSync({ + dir: input, + prefix: ".quarto-publish-worktree-", + }); removeIfExists(tempDir); - const deployId = shortUuid(); + // cleaning up leftover by listing folder with prefix .quarto-publish-worktree- and calling git worktree rm on them + const worktreeDir = Deno.readDirSync(input); + for (const entry of worktreeDir) { + if ( + entry.isDirectory && entry.name.startsWith(".quarto-publish-worktree-") + ) { + debug( + `Cleaning up leftover worktree folder ${entry.name} from past deploys`, + ); + const worktreePath = join(input, entry.name); + await execProcess({ + cmd: ["git", "worktree", "remove", worktreePath], + cwd: input, + }); + removeIfExists(worktreePath); + } + } + // create worktree and deploy from it + const deployId = shortUuid(); + debug(`Deploying from worktree ${tempDir} with deployId ${deployId}`); await withWorktree(input, relative(input, tempDir), async () => { // copy output to tempdir and add .nojekyll (include deployId // in .nojekyll so we can poll for completed deployment) From 9abd4db03188fed1926baa8044fbf9a7b2513c2c Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Mon, 14 Apr 2025 14:43:04 +0200 Subject: [PATCH 2/4] use a temp context in .quarto scratch directory --- src/publish/gh-pages/gh-pages.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/publish/gh-pages/gh-pages.ts b/src/publish/gh-pages/gh-pages.ts index 12f8c3849b8..86f3e34a3d4 100644 --- a/src/publish/gh-pages/gh-pages.ts +++ b/src/publish/gh-pages/gh-pages.ts @@ -33,6 +33,8 @@ import { gitHubContextForPublish, verifyContext, } from "../common/git.ts"; +import { createTempContext } from "../../core/temp.ts"; +import { projectScratchPath } from "../../project/project-scratch.ts"; export const kGhpages = "gh-pages"; const kGhpagesDescription = "GitHub Pages"; @@ -190,25 +192,25 @@ async function publish( ); // allocate worktree dir - const tempDir = Deno.makeTempDirSync({ - dir: input, - prefix: ".quarto-publish-worktree-", - }); + const temp = createTempContext( + { prefix: "quarto-publish-worktree-", dir: projectScratchPath(input) }, + ); + const tempDir = temp.baseDir; removeIfExists(tempDir); // cleaning up leftover by listing folder with prefix .quarto-publish-worktree- and calling git worktree rm on them - const worktreeDir = Deno.readDirSync(input); + const worktreeDir = Deno.readDirSync(projectScratchPath(input)); for (const entry of worktreeDir) { if ( - entry.isDirectory && entry.name.startsWith(".quarto-publish-worktree-") + entry.isDirectory && entry.name.startsWith("quarto-publish-worktree-") ) { debug( `Cleaning up leftover worktree folder ${entry.name} from past deploys`, ); - const worktreePath = join(input, entry.name); + const worktreePath = join(projectScratchPath(input), entry.name); await execProcess({ cmd: ["git", "worktree", "remove", worktreePath], - cwd: input, + cwd: projectScratchPath(input), }); removeIfExists(worktreePath); } @@ -231,6 +233,7 @@ async function publish( ["push", "--force", "origin", "HEAD:gh-pages"], ]); }); + temp.cleanup(); info(""); // if this is the creation of gh-pages AND this is a user home/default site From 3cd211193efce46fe28d90ca7b3d0dea86ca9973 Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Mon, 14 Apr 2025 14:51:26 +0200 Subject: [PATCH 3/4] Avoid duplicating name --- src/publish/gh-pages/gh-pages.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/publish/gh-pages/gh-pages.ts b/src/publish/gh-pages/gh-pages.ts index 86f3e34a3d4..019faf8ab9d 100644 --- a/src/publish/gh-pages/gh-pages.ts +++ b/src/publish/gh-pages/gh-pages.ts @@ -191,9 +191,10 @@ async function publish( type === "site" ? target?.url : undefined, ); + const kPublishWorktreeDir = "quarto-publish-worktree-"; // allocate worktree dir const temp = createTempContext( - { prefix: "quarto-publish-worktree-", dir: projectScratchPath(input) }, + { prefix: kPublishWorktreeDir, dir: projectScratchPath(input) }, ); const tempDir = temp.baseDir; removeIfExists(tempDir); @@ -202,7 +203,7 @@ async function publish( const worktreeDir = Deno.readDirSync(projectScratchPath(input)); for (const entry of worktreeDir) { if ( - entry.isDirectory && entry.name.startsWith("quarto-publish-worktree-") + entry.isDirectory && entry.name.startsWith(kPublishWorktreeDir) ) { debug( `Cleaning up leftover worktree folder ${entry.name} from past deploys`, From 8b96af7f61b26532377a70f37c81d54ac87e6870 Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Mon, 14 Apr 2025 15:00:10 +0200 Subject: [PATCH 4/4] Add to changelog --- news/changelog-1.7.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/news/changelog-1.7.md b/news/changelog-1.7.md index 8554c5d4e16..9578926bd0c 100644 --- a/news/changelog-1.7.md +++ b/news/changelog-1.7.md @@ -162,6 +162,10 @@ All changes included in 1.7: - ([#12366](https://github.com/quarto-dev/quarto-cli/pull/12366)): Added Bulgarian translation for Quarto UI text (credit: @sakelariev) +## `quarto publish` + +- ([#9929](https://github.com/quarto-dev/quarto-cli/issues/9929)): `quarto publish gh-pages` will now clean previous worktree directory leftover from previous deploys. + ## Other Fixes and Improvements - A new folder `quarto-session-temp` can be created in `.quarto` to store temporary files created by Quarto during a rendering. Reminder: `.quarto` is for internal use of Quarto and should not be versioned (thus added to `.gitignore`).