From 1e441b59fb77c26c7f14d56303a7fe5377f275cf Mon Sep 17 00:00:00 2001 From: Auto Rebase Date: Thu, 13 Feb 2025 21:09:53 +0100 Subject: [PATCH] Printing styled table --- app.ts | 16 ++++++++-------- dist/app.js | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app.ts b/app.ts index 16731ce..a560b8f 100644 --- a/app.ts +++ b/app.ts @@ -1,7 +1,7 @@ -import { spawn } from "child_process"; -import { ChildProcess, SpawnOptions } from "node:child_process"; +import {spawn} from "child_process"; +import {ChildProcess, SpawnOptions} from "node:child_process"; import * as core from '@actions/core'; -import { LogLevel, styledTable, writeConsole } from "@skydust/toolkit"; +import {LogLevel, styledTable, writeConsole} from "@skydust/toolkit"; // Ignored branches const IGNORED_BRANCHES: string[] = core.getInput('branchesToIgnore', { required: false }).split(","); @@ -297,16 +297,16 @@ const main = async (): Promise => { } const failedRebase = rebasedBranches.filter(rebased => !rebased.success) - .map(rebased => [rebased.branch, rebased.onBranch, rebased.action] as string[]); + .map(rebased => [rebased.branch.replace("origin/",""), Action[rebased.action], rebased.onBranch.replace("origin/","")] as string[]); if(failedRebase.length === 0) { writeConsole("All rebase where done successfully", LogLevel.INFO); } else { - writeConsole("Some rebase failed", LogLevel.WARNING); - styledTable([ - ["Branch", "Action", "Onto branch"], + writeConsole("Some rebases failed.", LogLevel.WARNING); + writeConsole(styledTable([ + ["Branch", "Tried Action", "Onto branch"], ...failedRebase - ]); + ]), LogLevel.WARNING); } } catch (error) { writeConsole("Error during workflow execution", LogLevel.ERROR); diff --git a/dist/app.js b/dist/app.js index 5888525..e99e140 100644 --- a/dist/app.js +++ b/dist/app.js @@ -44,4 +44,4 @@ ${y.format(z)} `)):(b===LogLevel.ERROR||b===LogLevel.WARNING)&&process.stderr.write(c.concat(` `))},tableConfig={border:{topBody:"─",topJoin:"┬",topLeft:"┌",topRight:"┐",bottomBody:"─",bottomJoin:"┴",bottomLeft:"└",bottomRight:"┘",bodyLeft:"│",bodyRight:"│",bodyJoin:"│",joinBody:"─",joinLeft:"├",joinRight:"┤",joinJoin:"┼"}},styledTable=(a,b)=>(0,import_src.table)(a,{...tableConfig,...b}),IGNORED_BRANCHES=import_core.getInput("branchesToIgnore",{required:!1}).split(","),mainBranch=`origin/${import_core.getInput("mainBranch",{required:!1})}`,CI_TOKEN=import_core.getInput("ciToken",{required:!1,trimWhitespace:!0}),{GITHUB_SERVER_URL}=process.env;var Action=function(a){return a[a.Rebase=0]="Rebase",a[a.Reset=1]="Reset",a}(Action||{});const runGitCommand=(a,b)=>(writeConsole(`Running git command: git ${a.join(" ")}`),new Promise((c,d)=>{const e=spawn("git",a,{stdio:"pipe",...b});let f="",g="";e.stdout.on("data",h=>f+=h.toString()),e.stderr.on("data",h=>g+=h.toString()),e.on("close",h=>h===0?c(f):d(Error(`Git command failed with code ${h}: ${g}`)))})),fetchBranches=async()=>{writeConsole("Fetching all branches..."),await runGitCommand(["fetch","--all"]);const a=await runGitCommand(["branch","-r"]);return a.split(` `).map(b=>b.trim()).filter(b=>b!==""&&!IGNORED_BRANCHES.some(c=>RegExp(`^${c}$`).test(b.replace("origin/",""))))},getCommitsForBranch=async a=>{const b=await runGitCommand(["rev-list",a]);return new Set(b.split(` -`).filter(Boolean))},removeIgnoredBranches=a=>{let b={};for(const[c,d]of Object.entries(a)){if(d.ignore)continue;b[c]=d}return b},buildRebaseDependencyGraph=async a=>{const b={};for(const d of a)b[d]=await getCommitsForBranch(d),writeConsole(`Commits ${d}`,LogLevel.DEBUG),writeConsole(b[d],LogLevel.DEBUG);let c={};for(const d of a)for(const e of a){if(d!==e)continue;const f=b[d].isSupersetOf(b[e]);if(!f)continue;const g=b[d].difference(b[e]);if(e===mainBranch&&(c[d]={ignore:!0}),g.size===0){const h=c[d]?.equalBranches??[];c[d]={rebaseBranch:mainBranch,...c[d],equalBranches:[...h,e]}}else d!==mainBranch&&(!c[d]||c[d].differenceWithRebase>g.size)&&(c[d]={...c[d],rebaseBranch:e,differenceWithRebase:g.size})}for(const d of a){if(d!==mainBranch)continue;c[d]=c[d]??{rebaseBranch:mainBranch,differenceWithRebase:0}}return removeIgnoredBranches(c)},rebaseOrder=a=>{writeConsole("Order everything",LogLevel.DEBUG);let b=[];for(const c of Object.keys(a)){const d=b.find(e=>a[c].equalBranches?.some(f=>f===e.branch));b.push(d?{branch:c,onBranch:d.branch,action:Action.Reset}:{branch:c,onBranch:a[c].rebaseBranch,action:Action.Rebase})}return b=b.sort((c,d)=>{const e=a[c.branch].differenceWithRebase,f=a[d.branch].differenceWithRebase;return e-f}),b=b.sort((c,d)=>c.action-d.action),b},rebaseBranch=async a=>{let{branch:b,onBranch:c,action:d}=a;writeConsole(`${d===Action.Rebase?"Rebasing":"Resetting"} ${b} on ${c}`);let e=!0;return await runGitCommand(["checkout",b.replace("origin/","")]),d===Action.Rebase?await runGitCommand(["rebase",c]).catch(async f=>{writeConsole(`Failed to rebase ${b} on ${c}`,LogLevel.WARNING),writeConsole(f?.message,LogLevel.WARNING),await runGitCommand(["rebase","--abort"]),e=!1}):d===Action.Reset&&await runGitCommand(["reset","--hard",c]),await runGitCommand(["push","--force-with-lease"]),{...a,success:e}},setupCIToken=async()=>{writeConsole("Overriding git repository auth with CI_TOKEN");const a=await runGitCommand(["remote","get-url","origin"]),b=a.trim().replace(/https?:\/\//,""),c=`https://MilaBot:${CI_TOKEN}@${b}.git`;await runGitCommand(["remote","set-url","origin",c]),await runGitCommand(["config","--local","--unset",`http.https://${GITHUB_SERVER_URL.replace(/https?:\/\//,"")}/.extraheader`])},setupAutoRebaseGit=async()=>{CI_TOKEN?await setupCIToken():writeConsole("Couldn't find a CI_TOKEN. Using the gitea ghost.",LogLevel.WARNING),await runGitCommand(["config","user.email","auto-rebase@skydust.fr"]),await runGitCommand(["config","user.name","Auto Rebase"])},main=async()=>{try{writeConsole("Setup auto rebase"),await setupAutoRebaseGit();const a=await fetchBranches();a.push(mainBranch),writeConsole("Branches"),writeConsole(a),writeConsole("Determining dependencies...");const b=await buildRebaseDependencyGraph(a);writeConsole(b,LogLevel.DEBUG);const c=rebaseOrder(b);c.length===0?writeConsole("Nothing to rebase"):(writeConsole("Rebase order"),writeConsole(c));const d=[];for(const f of c)d.push(await rebaseBranch(f));const e=d.filter(f=>!f.success).map(f=>[f.branch,f.onBranch,f.action]);e.length===0?writeConsole("All rebase where done successfully",LogLevel.INFO):(writeConsole("Some rebase failed",LogLevel.WARNING),styledTable([["Branch","Action","Onto branch"],...e]))}catch(a){writeConsole("Error during workflow execution",LogLevel.ERROR),writeConsole(a,LogLevel.ERROR),process.exit(1)}};main(); \ No newline at end of file +`).filter(Boolean))},removeIgnoredBranches=a=>{let b={};for(const[c,d]of Object.entries(a)){if(d.ignore)continue;b[c]=d}return b},buildRebaseDependencyGraph=async a=>{const b={};for(const d of a)b[d]=await getCommitsForBranch(d),writeConsole(`Commits ${d}`,LogLevel.DEBUG),writeConsole(b[d],LogLevel.DEBUG);let c={};for(const d of a)for(const e of a){if(d!==e)continue;const f=b[d].isSupersetOf(b[e]);if(!f)continue;const g=b[d].difference(b[e]);if(e===mainBranch&&(c[d]={ignore:!0}),g.size===0){const h=c[d]?.equalBranches??[];c[d]={rebaseBranch:mainBranch,...c[d],equalBranches:[...h,e]}}else d!==mainBranch&&(!c[d]||c[d].differenceWithRebase>g.size)&&(c[d]={...c[d],rebaseBranch:e,differenceWithRebase:g.size})}for(const d of a){if(d!==mainBranch)continue;c[d]=c[d]??{rebaseBranch:mainBranch,differenceWithRebase:0}}return removeIgnoredBranches(c)},rebaseOrder=a=>{writeConsole("Order everything",LogLevel.DEBUG);let b=[];for(const c of Object.keys(a)){const d=b.find(e=>a[c].equalBranches?.some(f=>f===e.branch));b.push(d?{branch:c,onBranch:d.branch,action:Action.Reset}:{branch:c,onBranch:a[c].rebaseBranch,action:Action.Rebase})}return b=b.sort((c,d)=>{const e=a[c.branch].differenceWithRebase,f=a[d.branch].differenceWithRebase;return e-f}),b=b.sort((c,d)=>c.action-d.action),b},rebaseBranch=async a=>{let{branch:b,onBranch:c,action:d}=a;writeConsole(`${d===Action.Rebase?"Rebasing":"Resetting"} ${b} on ${c}`);let e=!0;return await runGitCommand(["checkout",b.replace("origin/","")]),d===Action.Rebase?await runGitCommand(["rebase",c]).catch(async f=>{writeConsole(`Failed to rebase ${b} on ${c}`,LogLevel.WARNING),writeConsole(f?.message,LogLevel.WARNING),await runGitCommand(["rebase","--abort"]),e=!1}):d===Action.Reset&&await runGitCommand(["reset","--hard",c]),await runGitCommand(["push","--force-with-lease"]),{...a,success:e}},setupCIToken=async()=>{writeConsole("Overriding git repository auth with CI_TOKEN");const a=await runGitCommand(["remote","get-url","origin"]),b=a.trim().replace(/https?:\/\//,""),c=`https://MilaBot:${CI_TOKEN}@${b}.git`;await runGitCommand(["remote","set-url","origin",c]),await runGitCommand(["config","--local","--unset",`http.https://${GITHUB_SERVER_URL.replace(/https?:\/\//,"")}/.extraheader`])},setupAutoRebaseGit=async()=>{CI_TOKEN?await setupCIToken():writeConsole("Couldn't find a CI_TOKEN. Using the gitea ghost.",LogLevel.WARNING),await runGitCommand(["config","user.email","auto-rebase@skydust.fr"]),await runGitCommand(["config","user.name","Auto Rebase"])},main=async()=>{try{writeConsole("Setup auto rebase"),await setupAutoRebaseGit();const a=await fetchBranches();a.push(mainBranch),writeConsole("Branches"),writeConsole(a),writeConsole("Determining dependencies...");const b=await buildRebaseDependencyGraph(a);writeConsole(b,LogLevel.DEBUG);const c=rebaseOrder(b);c.length===0?writeConsole("Nothing to rebase"):(writeConsole("Rebase order"),writeConsole(c));const d=[];for(const f of c)d.push(await rebaseBranch(f));const e=d.filter(f=>!f.success).map(f=>[f.branch.replace("origin/",""),Action[f.action],f.onBranch.replace("origin/","")]);e.length===0?writeConsole("All rebase where done successfully",LogLevel.INFO):(writeConsole("Some rebases failed.",LogLevel.WARNING),writeConsole(styledTable([["Branch","Tried Action","Onto branch"],...e]),LogLevel.WARNING))}catch(a){writeConsole("Error during workflow execution",LogLevel.ERROR),writeConsole(a,LogLevel.ERROR),process.exit(1)}};main(); \ No newline at end of file