diff --git a/.changeset/mighty-buttons-fry.md b/.changeset/mighty-buttons-fry.md new file mode 100644 index 000000000..a6ab5f382 --- /dev/null +++ b/.changeset/mighty-buttons-fry.md @@ -0,0 +1,7 @@ +--- +'skuba': minor +--- + +lint, format: Skip autofixing on Renovate branches when there is no open pull request + +This prevents an issue where a Renovate branch can get stuck in the `Edited/Blocked` state without a pull request being raised. diff --git a/src/cli/lint/autofix.test.ts b/src/cli/lint/autofix.test.ts index 521d9d86b..60b68f6a2 100644 --- a/src/cli/lint/autofix.test.ts +++ b/src/cli/lint/autofix.test.ts @@ -1,5 +1,6 @@ import simpleGit from 'simple-git'; +import * as Buildkite from '../../api/buildkite'; import * as Git from '../../api/git'; import * as GitHub from '../../api/github'; import { runESLint } from '../adapter/eslint'; @@ -10,6 +11,7 @@ import { AUTOFIX_IGNORE_FILES, autofix } from './autofix'; jest.mock('simple-git'); jest.mock('../../api/git'); jest.mock('../../api/github'); +jest.mock('../../api/buildkite'); jest.mock('../adapter/eslint'); jest.mock('../adapter/prettier'); @@ -105,6 +107,32 @@ describe('autofix', () => { expectNoAutofix(); }); + it('bails on a renovate branch when there is no open pull request', async () => { + jest.mocked(Git.currentBranch).mockResolvedValue('renovate-skuba-7.x'); + jest + .mocked(GitHub.getPullRequestNumber) + .mockRejectedValue( + new Error( + `Commit cdd1520 is not associated with an open GitHub pull request`, + ), + ); + + await expect(autofix(params)).resolves.toBeUndefined(); + + expect(Buildkite.annotate).toHaveBeenCalled(); + + expectNoAutofix(); + }); + + it('suceeds on a renovate branch when there is an open pull request associated with the commit', async () => { + jest.mocked(Git.currentBranch).mockResolvedValue('renovate-skuba-7.x'); + jest.mocked(GitHub.getPullRequestNumber).mockResolvedValue(6); + + await expect(autofix(params)).resolves.toBeUndefined(); + + expectAutofixCommit(); + }); + it('bails on a GitHub protected branch', async () => { process.env.GITHUB_REF_PROTECTED = 'true'; diff --git a/src/cli/lint/autofix.ts b/src/cli/lint/autofix.ts index 631a452fd..27b3eaf6c 100644 --- a/src/cli/lint/autofix.ts +++ b/src/cli/lint/autofix.ts @@ -4,6 +4,7 @@ import { inspect } from 'util'; import fs from 'fs-extra'; import simpleGit from 'simple-git'; +import * as Buildkite from '../../api/buildkite'; import * as Git from '../../api/git'; import * as GitHub from '../../api/github'; import { isCiEnv } from '../../utils/env'; @@ -18,6 +19,8 @@ import { REFRESHABLE_IGNORE_FILES } from '../configure/refreshIgnoreFiles'; import type { Input } from './types'; +const RENOVATE_DEFAULT_PREFIX = 'renovate'; + const AUTOFIX_COMMIT_MESSAGE = 'Run `skuba format`'; const AUTOFIX_DELETE_FILES = [ @@ -79,6 +82,21 @@ const shouldPush = async ({ return false; } + if (currentBranch?.startsWith(RENOVATE_DEFAULT_PREFIX)) { + try { + await GitHub.getPullRequestNumber(); + } catch (error) { + const warning = + 'An autofix is available, but it was not pushed because an open pull request for this Renovate branch could not be found. If a pull request has since been created, retry the lint step to push the fix.'; + log.warn(warning); + try { + await Buildkite.annotate(Buildkite.md.terminal(warning)); + } catch {} + + return false; + } + } + let headCommitMessage; try { headCommitMessage = await Git.getHeadCommitMessage({ dir });