Beyond Deployments: Creative Uses for GitLab Scheduled Pipelines
When we talk about GitLab pipelines, we usually think of continuous integrations and deployments – jobs that runs tests, builds artifacts, deploy services. Pipelines are essentially automated tasks that run in response to an event or condition, whether that’s a merge request, a push to a branch, or even a defined schedule.
Once we look beyond continuous integrations and deployments, pipelines open up an interesting world of possibilities. With a little creativity, they can become your productivity buddy and can keep team workflows in top shape.
At Runa, we gave a creative sparkle to scheduled pipelines and came up with the Runa Review Bot; a friendly reminder that sends periodic summaries of all open merge requests from our team to our Slack channel.
The Problem We Wanted to Solve
- The Merge Requests(MR) sits idle until the next stand-up, or when the author finally drops a “Hey, can someone review my MR?” reminder.
- Reviewers open a large MR late in the day (say, at 6 PM) and instantly regret it. I have had a lot of such experiences, and I am sure you do too.
- Someone’s waiting on a code review but does not want to nag people on Slack.
These overall result in delays, context-switching, and often means reviews happen later than they should on something that could have been merged sooner.
Why MR Size Matters
Not all MRs are created equal. By showing additions and deletions counts in the Slack summary, we give reviewers the choice.

Is this a quick “coffee-break” review? Or is this going to be a “block-off-an-hour” deep dive?
Developers can get a sense of what’s coming and whether they have the bandwidth to review it, without even opening the MR. The size of an MR is not necessarily linked to the time taken to review it. It is more about helping each other plan better and making sure no one gets caught off guard.
At Runa, we generally prefer small MR’s. We believe it reduce the cognitive load for reviewers, making it easier to spot issues early and provide meaningful feedback. For authors, smaller MRs are easier to test, revert and/or merge, resulting in better review cycles and quality.
The Solution We Built: The Runa Review Bot

Instead of manually pinging for review on Slack, we built a Gitlab pipeline schedule that runs twice a day – once in the morning and once in the late afternoon.
Here’s What it Does:
- Scans for open MRs in our repositories.
- Compiles a friendly Slack message with:
- MR title, link and author.
- Short description of what the MR is about.
- MR size (additions + deletions + no. of files changed), so reviewers can decide if they have time to tackle it now or later.
- Finally, it sends the summary to the team’s Slack channel, or DM reviewers directly using Slack webhooks.

The scheduled pipeline triggers a Python script twice a day. Under the hood, the script fetches open merge requests, compiles details and posts a message to Slack.
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: always
stages:
- review-reminder
send_open_merge_requests_to_slack:
stage: review-reminder
variables:
TEAM_NAME: $TEAM_NAME
GITLAB_TOKEN: $GITLAB_TOKEN
SLACK_CHANNEL_WEBHOOK_URL: $SLACK_CHANNEL_WEBHOOK_URL
TEAM_MEMBER_IDS: $TEAM_MEMBER_IDS
script:
- cd runa_review_bot
- poetry install
- poetry run python main.py
Pseudocode:
BEGIN
Load environment variables: TEAM_NAME, GITLAB_TOKEN, SLACK_WEBHOOK, TEAM_MEMBER_IDS
Set BASE_URL ← "https://gitlab.com/api/v4"
FUNCTION get_diff_stat(project_id, mr_id):
Fetch diffs from GitLab
RETURN additions, deletions, files_changed
FUNCTION get_open_mrs(user_ids):
all_mrs ← []
FOR each user_id IN user_ids:
Fetch open, non-draft MRs for user_id
FOR each MR:
diff_stat ← get_diff_stat(project_id, mr_id)
IF MR can be merged AND no conflicts:
Add MR with diff_stat to all_mrs
RETURN all_mrs
FUNCTION format_for_slack(mrs):
RETURN formatted message with MR title, author, link, and size
FUNCTION send_to_slack(message):
POST message to SLACK_WEBHOOK
FUNCTION main():
mrs ← get_open_mrs(TEAM_MEMBER_IDS)
IF mrs not empty:
send_to_slack(format_for_slack(mrs))
ELSE:
PRINT "No open merge requests."
main()
END
What’s Changed?
- Better productivity – Reviewers can plan their day around MR sizes.
- Less Slack noise – No need for repeated manual pings.
- Lower friction – Hiding unfinished MRs as drafts keeps the bot from spamming half-baked work.
| Metric | Before Bot | After Bot | Improvement |
|---|---|---|---|
| Average approval time | 4.0 hrs | 1.7 hrs | ⬆️ 58% faster |
| Median approval time | 3.15 hrs | 0.75 hrs | ⬆️ 76% faster |
| Approvals ≤ 1 hr | 1 / 10 (10%) | 8 / 11 (73%) | ⬆️ 7x improvement |
| Slow approvals (>4 hrs) | 4 / 10 (40%) | 2 / 11 (18%) | ⬇️ 55% fewer slow approvals |
Behavioral Observations
- Spikes at 9:30 AM and 4:30 PM – correspond exactly to the bot’s scheduled Slack posts.
- Immediate approvals after notifications show the bot boosted MR visibility.
Workaround – For When You Don’t Want Your MR To Be Reviewed Yet
Well, mark it as a draft. Our review bot filters out draft MRs-we know sometimes you’re not ready for feedback, and you might want to hide your “not-so-proud-yet” commits.
Final Thoughts
Scheduled pipelines aren’t just for shipping code – they can be communication tools too. By automating MR reminders, we’ve freed up mental bandwidth and reduced the “Did anyone see my MR?” chatter.
And yes, if you’re feeling cheeky, you can still hide your giant “work in progress” refactors by marking them as drafts. The bot won’t know. 😉