fix: Always run git fetch in netlify-branch-sync * Always run git fetch If we don't run git fetch `FETCH_HEAD` will not be set, since git clone does not set it. Approved-by: Joakim Jäderberg
172 lines
4.5 KiB
JavaScript
172 lines
4.5 KiB
JavaScript
// @ts-check
|
|
|
|
import { existsSync } from "node:fs"
|
|
|
|
const SYNC_SOURCE = "master"
|
|
|
|
// SYNC_DEST is defined in code and not in an environment variable to
|
|
// have this config version controlled.
|
|
const SYNC_DEST = [
|
|
"test",
|
|
// "stage",
|
|
// "prod"
|
|
]
|
|
|
|
const CLONE_DIR = `${process.env.HOME}/branch-sync-clone`
|
|
|
|
function error(msg) {
|
|
throw new Error(`[branch-sync] ${msg}`)
|
|
}
|
|
|
|
function createLogger() {
|
|
return {
|
|
debug(msg) {
|
|
console.log(`[branch-sync] ${msg}`)
|
|
},
|
|
info(msg) {
|
|
// info logs are grey
|
|
console.log("\x1b[90m%s\x1b[0m", `[branch-sync] ${msg}`)
|
|
},
|
|
}
|
|
}
|
|
|
|
export const onPreBuild = async function ({ utils }) {
|
|
// Only run for branch builds of source branch.
|
|
if (
|
|
process.env.BRANCH === SYNC_SOURCE &&
|
|
process.env.CONTEXT === "branch-deploy"
|
|
) {
|
|
try {
|
|
const logger = createLogger()
|
|
|
|
if (!process.env.BITBUCKET_USER_EMAIL) {
|
|
error(
|
|
`Missing commit user email, set env var 'BITBUCKET_USER_EMAIL'. See README.`
|
|
)
|
|
}
|
|
|
|
if (!process.env.BITBUCKET_ACCESS_TOKEN) {
|
|
error(
|
|
`Missing access token for Bitbucket, set env var 'BITBUCKET_ACCESS_TOKEN'. See README.`
|
|
)
|
|
}
|
|
|
|
const { run } = utils
|
|
|
|
await run("git", [
|
|
"config",
|
|
"user.email",
|
|
process.env.BITBUCKET_USER_EMAIL,
|
|
])
|
|
|
|
logger.debug(
|
|
`Git user configured with email ${process.env.BITBUCKET_USER_EMAIL}`
|
|
)
|
|
|
|
await run("git", ["config", "user.name", "Netlify Branch Sync Bot"])
|
|
|
|
logger.debug(`Git user configured with name 'Netlify Branch Sync Bot'`)
|
|
|
|
logger.debug(`Clone directory: ${CLONE_DIR}`)
|
|
|
|
if (
|
|
await utils.cache.restore(CLONE_DIR, {
|
|
move: true,
|
|
})
|
|
) {
|
|
logger.debug(`Restored cached for ${CLONE_DIR}`)
|
|
} else {
|
|
logger.debug(`Nothing to restore from cache for ${CLONE_DIR}`)
|
|
}
|
|
|
|
if (existsSync(CLONE_DIR)) {
|
|
try {
|
|
await run("git", [
|
|
"-C",
|
|
CLONE_DIR,
|
|
"rev-parse",
|
|
"--is-bare-repository",
|
|
])
|
|
logger.debug(
|
|
`Verified cached clone directory is a valid bare repository.`
|
|
)
|
|
} catch (e) {
|
|
logger.info(
|
|
`Cached clone directory is corrupted or invalid. Removing and recloning. Error: ${e.message}`
|
|
)
|
|
await run("rm", ["-rf", CLONE_DIR]) // Remove corrupted cache
|
|
}
|
|
}
|
|
|
|
if (!existsSync(CLONE_DIR)) {
|
|
// Clone if there is no clone.
|
|
const token = process.env.BITBUCKET_ACCESS_TOKEN ?? ""
|
|
const cloneURL = `https://x-token-auth:${token}@bitbucket.org/scandic-swap/web.git`
|
|
|
|
logger.debug(`Cloning from ${cloneURL.replace(token, "****")}`)
|
|
logger.debug(`Cloning to ${CLONE_DIR}`)
|
|
|
|
await run("git", ["clone", "--bare", "--branch", SYNC_SOURCE, cloneURL, CLONE_DIR])
|
|
}
|
|
|
|
// Always fetch to ensure FETCH_HEAD is available
|
|
logger.debug(`Fetching from origin`)
|
|
|
|
await run("git", ["-C", CLONE_DIR, "fetch", "--no-tags", "origin", SYNC_SOURCE])
|
|
|
|
logger.debug(`Attempting to sync: ${SYNC_DEST.join(", ")}`)
|
|
|
|
for (let i = 0; i < SYNC_DEST.length; ++i) {
|
|
const branch = SYNC_DEST[i]
|
|
await run("git", [
|
|
"-C",
|
|
CLONE_DIR,
|
|
"push",
|
|
"origin",
|
|
`FETCH_HEAD:${branch}`,
|
|
])
|
|
console.log(`Successfully synced '${branch}' with '${SYNC_SOURCE}'`)
|
|
}
|
|
|
|
utils.status.show({
|
|
title: "Branch sync",
|
|
summary: "All branches are synced! ✅",
|
|
text: [
|
|
`The following branches have been synced with '${SYNC_SOURCE}'@${process.env.COMMIT_REF}:`,
|
|
"",
|
|
]
|
|
.concat(
|
|
SYNC_DEST.map((branch) => {
|
|
return `- ${branch} - [Deployment list](https://app.netlify.com/sites/web-scandic-hotels/deploys?filter=${branch})`
|
|
})
|
|
)
|
|
.join("\n"),
|
|
})
|
|
} catch (error) {
|
|
utils.build.failBuild("Failed to sync branches.", { error })
|
|
}
|
|
}
|
|
}
|
|
|
|
export const onPostBuild = async function ({ utils }) {
|
|
// Only run for branch builds of source branch.
|
|
if (
|
|
process.env.BRANCH === SYNC_SOURCE &&
|
|
process.env.CONTEXT === "branch-deploy"
|
|
) {
|
|
try {
|
|
const logger = createLogger()
|
|
|
|
if (
|
|
await utils.cache.save(CLONE_DIR, {
|
|
move: true,
|
|
})
|
|
) {
|
|
logger.debug(`Saved cached for ${CLONE_DIR}`)
|
|
}
|
|
} catch (error) {
|
|
utils.build.failBuild("Failed to sync branches.", { error })
|
|
}
|
|
}
|
|
}
|