Created
June 1, 2023 10:41
-
-
Save Sy1v4in/0d481cd5463f8fdb1404417e190ab2bc to your computer and use it in GitHub Desktop.
A simple script using zx that synchronizes the staging branch with the main one and merging the PR labelized win in-staging
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env zx | |
import 'zx/globals' | |
import { Octokit } from '@octokit/rest' | |
const octokit = new Octokit({ | |
auth: process.env.GH_TOKEN, | |
}) | |
const currentBranch = async () => $`git branch --show-current` | |
const checkIfLocalRepoIsClean = async () => $`git diff --quiet` | |
const branchesToSynchronize = async (repository, targetBranchName) => { | |
const pullRequests = await octokit.rest.pulls.list(repository) | |
return pullRequests.data.filter(isOnTargetBranch(targetBranchName)).map(branchName) | |
} | |
const isOnTargetBranch = targetBranch => pr => | |
pr.labels.some(label => label.name.includes(targetBranch)) | |
const branchName = pr => pr.head.ref | |
const checkout = async (branch, { pull = false, create = false } = {}) => { | |
const options = create ? '-b' : '' | |
await $`git checkout ${options} ${branch}` | |
pull && (await $`git pull`) | |
} | |
const createBranch = async branch => { | |
await nothrow($`git branch -D ${branch}`) | |
await checkout(branch, { create: true }) | |
} | |
const merge = async branch => { | |
await $`git merge origin/${branch} --no-verify` | |
} | |
const abortMerge = async () => { | |
await $`git merge --abort` | |
} | |
const pushForce = async branch => $`git push --force --set-upstream origin ${branch}` | |
const synchronizeBranches = async ({ repository, sourceBranch, targetBranch }) => { | |
await checkIfLocalRepoIsClean() | |
const previousBranch = await currentBranch() | |
await checkout(sourceBranch, { pull: true }) | |
await createBranch(targetBranch) | |
const branchesForWhichTheMergeHasFailed = [] | |
const branches = await branchesToSynchronize(repository, targetBranch) | |
for (let branch of branches) { | |
try { | |
await merge(branch) | |
} catch (e) { | |
console.error(`Could not merge branch ${branch}`) | |
branchesForWhichTheMergeHasFailed.push(branch) | |
await abortMerge() | |
} | |
} | |
if (branchesForWhichTheMergeHasFailed.length > 0) { | |
console.log(`List of branches that have fail when merged on ${targetBranch}:`) | |
branchesForWhichTheMergeHasFailed.forEach(branch => console.log(`\t• ${branch}`)) | |
console.log(`They have to be merge manually`) | |
return | |
} | |
if (branches.length > 0) { | |
await pushForce(targetBranch) | |
} | |
await checkout(previousBranch) | |
} | |
await synchronizeBranches({ | |
repository: { owner: 'TheMenu', repo: 'social-backend' }, | |
sourceBranch: 'main', | |
targetBranch: 'staging', | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment