diff --git a/app.ts b/app.ts index b125f9b..e69de29 100644 --- a/app.ts +++ b/app.ts @@ -1,135 +0,0 @@ -import * as core from '@actions/core'; -import { spawn } from "child_process"; -import fs from "fs/promises"; -import path from 'path'; -import {ChildProcess, SpawnOptions} from "node:child_process"; - -const myToken = core.getInput('branches'); - -// Ignored branches -const IGNORED_BRANCHES = ['master', 'main', 'dev', 'release']; - -type BranchDependencies = Record; - -/** - * Helper function to run a Git command and capture stdout and stderr. - */ -const runGitCommand = (args: string[], options?: SpawnOptions): Promise => - new Promise((resolve, reject) => { - const git: ChildProcess = spawn('git', args, { stdio: "inherit", ...options }); - let stdout: string = ""; - let stderr: string = ""; - - git.stdout.on('data', (data) => stdout += data.toString()); - git.stderr.on('data', (data) => stderr += data.toString()); - - // Handle completion - git.on('close', (code) => (code === 0) ? - resolve(stdout) : - reject(new Error(`Git command failed with code ${code}: ${stderr}`))); - }); - -/** - * Fetch all remote branches. - */ -const fetchBranches = async (): Promise => { - console.log('Fetching all branches...'); - await runGitCommand(['fetch', '--all']); - const branches = await runGitCommand(['branch', '-r']); - return branches - .split('\n') - .map((branch) => branch.trim().replace('origin/', '')) - .filter((branch) => !IGNORED_BRANCHES.includes(branch) && branch !== ''); -} - -/** - * Detect dependencies between branches. - */ -const detectDependencies = async (branches: string[]): Promise => { - console.log('Detecting dependencies...'); - const dependencies: BranchDependencies = {}; - - for (const branch of branches) { - dependencies[branch] = null; // Default: no dependency - - for (const otherBranch of branches) { - if (branch !== otherBranch) { - const base = await runGitCommand(['merge-base', `origin/${branch}`, `origin/${otherBranch}`]); - const isAncestor = await runGitCommand(['merge-base', '--is-ancestor', base.trim(), `origin/${branch}`]).catch(() => false); - if (isAncestor) { - dependencies[branch] = otherBranch; - break; - } - } - } - } - return dependencies; -} - -/** - * Perform a topological sort to determine the rebase order. - */ -const determineRebaseOrder = (dependencies: BranchDependencies) => { - console.log('Determining rebase order...'); - const visited = new Set(); - const order = []; - - const visit = (branch) => { - if (visited.has(branch)) return; - visited.add(branch); - if (dependencies[branch]) visit(dependencies[branch]); - order.push(branch); - }; - - Object.keys(dependencies).forEach((branch) => visit(branch)); - return order; -} - -/** - * Rebase a branch onto its base branch. - */ -const rebaseBranch = async (branch: string, baseBranch = 'master'): Promise => { - console.log(`Rebasing ${branch} onto ${baseBranch}...`); - try { - await runGitCommand(['checkout', branch]); - await runGitCommand(['fetch', 'origin', baseBranch]); - await runGitCommand(['rebase', `origin/${baseBranch}`]); - console.log(`Rebase successful for ${branch}. Pushing...`); - await runGitCommand(['push', '--force-with-lease']); - } catch (error) { - console.error(`Rebase failed for ${branch}: ${error.message}`); - await runGitCommand(['rebase', '--abort']); - } -} - -/** - * Main function to execute the workflow. - */ -const main = async (): Promise => { - try { - // Step 1: Fetch branches - const branches = await fetchBranches(); - await fs.writeFile(BRANCHES_FILE, branches.join('\n'), 'utf-8'); - console.log('Branches:', branches); - - // Step 2: Detect dependencies - const dependencies = await detectDependencies(branches); - await fs.writeFile(DEPENDENCIES_FILE, JSON.stringify(dependencies, null, 2), 'utf-8'); - console.log('Dependencies:', dependencies); - - // Step 3: Determine rebase order - const order = determineRebaseOrder(dependencies); - console.log('Rebase order:', order); - - // Step 4: Rebase branches - for (const branch of order) { - const baseBranch = dependencies[branch] || 'master'; - await rebaseBranch(branch, baseBranch); - } - } catch (error) { - console.error('Error during workflow execution:', error.message); - } -} - -// Execute the script -main();