From 89f7fc83eb278321241734c9cd770cb63fbe652a Mon Sep 17 00:00:00 2001 From: Guz013 <43732358+Guz013@users.noreply.github.com> Date: Thu, 20 Jul 2023 17:43:26 -0300 Subject: [PATCH] =?UTF-8?q?ci:=20=F0=9F=91=B7=20replace=20renovate=20chang?= =?UTF-8?q?esets=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/renovate-changesets.yml | 105 +++++++++++++++++++--- 1 file changed, 92 insertions(+), 13 deletions(-) diff --git a/.github/workflows/renovate-changesets.yml b/.github/workflows/renovate-changesets.yml index 82791e8..6c50dc1 100644 --- a/.github/workflows/renovate-changesets.yml +++ b/.github/workflows/renovate-changesets.yml @@ -1,18 +1,97 @@ +# Credits to https://github.com/backstage/backstage/blob/master/.github/workflows/sync_renovate-changesets.yml + name: "📦 Renovate Changesets" - -on: pull_request - -permissions: - contents: write - pull-requests: write +on: + pull_request_target: + paths: + - '.github/workflows/sync_renovate-changesets.yml' + - '**/yarn.lock' jobs: - changesets: + generate-changeset: runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - if: ${{ github.actor == 'dependabot[bot]' || github.actor == 'renovate[bot]' || github.actor == 'renovate' }} + if: github.actor == 'renovate[bot]' && github.repository == 'loreddev/eslit' steps: - - name: Dependabot Changesets - uses: feelepxyz/dependabot-changesets@v1 + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 2 + - name: Configure Git + run: | + git config --global user.email action@github.io + git config --global user.name 'Github changeset workflow' + - name: Generate changeset + uses: actions/github-script@v6 + with: + script: | + const { promises: fs } = require("fs"); + // Parses package.json files and returns the package names + async function getPackagesNames(files) { + const names = []; + for (const file of files) { + const data = JSON.parse(await fs.readFile(file, "utf8")); + if (!data.private) { + names.push(data.name); + } + } + return names; + } + + async function createChangeset(fileName, packageBumps, packages) { + let message = ""; + for (const [pkg, bump] of packageBumps) { + message = message + `Updated dependency \`${pkg}\` to \`${bump}\`.\n`; + } + + const pkgs = packages.map((pkg) => `'${pkg}': patch`).join("\n"); + const body = `---\n${pkgs}\n---\n\n${message.trim()}\n`; + await fs.writeFile(fileName, body); + } + + async function getBumps(files) { + const bumps = new Map(); + for (const file of files) { + const { stdout: changes } = await exec.getExecOutput("git", [ + "show", + file, + ]); + for (const change of changes.split("\n")) { + if (!change.startsWith("+ ")) { + continue; + } + const match = change.match(/"(.*?)"/g); + bumps.set(match[0].replace(/"/g, ""), match[1].replace(/"/g, "")); + } + } + return bumps; + } + + const branch = await exec.getExecOutput("git branch --show-current"); + if (!branch.stdout.startsWith("renovate/")) { + console.log("Not a renovate branch, skipping"); + return; + } + const diffOutput = await exec.getExecOutput("git diff --name-only HEAD~1"); + const diffFiles = diffOutput.stdout.split("\n"); + if (diffFiles.find((f) => f.startsWith(".changeset"))) { + console.log("Changeset already exists, skipping"); + return; + } + const files = diffFiles + .filter((file) => file !== "package.json") // skip root package.json + .filter((file) => file.includes("package.json")); + const packageNames = await getPackagesNames(files); + if (!packageNames.length) { + console.log("No package.json changes to published packages, skipping"); + return; + } + const { stdout: shortHash } = await exec.getExecOutput( + "git rev-parse --short HEAD" + ); + const fileName = `.changeset/renovate-${shortHash.trim()}.md`; + + const packageBumps = await getBumps(files); + await createChangeset(fileName, packageBumps, packageNames); + await exec.exec("git", ["add", fileName]); + await exec.exec("git commit -C HEAD --amend --no-edit"); + await exec.exec("git push --force");