UNPKG

@scaleway/changesets-renovate

Version:

Automatically create changesets for Renovate

108 lines (106 loc) 3.54 kB
#!/usr/bin/env node 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 };