name: Sync Dependabot changeset on: pull_request_target: paths: - '.github/workflows/sync_dependabot-changesets.yml' - '**/yarn.lock' jobs: generate-changeset: runs-on: ubuntu-latest if: github.actor == 'dependabot[bot]' && github.repository == 'backstage/backstage' steps: - name: Harden Runner uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 with: egress-policy: audit - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: fetch-depth: 2 ref: ${{ github.head_ref }} token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} - name: Configure Git run: | git config --global user.email noreply@backstage.io git config --global user.name 'Github changeset workflow' - name: Generate changeset uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 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, commitMessage, packages) { const pkgs = packages.map(pkg => `'${pkg}': patch`).join('\n'); const message = commitMessage.replace(/([bB])ump ([\S]+)/, '$1ump `$2`').trim(); const body = `---\n${pkgs}\n---\n\n${message}\n`; await fs.writeFile(fileName, body); } const branch = await exec.getExecOutput('git branch --show-current'); if (!branch.stdout.startsWith('dependabot/')) { console.log('Not a dependabot 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/dependabot-${shortHash.trim()}.md`; const { stdout: commitMessage } = await exec.getExecOutput('git show --pretty=format:%s -s HEAD'); await createChangeset(fileName, commitMessage, packageNames); await exec.exec('git', ['add', fileName]); await exec.exec('git commit -C HEAD --amend --no-edit'); await exec.exec('git push --force');