"Get pipeline status into Slack" sounds like a single setting. In practice it's a choice between the native app that GitLab ships, a webhook you wire up yourself, and a tool that keeps one message per MR in sync. The right pick depends on how much channel noise you can stand and whether you care about seeing CI status on the merge request rather than in a separate ping.
The 60-second version
- The native GitLab for Slack app posts pipeline events to a channel, with a "Notify only broken pipelines" filter and a "Notify only when status changes" filter. Free, both editions.
- DIY webhooks carry the result in
object_attributes.statuson pipeline events; you relay it to Slack. It works, but every event is its own message. - The hard part is putting pipeline pass/fail on the merge request's own message. MR events carry
head_pipeline_id, not the status, so you correlate two event streams yourself.
Option 1: the native GitLab for Slack app
The GitLab for Slack app is GitLab's own app, and pipeline events are one of the event types it can post to a channel. It's free on Free, Premium, and Ultimate, and it's the fastest way to get CI results into Slack without writing code.
Two settings make it usable instead of deafening:
- Notify only broken pipelines limits pipeline notifications to failed pipelines, so a green run stays quiet.
- Notify only when status changes notifies only when the pipeline status for the ref actually changes, which cuts the repeat pings on retried or restarted pipelines.
You can send each event to up to 10 Slack channels, so a broken-pipeline alert can fan out to the team channel and an on-call channel at once. The tradeoff is the one every native-app user meets: it sends a separate message per event. The pipeline result arrives as its own line in the channel, unconnected to the merge request message that triggered it.
Option 2: DIY with GitLab pipeline webhooks
If you want control over formatting or routing, wire it yourself. Turn on "Pipeline events" in GitLab project webhooks and GitLab POSTs JSON on every pipeline state change. The status you want is in object_attributes.status (values like success, failed, running, canceled), and object_attributes.detailed_status carries a display string such as passed that reads better in a message.
Two things bite here, and both are worth knowing before you build:
- A Slack incoming webhook can only create a message. Updating a status in place needs the
chat.updateWeb API with a bot token plus the stored channel and messagets. So a plain incoming webhook gives you a new message per state, not a single line that flips from running to passed. - GitLab automatically disables a webhook that fails four consecutive times (temporarily, backing off up to 24 hours) and permanently after 40. A flaky receiver stops delivering CI results quietly, so you need monitoring on the receiver, not just the happy path.
The hard part: pipeline status on the MR message
Most teams don't actually want a pipeline ping floating loose in the channel. They want to look at the merge request notification and see whether its build is green. That's the request that's genuinely awkward, because GitLab treats merge request state and pipeline state as separate events.
A "Merge request events" payload does not carry the pipeline status. It carries head_pipeline_id, the identifier of the MR's head pipeline. To render pass/fail on the MR's own Slack message you have to keep state keyed by merge request, match each incoming pipeline event back to the MR that owns it, and edit the existing Slack message with chat.update. That's a small stateful service, not a webhook config. It's doable, but budget it as an engineering project rather than an afternoon.
Full disclosure: we make PRFlow, which does exactly that correlation for you. It posts one Slack message per merge request that updates in place, with the pipeline pass/fail shown on that same message, and it stays read-only on GitLab (the read_api scope, never write). If you're weighing it against GitLab's app, here's the honest comparison with the native GitLab for Slack app.
Which one should you pick?
- Want CI results in Slack today, no code, and can accept a separate message? The native GitLab for Slack app, with "Notify only broken pipelines" turned on.
- Have bespoke formatting or routing needs and the engineering time? DIY pipeline webhooks, knowing you'll add a bot token and state to get anything better than create-only messages.
- Want pass/fail on the merge request message without building the correlation? A consolidation tool that keeps one message per MR in sync.
Bottom line
Getting a pipeline result into Slack is easy. Getting it onto the merge request it belongs to is the part that separates a five-minute setup from a real build. Decide which one you actually want before you start, and if the answer is CI-on-the-MR, don't underestimate the state you'll have to keep. For a wider view of every way to connect the two, see the GitLab Slack integration guide, or the GitLab integration overview.