Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: handle merge_group event - get squashed commit #806

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,66 @@ jobs:

Alternatively, you can run on other event types such as `on: [push]`. In that case the action will lint the push event's commit(s) instead of linting commits from a pull request. You can also combine `push` and `pull_request` together in the same workflow.

### Using with GitHub Merge Queues

GitHub's [merge queue](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue) is a feature that allows you to queue pull requests for merging once they meet certain criteria. When using merge queues, you need to ensure that your workflows are set up to handle the merge_group event, which is triggered when pull requests are added to the merge queue.

#### Workflow Configuration

To use the commitlint-github-action with merge queues, you need to set up a workflow that listens to the merge_group event. Here's an example of how to configure your workflow:

```yaml
name: Lint Commit Messages in Merge Queue

on:
merge_group:
types:
- checks_requested

jobs:
commitlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.sha }}

- uses: wagoid/commitlint-github-action@v6
```

#### Important Note:

To ensure that the merge_group event triggers correctly, you need to have **at least one workflow that responds to the pull_request event** with a job named the same as the one in your merge_group workflow (**commitlint** in this example). This is necessary because the merge queue relies on the existence of status checks from the pull request context.

Here's a minimal pull_request workflow to satisfy this requirement:

```yaml
name: Placeholder Workflow for Merge Queue

on:
pull_request:

jobs:
commitlint:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
```

This workflow can also be a meaningful one that checks out the commits in your PR and runs other checks, but it must have a job named **commitlint**.

### Enabling Merge Queues in Your Repository

Before you can use merge queues, you need to enable the feature in your repository settings:

- Go to your repository's Settings > Branches.
- Under Branch protection rules, edit the rule for your target branch (e.g. master).
- Enable Require merge queue.
- Specify your new job (e.g. commitlint) and any other required status checks, that must pass before merging.

For more information on configuring merge queues, refer to the [GitHub documentation on managing a merge queue](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue).

## Inputs

You can supply these inputs to the `wagoid/commitlint-github-action@v6` step.
Expand Down
15 changes: 15 additions & 0 deletions src/action.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { format } from '@commitlint/format'
import load from '@commitlint/load'
import generateOutputs from './generateOutputs.mjs'

const mergeGroupEvent = 'merge_group'
const pullRequestEvent = 'pull_request'
const pullRequestTargetEvent = 'pull_request_target'
const pullRequestEvents = [pullRequestEvent, pullRequestTargetEvent]
Expand Down Expand Up @@ -65,7 +66,21 @@ const getPullRequestEventCommits = async () => {
}))
}

const getMergeGroupEventCommits = async () => {
const { merge_group } = eventContext.payload

return [
{
message: merge_group.head_commit.message,
hash: merge_group.head_sha,
},
]
}

const getEventCommits = async () => {
if (GITHUB_EVENT_NAME === mergeGroupEvent) {
return getMergeGroupEventCommits()
}
if (pullRequestEvents.includes(GITHUB_EVENT_NAME)) {
return getPullRequestEventCommits()
}
Expand Down
54 changes: 54 additions & 0 deletions src/action.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import { jest, describe, it } from '@jest/globals'
import * as td from 'testdouble'
import {
buildResponseCommit,
createMergeGroupEventPayload,
createPullRequestEventPayload,
createPushEventPayload,
updateMergeGroupEnvVars,
updatePullRequestEnvVars,
updatePushEnvVars,
} from './testUtils.mjs'
Expand Down Expand Up @@ -952,4 +954,56 @@ describe('Commit Linter action', () => {
td.verify(mockCore.setFailed(contains(incorrectCommit.message)))
})
})

describe('when handling merge_group event', () => {
beforeEach(async () => {
cwd = await git.bootstrap('fixtures/conventional', process.cwd())
td.when(mockCore.getInput('configFile')).thenReturn(
'./commitlint.config.mjs',
)

td.replace(process, 'cwd', () => cwd)
td.replace(console, 'log')
})

it('should lint the squashed commit message successfully', async () => {
const mergeGroupData = {
head_sha: 'merge-group-head-sha',
head_commit: {
id: 'merge-group-head-sha',
message: 'feat: add new feature\n\nThis is a detailed description.',
tree_id: 'tree-sha',
},
}

await createMergeGroupEventPayload(cwd, mergeGroupData)
updateMergeGroupEnvVars(cwd)

await runAction()

td.verify(mockCore.setFailed(), { times: 0, ignoreExtraArgs: true })
td.verify(console.log('Lint free! 🎉'))
})

it('should fail if the squashed commit message has linting errors', async () => {
const mergeGroupData = {
head_sha: 'merge-group-head-sha',
head_commit: {
id: 'merge-group-head-sha',
message: 'bad commit message',
tree_id: 'tree-sha',
},
}

await createMergeGroupEventPayload(cwd, mergeGroupData)
updateMergeGroupEnvVars(cwd)

await runAction()

td.verify(
mockCore.setFailed(contains('You have commit messages with errors')),
)
td.verify(mockCore.setFailed(contains('bad commit message')))
})
})
})
29 changes: 29 additions & 0 deletions src/testUtils.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,32 @@ export const buildResponseCommit = (sha, message) => ({
message,
},
})

export const createMergeGroupEventPayload = async (cwd, mergeGroupData) => {
const payload = {
action: 'checks_requested',
merge_group: mergeGroupData,
repository: {
owner: {
login: 'wagoid',
},
name: 'commitlint-github-action',
},
}

const eventPath = path.join(cwd, 'mergeGroupEventPayload.json')

updateEnvVars({
GITHUB_EVENT_PATH: eventPath,
GITHUB_EVENT_NAME: 'merge_group',
GITHUB_REPOSITORY: 'wagoid/commitlint-github-action',
})
await writeFile(eventPath, JSON.stringify(payload), 'utf8')
}

export const updateMergeGroupEnvVars = (cwd) => {
updateEnvVars({
GITHUB_WORKSPACE: cwd,
GITHUB_EVENT_NAME: 'merge_group',
})
}
Loading