diff --git a/baker/BuildkiteTrigger.ts b/baker/BuildkiteTrigger.ts index 72a09250476..4cf78464d9b 100644 --- a/baker/BuildkiteTrigger.ts +++ b/baker/BuildkiteTrigger.ts @@ -4,6 +4,19 @@ import { BUILDKITE_BRANCH, } from "../settings/serverSettings.js" +type BuildState = + | "running" + | "scheduled" + | "passed" + | "failing" + | "failed" + | "blocked" + | "canceled" + | "canceling" + | "skipped" + | "not_run" + | "finished" + export class BuildkiteTrigger { private organizationSlug = "our-world-in-data" private pipelineSlug = BUILDKITE_DEPLOY_CONTENT_PIPELINE_SLUG @@ -59,10 +72,14 @@ export class BuildkiteTrigger { Authorization: `Bearer ${BUILDKITE_API_ACCESS_TOKEN}`, } - let status = "" + let state: BuildState = "scheduled" + + while ( + ["running", "scheduled", "canceling", "failing"].includes(state) + ) { + // Wait for 10 seconds + await new Promise((res) => setTimeout(res, 10000)) - // Poll the status every 10 seconds (or your preferred interval) - while (status !== "passed" && status !== "failed") { const response = await fetch(url, { method: "GET", headers: headers, @@ -73,18 +90,13 @@ export class BuildkiteTrigger { } const buildData = await response.json() - status = buildData.state - - if (status !== "passed" && status !== "failed") { - await new Promise((res) => setTimeout(res, 10000)) // Wait for 10 seconds - } + state = buildData.state } - if (status === "passed") { - return - } else { + if (!["passed", "skipped", "canceled", "finished"].includes(state)) { + // failing states: failed, blocked, not_run throw new Error( - `Build failed with status "${status}". See Buildkite for details.` + `Build ${buildNumber} failed with state "${state}". See Buildkite for details.` ) } } diff --git a/baker/DeployUtils.ts b/baker/DeployUtils.ts index fa902a4d183..77370b690ed 100644 --- a/baker/DeployUtils.ts +++ b/baker/DeployUtils.ts @@ -2,8 +2,14 @@ import fs from "fs-extra" import { BuildkiteTrigger } from "../baker/BuildkiteTrigger.js" import { logErrorAndMaybeSendToBugsnag, warn } from "../serverUtils/errorLog.js" import { DeployQueueServer } from "./DeployQueueServer.js" -import { BUILDKITE_API_ACCESS_TOKEN } from "../settings/serverSettings.js" -import { DeployChange } from "@ourworldindata/utils" +import { + BAKED_SITE_DIR, + BAKED_BASE_URL, + BUILDKITE_API_ACCESS_TOKEN, +} from "../settings/serverSettings.js" +import { DeployChange, OwidGdocPublished } from "@ourworldindata/utils" +import { Gdoc } from "../db/model/Gdoc/Gdoc.js" +import { SiteBaker } from "../baker/SiteBaker.js" const deployQueueServer = new DeployQueueServer() @@ -31,20 +37,34 @@ const triggerBakeAndDeploy = async ( ) => { message = message ?? (await defaultCommitMessage()) - // co-deploy to Buildkite + // deploy to Buildkite if we're on master and BUILDKITE_API_ACCESS_TOKEN is set if (BUILDKITE_API_ACCESS_TOKEN) { const buildkite = new BuildkiteTrigger() - // once we fully switch to baking on buildkite, we should await this if (lightningQueue?.length) { - buildkite + await buildkite .runLightningBuild( message!, lightningQueue.map((change) => change.slug!) ) .catch(logErrorAndMaybeSendToBugsnag) } else { - // once we fully switch to baking on buildkite, we should await this - buildkite.runFullBuild(message).catch(logErrorAndMaybeSendToBugsnag) + await buildkite + .runFullBuild(message) + .catch(logErrorAndMaybeSendToBugsnag) + } + } else { + // otherwise, bake locally. This is used for local development or staging servers + const baker = new SiteBaker(BAKED_SITE_DIR, BAKED_BASE_URL) + if (lightningQueue?.length) { + for (const change of lightningQueue) { + const gdoc = (await Gdoc.findOneByOrFail({ + published: true, + slug: change.slug, + })) as OwidGdocPublished + await baker.bakeGDocPost(gdoc) + } + } else { + await baker.bakeAll() } } }