2 Commits
v0.0.9 ... main

Author SHA1 Message Date
ac5ff6e375 chore(release): v0.0.10 2026-06-15 08:48:11 -04:00
ff0c257e57 feat: ignore missing gitea repo in provision 2026-06-15 08:47:55 -04:00
3 changed files with 42 additions and 10 deletions

View File

@@ -1,5 +1,13 @@
# Changelog # Changelog
## v0.0.10
[compare changes](https://gitea.websimple.com/pascalmartineau/wpop/compare/v0.0.9...v0.0.10)
### 🚀 Enhancements
- Ignore missing gitea repo in provision (ff0c257)
## v0.0.9 ## v0.0.9
[compare changes](https://gitea.websimple.com/pascalmartineau/wpop/compare/v0.0.8...v0.0.9) [compare changes](https://gitea.websimple.com/pascalmartineau/wpop/compare/v0.0.8...v0.0.9)

View File

@@ -1,6 +1,6 @@
{ {
"name": "@lewebsimple/wpop", "name": "@lewebsimple/wpop",
"version": "0.0.9", "version": "0.0.10",
"description": "WordPress operations CLI for Websimple projects.", "description": "WordPress operations CLI for Websimple projects.",
"license": "MIT", "license": "MIT",
"author": "Pascal Martineau <pascal@lewebsimple.ca>", "author": "Pascal Martineau <pascal@lewebsimple.ca>",

View File

@@ -28,6 +28,7 @@ type Derived = {
templateOwner: string; templateOwner: string;
templateRepo: string; templateRepo: string;
cloneUrl: string; cloneUrl: string;
templateCloneUrl: string;
}; };
type ProvisionReport = { type ProvisionReport = {
@@ -70,8 +71,8 @@ export async function provision(
throw new Error(`Local root path does not exist: ${env.WP_LOCAL_ROOT_PATH}`); throw new Error(`Local root path does not exist: ${env.WP_LOCAL_ROOT_PATH}`);
} }
await ensureGiteaRepo(context, env, slug, derived, report); const repoAvailable = await ensureGiteaRepo(context, env, slug, derived, report);
await ensureSiteDirectory(context, env, slug, derived, report); await ensureSiteDirectory(context, env, derived, repoAvailable, report);
await checkGitFreshness(context, derived.sitePath); await checkGitFreshness(context, derived.sitePath);
await ensureDatabase(context, derived.dbName, report); await ensureDatabase(context, derived.dbName, report);
await ensureCore(context, env, derived.sitePath, report); await ensureCore(context, env, derived.sitePath, report);
@@ -102,6 +103,7 @@ function resolveDerived(env: ProvisionEnv, slug: string): Derived {
templateOwner, templateOwner,
templateRepo, templateRepo,
cloneUrl: `ssh://${env.WPOP_GITEA_SSH_USER}@${host}:${env.WPOP_GITEA_SSH_PORT}/${env.WPOP_GITEA_OWNER}/${slug}.git`, cloneUrl: `ssh://${env.WPOP_GITEA_SSH_USER}@${host}:${env.WPOP_GITEA_SSH_PORT}/${env.WPOP_GITEA_OWNER}/${slug}.git`,
templateCloneUrl: `ssh://${env.WPOP_GITEA_SSH_USER}@${host}:${env.WPOP_GITEA_SSH_PORT}/${templateOwner}/${templateRepo}.git`,
}; };
} }
@@ -144,24 +146,30 @@ async function confirm(context: WPopContext, slug: string, derived: Derived): Pr
return Boolean(response.confirmed); return Boolean(response.confirmed);
} }
/**
* Ensures the per-site Gitea repo exists. Returns `true` when the repo is
* available to clone from (it already existed or was just created), `false`
* when the user declined creation — in which case the caller falls back to
* cloning the template directly so the local site is still provisioned.
*/
async function ensureGiteaRepo( async function ensureGiteaRepo(
context: WPopContext, context: WPopContext,
env: ProvisionEnv, env: ProvisionEnv,
slug: string, slug: string,
derived: Derived, derived: Derived,
report: ProvisionReport, report: ProvisionReport,
): Promise<void> { ): Promise<boolean> {
if (context.dryRun) { if (context.dryRun) {
consola.info( consola.info(
`[dry-run] Would ensure Gitea repo ${derived.owner}/${slug} exists (create from ${env.WPOP_GITEA_TEMPLATE} if missing)`, `[dry-run] Would ensure Gitea repo ${derived.owner}/${slug} exists (create from ${env.WPOP_GITEA_TEMPLATE} if missing)`,
); );
return; return true;
} }
const exists = await giteaRepoExists(env.giteaBaseUrl, env.giteaToken, derived.owner, slug); const exists = await giteaRepoExists(env.giteaBaseUrl, env.giteaToken, derived.owner, slug);
if (exists) { if (exists) {
consola.info(`Gitea repo ${derived.owner}/${slug} already exists`); consola.info(`Gitea repo ${derived.owner}/${slug} already exists`);
return; return true;
} }
if (!context.yes) { if (!context.yes) {
@@ -172,7 +180,11 @@ async function ensureGiteaRepo(
initial: true, initial: true,
}); });
if (!response.confirmed) { if (!response.confirmed) {
throw new Error(`Gitea repo ${derived.owner}/${slug} is required but was not created`); consola.warn(
`Skipping Gitea repo ${derived.owner}/${slug}; provisioning local site from template ${env.WPOP_GITEA_TEMPLATE}`,
);
report.steps.push("gitea:skip");
return false;
} }
} }
@@ -184,13 +196,14 @@ async function ensureGiteaRepo(
name: slug, name: slug,
}); });
report.steps.push("gitea:create"); report.steps.push("gitea:create");
return true;
} }
async function ensureSiteDirectory( async function ensureSiteDirectory(
context: WPopContext, context: WPopContext,
env: ProvisionEnv, env: ProvisionEnv,
slug: string,
derived: Derived, derived: Derived,
repoAvailable: boolean,
report: ProvisionReport, report: ProvisionReport,
): Promise<void> { ): Promise<void> {
if (!context.dryRun && existsSync(derived.sitePath)) { if (!context.dryRun && existsSync(derived.sitePath)) {
@@ -202,11 +215,22 @@ async function ensureSiteDirectory(
return; return;
} }
consola.info(`Cloning ${derived.cloneUrl} into ${derived.sitePath}`); const cloneUrl = repoAvailable ? derived.cloneUrl : derived.templateCloneUrl;
await run(context, "git", ["clone", derived.cloneUrl, derived.sitePath], { consola.info(`Cloning ${cloneUrl} into ${derived.sitePath}`);
await run(context, "git", ["clone", cloneUrl, derived.sitePath], {
cwd: env.WP_LOCAL_ROOT_PATH, cwd: env.WP_LOCAL_ROOT_PATH,
}); });
report.steps.push("git:clone"); report.steps.push("git:clone");
// When provisioning from the template (the per-site repo was not created),
// drop the origin remote so the clone is not tied to the template repo.
if (!repoAvailable) {
await run(context, "git", ["remote", "remove", "origin"], {
cwd: derived.sitePath,
reject: false,
});
report.steps.push("git:detach-template");
}
} }
async function checkGitFreshness(context: WPopContext, sitePath: string): Promise<void> { async function checkGitFreshness(context: WPopContext, sitePath: string): Promise<void> {