handles a merge queue with github actions and slack.
NOTE: smart-host has taken stewardship of the repository and transferred from
lwhiteley/slack-merge-queue
. The last version under the previous owner's account islwhiteley/slack-merge-queue@v3
. Please now use the version specified below in the documentation.
Create a slack api bot via https://api.slack.com/apps
then setup the following permissions
Base required scopes:
- chat:write.customize
- users:read.email
- incoming-webhook: should be enabled when the bot is added to a channel
Methods used and their scopes:
Please see each method's required scopes and add them to your slack bot token. If a new method is used with a new set of scopes, this will typically be a breaking change
Methods:
- users.info
- conversations.members
- conversations.list
- conversations.history
- conversations.replies
- chat.postMessage
- chat.update
- chat.delete
Once the bot is setup, install the bot to your desired channel.
NB:
- For private channels (or additional private channels), the bot (App) must be added to the channel
create a github secret with name SLACK_TOKEN
and its value the Bot User OAuth Access Token
.
Add the actions to your workflow. ensure the modes are used correctly as explained in the Modes
section.
There are various modes to achieve the different actions to manage the queue. These are:
This mode is responsible for adding a pull request to the slack queue. You can do this by commenting on a pull request with the init_trigger
(default: /merging
). For this mode to work, ensure this piece of your workflow is merged to the main branch of your repository.
sample:
name: sample-add-to-q
on:
issue_comment:
types: [created, edited]
pull_request_review:
types: [submitted, edited]
jobs:
add_to_queue:
env:
SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
runs-on: ubuntu-latest
name: Add PR to queue
steps:
- name: Add PR to queue
uses: smart-host/slack-merge-queue@v4
id: add_to_q
with:
mode: 'INIT'
channel: 'merge-queue'
init_trigger: '/merging'
# Use the output from the `add_to_q` step
- name: Get the output
run: echo "status => ${{ steps.add_to_q.outputs.status }}"
Additionally, you can set slack users to be notified by using a notify:
tag in the comment on a new line. This is a comma seperated list of user references. The user reference can be the:
- slack member id
- slack member's full name
- slack display name
- slack username
- email username portion (eg. john.doe@smq.com)
Please note that these references are case sensitive
eg.
/merging
notify: U024BE7LH, Max Musterman, Mark, jim.j, john.doe
Tips:
- You can update the
notify:
list in slack by editing an existingINIT
comment.- Only the watchers list can be updated by a comment change once a pull request is in the queue.
- If your slack username is the same as your github username then you will be automatically notified without specifying the
notify
list. This includes assignees and all other users associated with the pull request and comment made (except reviewers list)- github usernames will be lowercased to match slack requirements
This mode manually sets the status of a PR in the queue to CANCELLED
without needing to close a pull request. This can be considered a temporary cancel. To trigger this mode a comment can be made on the pull request with the desired or default trigger phrase.
eg. trigger cancel and override delete_on_cancel
option
/cancel-merge
delete_on_cancel: true
Actions taken:
- It will change the
Queue Status
fromMERGING
toCANCELLED
. - It will send a message to alert the next pull request in the queue when the current pull request is cancelled. Alert is only sent if the next PR is the next in line to be merged.
- if configured, will delete message thread after cancel complete
sample:
name: sample_cancel_in_queue
on:
issue_comment:
types: [created]
pull_request_review:
types: [submitted]
jobs:
add_to_queue:
env: # Or as an environment variable
SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
runs-on: ubuntu-latest
name: Cancel PR in queue
steps:
- name: Cancel PR in queue
uses: smart-host/slack-merge-queue@v4
id: cancel_pr
with:
mode: 'CANCEL'
channel: 'merge-queue'
cancel_trigger: '/cancel-merge'
cancel_ready_message: 'Previous PR merge was temporarily cancelled. This PR is now up for merge!'
# delete_on_cancel: 'true' # uncomment if you want to delete cancelled prs from queue
# Use the output from the `cancel_pr` step
- name: Get the output
run: echo "status => ${{ steps.cancel_pr.outputs.status }}"
- name: Get the next PR number
run: echo "next pr => ${{ steps.cancel_pr.outputs.next_pr }}"
This mode updates the slack message of the current pull request.
Actions taken:
- It will change the
Queue Status
fromMERGING
to eitherCANCELLED
orMERGED
for current PR. - It will send a message to alert the next Pull request in the queue when the current pull request is closed/merged.
- If a PR is merged ahead of one currently up for merge, The unmerged PR(s) will be marked as
STALE
. They can be added to the queue again by re-triggering theINIT
mode. - if configured, will delete message thread after cancel complete
sample:
name: sample_update_queue
on:
pull_request:
types: [closed]
jobs:
update_q_on_close:
env:
SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
runs-on: ubuntu-latest
name: Update Queue
steps:
- name: Update queue
uses: smart-host/slack-merge-queue@v4
id: update_q_on_close
with:
mode: 'MERGE'
channel: 'merge-queue'
merge_ready_message: 'Last PR closed. This PR is now up for merge!'
# delete_on_cancel: 'true' # uncomment if you want to delete cancelled prs from queue
# Use the output from the `update_q_on_close` step
- name: Get the output status
run: echo "status => ${{ steps.update_q_on_close.outputs.status }}"
- name: Get the next PR number
run: echo "next pr => ${{ steps.update_q_on_close.outputs.next_pr }}"
This mode alerts the current pull request in the queue by adding a message to its thread. Typically this can be used to alert the thread when the build/workflow is complete but can be used at any point in the build process based on your use case. If used to alert when the build is complete, ensure the proper dependencies are set to ensure the job is run last or close to last as a post build step.
simple example:
workflow completed example:
name: sample_alert_current
on:
workflow_run:
# will trigger alert for each workflow listed
workflows: ['mock-workflow']
types:
- completed
jobs:
alert_current_pr:
env:
SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
runs-on: ubuntu-latest
name: Alert Current in Queue
steps:
- name: Alert queue
uses: smart-host/slack-merge-queue@v4
id: alert
with:
mode: 'ALERT'
channel: 'merge-queue'
# the following variables are only available in 'workflow_run' event
alert_message: '`${{ github.event.workflow.name }}` is complete with status `${{ github.event.workflow_run.conclusion }}`!'
# Use the output from the `alert` step
- name: Get the output status
run: echo "status => ${{ steps.alert.outputs.status }}"
- Invalid required inputs will fail the build
- Process errors will not fail the build
- A status will be given along with an error log
The queue tag is sent by the INIT
mode.
Pattern: [Search Prefix] :: [PR number] :: [Queue Status] :: [PR link]
eg.
Q-PR :: 3 :: MERGED :: chore: add package keyword
Section | Description |
---|---|
Search Prefix | Critical piece used to search for queue tags within the channel. It is important that non-queue messages within the channel do not start with the sub string Q-PR |
PR number | The pull request number |
Queue Status | The status of the pull request in the queue. enum: MERGING , CANCELLED , MERGED , STALE |
PR link | A link to the pull request page. The text for the link is the pull request title |
Input | Modes | Description |
---|---|---|
mode | ___ | Required input to tell the GH Action what mode to run. An invalid mode will fail the build. enum: INIT , CANCEL , MERGE , ALERT required: true |
channel | ALL | The slack channel to use as the merge queue. Can specify channel id or name. Will not be used if channel_id is specified. Build will fail if the channel cannot be found required: true (if channel_id is not specified) |
channel_id | ALL | The slack channel id to use as the merge queue. If specified, the action will skip a channel lookup and proceed to use the channel id for further operations. required: false |
team_id | ALL | encoded Slack team id to list channels in, required if token belongs to org-wide app eg. T1234567890 default: undefined |
icon_emoji | ALL | A slack emoji to use as the bot's avatar default: :robot_face: |
history_threshold | ALL | The history threshold will stop looking up messages after the specified number of messages found do not have the 'MERGING' status default: 10 |
channel_types | ALL | Mix and match channel types by providing a comma-separated list of any combination of public_channel , private_channel , mpim , im default: public_channel,private_channel |
init_trigger | INIT | The trigger text for adding a PR to the merge queue. default: /merging |
cancel_trigger | CANCEL | The trigger text for cancelling a PR in the merge queue. default: /cancel-merge |
cancel_ready_message | CANCEL | Message to be sent to the next PR in the queue after a cancel is complete default: Previous PR merge was temporarily cancelled. This PR is now up for merge! |
merge_ready_message | MERGE | Message to be sent to the next PR in the queue after a merge/cancel occurs default: Last PR closed. This PR is now up for merge! |
alert_message | ALERT | Message to be sent to the current PR in the queue default: build is complete. Time to merge! |
only_when_current | ALERT | When true , will only send an alert to a PR in slack if it is currently up for merge. enum: true , false default: true |
auto_notify | INIT | When true , will automatically notify any related github users to the pull request. enum: true , false default: true |
delete_on_cancel | MERGE, CANCEL | When true , will delete a queue item when cancelled. enum: true , false default: false |
Output | Modes | Description |
---|---|---|
status | ALL | The status of the build run to give an insight into what has happened. These can be useful for taking additional actions in a workflow |
triggered | INIT, CANCEL | This is a boolean string which is set to true only if the correct trigger phrase is commented for an open pull request. enum: true , false |
next_pr | MERGE, CANCEL | this is the PR number for the next pull request in the queue. |
Status | Modes | Description |
---|---|---|
ALREADY_CLOSED | INIT, CANCEL | exported when the trigger is used but the pull request is already in a closed state. |
TRIGGER_NOT_FOUND | INIT, CANCEL | exported if a pull request comment does not contain the desired trigger |
WATCHERS_UPDATED | INIT | exported when a PR is already in the queue but watchers list has been updated |
ALREADY_QUEUED | INIT | exported when a PR is already added to the slack queue |
ADDED_TO_QUEUE | INIT | exported when the pull request has been added to the slack queue |
NOT_FOUND | ALERT, MERGE, CANCEL | exported when a queue tag is not found in slack |
COMPLETED | ALERT | exported when an unspecific action is complete. one such action is the generic alert action. |
CANCELLED | MERGE, CANCEL | exported when the build tag status has been updated to cancelled |
MERGED | MERGE | exported when the build tag status has been updated to merged |
FAILED | ALL | When any failure occurs then this status will be set for all modes |
- Pull requests are welcome!
Apache 2.0