diff --git a/.changeset/clean-cougars-thank.md b/.changeset/clean-cougars-thank.md new file mode 100644 index 000000000..8094a0266 --- /dev/null +++ b/.changeset/clean-cougars-thank.md @@ -0,0 +1,5 @@ +--- +"@scaleway/changesets-renovate": minor +--- + +add an option to sort the message diff --git a/packages/changesets-renovate/README.md b/packages/changesets-renovate/README.md index da823e30b..9d2dd6b8e 100644 --- a/packages/changesets-renovate/README.md +++ b/packages/changesets-renovate/README.md @@ -34,4 +34,36 @@ To skip checking the branch name starts `renovate/` SKIP_BRANCH_CHECK=TRUE changesets-renovate ``` +To sort both the package bumps and update messages alphabetically + +```bash +SORT_CHANGESETS=TRUE changesets-renovate +``` + +Example: + +Unsorted: +``` +--- +'package-z': patch +'package-a': patch +--- + +Updated dependency `@company/zzz` to `0.228.0`. +Updated dependency `@company/aaa` to `1.1.15`. +Updated dependency `@company/zzz-backend` to `^0.228.0`. +``` + +Sorted: +``` +--- +'package-a': patch +'package-z': patch +--- + +Updated dependency `@company/aaa` to `1.1.15`. +Updated dependency `@company/zzz-backend` to `^0.228.0`. +Updated dependency `@company/zzz` to `0.228.0`. +``` + It's inspired by this GitHub Action from Backstage: https://github.com/backstage/backstage/blob/master/.github/workflows/sync_renovate-changesets.yml diff --git a/packages/changesets-renovate/src/__tests__/__snapshots__/generate-changeset.test.ts.snap b/packages/changesets-renovate/src/__tests__/__snapshots__/generate-changeset.test.ts.snap index 3d400f5a3..4720c3a63 100644 --- a/packages/changesets-renovate/src/__tests__/__snapshots__/generate-changeset.test.ts.snap +++ b/packages/changesets-renovate/src/__tests__/__snapshots__/generate-changeset.test.ts.snap @@ -32,8 +32,32 @@ exports[`generate changeset file > should generate changeset file, commit and pu 'packageName': patch --- -Updated dependency \`package\` to \`version\`. -Updated dependency \`package2\` to \`version2\`. +Updated dependency \`packagez\` to \`version2\`. +Updated dependency \`packagea\` to \`version\`. +", + ], + ], + "results": [ + { + "type": "return", + "value": undefined, + }, + ], +} +`; + +exports[`generate changeset file > should generate sorted changeset file, but skip commit and push 1`] = ` +[MockFunction spy] { + "calls": [ + [ + ".changeset/renovate-test.md", + "--- +'packageNameA': patch +'packageNameB': patch +--- + +Updated dependency \`packagea\` to \`version\`. +Updated dependency \`packagez\` to \`version2\`. ", ], ], diff --git a/packages/changesets-renovate/src/__tests__/__snapshots__/generate-changeset.ts.snap b/packages/changesets-renovate/src/__tests__/__snapshots__/generate-changeset.ts.snap deleted file mode 100644 index 026efa184..000000000 --- a/packages/changesets-renovate/src/__tests__/__snapshots__/generate-changeset.ts.snap +++ /dev/null @@ -1,47 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`generate changeset file should generate changeset file, but skip commit and push 1`] = ` -[MockFunction] { - "calls": [ - [ - ".changeset/renovate-test.md", - "--- -'packageName': patch ---- - -Updated dependency \`package\` to \`version\`. -Updated dependency \`package2\` to \`version2\`. -", - ], - ], - "results": [ - { - "type": "return", - "value": undefined, - }, - ], -} -`; - -exports[`generate changeset file should generate changeset file, commit and push 1`] = ` -[MockFunction] { - "calls": [ - [ - ".changeset/renovate-test.md", - "--- -'packageName': patch ---- - -Updated dependency \`package\` to \`version\`. -Updated dependency \`package2\` to \`version2\`. -", - ], - ], - "results": [ - { - "type": "return", - "value": undefined, - }, - ], -} -`; diff --git a/packages/changesets-renovate/src/__tests__/generate-changeset.test.ts b/packages/changesets-renovate/src/__tests__/generate-changeset.test.ts index ca9b644f4..ef19e1f0e 100644 --- a/packages/changesets-renovate/src/__tests__/generate-changeset.test.ts +++ b/packages/changesets-renovate/src/__tests__/generate-changeset.test.ts @@ -10,6 +10,13 @@ beforeEach(() => { }) describe('generate changeset file', () => { + beforeEach(() => { + delete process.env['SKIP_BRANCH_CHECK'] + delete process.env['SKIP_COMMIT'] + delete process.env['BRANCH_PREFIX'] + delete process.env['SORT_CHANGESETS'] + }) + it('should skip if not in renovate branch', async () => { mockSimpleGit.mockReturnValue({ ...defaultGitValues, @@ -63,7 +70,6 @@ describe('generate changeset file', () => { process.env['BRANCH_PREFIX'] = 'dep-upgrade/' await run() - process.env['BRANCH_PREFIX'] = undefined expect(console.log).not.toHaveBeenCalledWith( 'Not a renovate branch, skipping', @@ -113,7 +119,6 @@ describe('generate changeset file', () => { process.env['SKIP_BRANCH_CHECK'] = 'TRUE' await run() - process.env['SKIP_BRANCH_CHECK'] = undefined expect(console.log).not.toHaveBeenCalledWith( 'Not a renovate branch, skipping', @@ -188,8 +193,8 @@ describe('generate changeset file', () => { ], }), show: () => ` -+ "package": "version" -+ "package2": "version2" ++ "packagez": "version2" ++ "packagea": "version" `, revparse, add, @@ -260,6 +265,61 @@ describe('generate changeset file', () => { expect(push).not.toHaveBeenCalledTimes(1) }) + it('should generate sorted changeset file, but skip commit and push', async () => { + const rev = 'test' + const fileName = `.changeset/renovate-${rev}.md` + const fileA = 'test-a/package.json' + const fileB = 'test-b/package.json' + const revparse = vi.fn().mockReturnValue(rev) + const add = vi.fn() + const commit = vi.fn() + const push = vi.fn() + + mockSimpleGit.mockReturnValue({ + branch: () => ({ + current: 'renovate/test', + }), + diffSummary: () => ({ + files: [ + { + file: fileB, + }, + { + file: fileA, + }, + ], + }), + show: () => ` ++ "packagez": "version2" ++ "packagea": "version" +`, + revparse, + add, + commit, + push, + }) + + fs.readFile = vi + .fn() + .mockResolvedValueOnce(`{}`) + .mockResolvedValueOnce(`{"name":"packageNameB","version":"1.1.1"}`) + .mockResolvedValueOnce(`{"name":"packageNameA","version":"1.0.0"}`) + fs.writeFile = vi.fn() + + process.env['SKIP_COMMIT'] = 'TRUE' + process.env['SORT_CHANGESETS'] = 'TRUE' + await run() + + expect(fs.readFile).toHaveBeenCalledWith(fileA, 'utf8') + expect(fs.readFile).toHaveBeenCalledWith(fileB, 'utf8') + expect(fs.writeFile).toMatchSnapshot() + expect(add).not.toHaveBeenCalledWith(fileName) + expect(commit).not.toHaveBeenCalledWith( + `chore: add changeset renovate-${rev}`, + ) + expect(push).not.toHaveBeenCalledTimes(1) + }) + it('should ignore workspace package.json', async () => { const file = 'package.json' diff --git a/packages/changesets-renovate/src/index.ts b/packages/changesets-renovate/src/index.ts index 25682b429..98eaa670e 100644 --- a/packages/changesets-renovate/src/index.ts +++ b/packages/changesets-renovate/src/index.ts @@ -59,12 +59,18 @@ async function createChangeset( packageBumps: Map, packages: string[], ) { - let message = '' + const messageLines = [] for (const [pkg, bump] of packageBumps) { - message += `Updated dependency \`${pkg}\` to \`${bump}\`.\n` + 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 = `---\n${pkgs}\n---\n\n${message.trim()}\n` await fs.writeFile(fileName, body)