mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-12 16:10:30 +02:00
144 lines
4.0 KiB
JavaScript
144 lines
4.0 KiB
JavaScript
import semver from 'semver';
|
|
import {
|
|
getCommitForRef,
|
|
localRefExists,
|
|
RELEASE_CANDIDATE_BRANCH_PREFIX,
|
|
remoteBranchExists,
|
|
resolveReleaseTagForTrack,
|
|
sh,
|
|
tagVersionInfoToReleaseCandidateBranchName,
|
|
trySh,
|
|
writeGithubOutput,
|
|
} from './github-helpers.mjs';
|
|
|
|
/**
|
|
* @typedef BranchChanges
|
|
* @property { import('./github-helpers.mjs').TagVersionInfo[] } branchesToEnsure TagVersionInfo for branches the system needs to make sure exist
|
|
* @property { string[] } branchesToDeprecate Branches the system needs to remove as deprecated
|
|
* */
|
|
|
|
/**
|
|
* Look into git tags and determine which release candidate branches need to
|
|
* exist and which need to be deprecated and removed.
|
|
*
|
|
* @returns { BranchChanges }
|
|
* */
|
|
export function determineBranchChanges() {
|
|
const branchesToDeprecate = [];
|
|
|
|
const currentBetaVersion = resolveReleaseTagForTrack('beta');
|
|
const currentStableVersion = resolveReleaseTagForTrack('stable');
|
|
|
|
if (!currentBetaVersion || !currentStableVersion) {
|
|
throw new Error(
|
|
`Could not find current stable and/or beta tags. Beta: ${currentBetaVersion?.tag ?? 'not found'}, Stable: ${currentStableVersion?.tag ?? 'not found'}`,
|
|
);
|
|
}
|
|
|
|
const branchesToEnsure = [currentBetaVersion, currentStableVersion];
|
|
|
|
const stableVersion = currentStableVersion.version;
|
|
// Deprecated branch is the current stable minus 2 versions. e.g. stable: 2.9.x, deprecated is 2.7.x
|
|
const deprecatedMinorVersion = semver.minor(stableVersion) - 2;
|
|
|
|
if (deprecatedMinorVersion >= 0) {
|
|
const deprecatedBranch = `${RELEASE_CANDIDATE_BRANCH_PREFIX}${semver.major(stableVersion)}.${deprecatedMinorVersion}.x`;
|
|
branchesToDeprecate.push(deprecatedBranch);
|
|
}
|
|
|
|
return {
|
|
branchesToEnsure,
|
|
branchesToDeprecate,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @param {import("./github-helpers.mjs").TagVersionInfo} tagInfo
|
|
*/
|
|
function ensureBranch(tagInfo) {
|
|
const branch = tagVersionInfoToReleaseCandidateBranchName(tagInfo);
|
|
|
|
if (remoteBranchExists(branch)) {
|
|
console.log(`Branch ${branch} already exists on origin. Skipping.`);
|
|
return branch;
|
|
}
|
|
|
|
const commitRef = getCommitForRef(tagInfo.tag);
|
|
|
|
console.log(`Creating branch ${branch} from ${tagInfo.tag} (${commitRef})`);
|
|
// Create local branch (force safe: it shouldn't exist, but keep it robust)
|
|
if (localRefExists(`refs/heads/${branch}`)) {
|
|
sh('git', ['branch', '-f', branch, commitRef]);
|
|
} else {
|
|
sh('git', ['switch', '-c', branch, commitRef]);
|
|
}
|
|
|
|
sh('git', ['push', 'origin', branch]);
|
|
|
|
return branch;
|
|
}
|
|
|
|
/**
|
|
* @param {string} branch
|
|
*/
|
|
function removeBranch(branch) {
|
|
if (!remoteBranchExists(branch)) {
|
|
console.log(`Couldn't find branch ${branch}. Skipping removal.`);
|
|
return null;
|
|
}
|
|
|
|
console.log(`Removing remote branch ${branch} from origin...`);
|
|
// Delete remote branch
|
|
trySh('git', ['push', 'origin', '--delete', branch]);
|
|
|
|
// Optional local cleanup (keeps reruns tidy)
|
|
if (localRefExists(`refs/heads/${branch}`)) {
|
|
console.log(`Removing local branch ${branch}...`);
|
|
trySh('git', ['branch', '-D', branch]);
|
|
}
|
|
|
|
return branch;
|
|
}
|
|
|
|
function main() {
|
|
const branchChanges = determineBranchChanges();
|
|
|
|
console.log('💡 Determined branch changes');
|
|
console.log('');
|
|
console.log(
|
|
` Branches to ensure: ${branchChanges.branchesToEnsure.map(tagVersionInfoToReleaseCandidateBranchName).join(', ')}`,
|
|
);
|
|
console.log(` Branches to deprecate: ${branchChanges.branchesToDeprecate.join(', ')}`);
|
|
console.log('');
|
|
console.log('Preparing to apply changes...');
|
|
|
|
let ensuredBranches = [];
|
|
for (const tagInfo of branchChanges.branchesToEnsure) {
|
|
const branch = ensureBranch(tagInfo);
|
|
ensuredBranches.push(branch);
|
|
}
|
|
|
|
console.log('');
|
|
console.log('Starting deprecation of branches...');
|
|
|
|
let removedBranches = [];
|
|
for (const branch of branchChanges.branchesToDeprecate) {
|
|
const removedBranch = removeBranch(branch);
|
|
if (removedBranch) {
|
|
removedBranches.push(removedBranch);
|
|
}
|
|
}
|
|
|
|
console.log('Done!');
|
|
|
|
writeGithubOutput({
|
|
ensuredBranches: ensuredBranches.join(','),
|
|
removedBranches: removedBranches.join(','),
|
|
});
|
|
}
|
|
|
|
// only run when executed directly, not when imported by tests
|
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
main();
|
|
}
|