@scaleway/changesets-renovate
Version:
Automatically create changesets for Renovate
108 lines (106 loc) • 3.54 kB
JavaScript
import fs from "node:fs/promises";
import { simpleGit } from "simple-git";
console.debug("simpleGit", simpleGit);
async function getChangesetIgnoredPackages() {
const changesetConfig = JSON.parse(
await fs.readFile(".changeset/config.json", "utf8")
);
return changesetConfig.ignore ?? [];
}
function shouldIgnorePackage(packageName, ignoredPackages) {
return ignoredPackages.some((ignoredPackage) => {
if (ignoredPackage.endsWith("*")) {
return packageName.startsWith(ignoredPackage.slice(0, -1));
}
return packageName === ignoredPackage;
});
}
async function getPackagesNames(files) {
const ignoredPackages = await getChangesetIgnoredPackages();
const packages = [];
const promises = files.map(async (file) => {
const data = JSON.parse(await fs.readFile(file, "utf8"));
if (shouldIgnorePackage(data.name, ignoredPackages)) {
return;
}
if (!data.workspaces && data.version) {
packages.push(data.name);
}
});
await Promise.all(promises);
return packages;
}
async function createChangeset(fileName, packageBumps, packages) {
const messageLines = [];
for (const [pkg, bump] of packageBumps) {
messageLines.push(`Updated dependency \`${pkg}\` to \`${bump}\`.`);
}
if (process.env["SORT_CHANGESETS"]) {
packages.sort();
messageLines.sort();
}
const message = messageLines.join("\n");
const pkgs = packages.map((pkg) => `'${pkg}': patch`).join("\n");
const body = `---
${pkgs}
---
${message.trim()}
`;
await fs.writeFile(fileName, body);
}
async function getBumps(files) {
const bumps = /* @__PURE__ */ new Map();
const promises = files.map(async (file) => {
const changes = await simpleGit().show([file]);
for (const change of changes.split("\n")) {
if (change.startsWith("+ ")) {
const match = change.match(/"(.*?)"/g);
if (match?.[0] && match[1]) {
bumps.set(match[0].replace(/"/g, ""), match[1].replace(/"/g, ""));
}
}
}
});
await Promise.all(promises);
return bumps;
}
async function run() {
const branch = await simpleGit().branch();
const branchPrefix = process.env["BRANCH_PREFIX"] ?? "renovate/";
console.log("Detected branch:", branch);
if (!branch.current.startsWith(branchPrefix) && !process.env["SKIP_BRANCH_CHECK"]) {
console.log("Not a renovate branch, skipping");
return;
}
const diffOutput = await simpleGit().diffSummary(["--name-only", "HEAD~1"]);
const diffFiles = diffOutput.files.map((file) => file.file);
console.log("Found changed files:", diffFiles);
if (diffFiles.find((f) => f.startsWith(".changeset"))) {
console.log("Changeset already exists, skipping");
return;
}
const files = diffFiles.filter((file) => file.includes("package.json"));
if (!files.length) {
console.log("No package.json changes to published packages, skipping");
return;
}
const packageNames = await getPackagesNames(files);
if (packageNames.length === 0) {
console.log("No packages modified, skipping");
return;
}
const shortHash = (await simpleGit().revparse(["--short", "HEAD"])).trim();
const fileName = `.changeset/renovate-${shortHash}.md`;
const packageBumps = await getBumps(files);
await createChangeset(fileName, packageBumps, packageNames);
if (!process.env["SKIP_COMMIT"]) {
await simpleGit().add(fileName);
await simpleGit().commit(`chore: add changeset renovate-${shortHash}`);
await simpleGit().push();
}
}
run().catch(console.error);
export {
run
};