"Hey, has staging been updated? What's new, what can I test?"
Ever heard that question from your team? I did, several times. I'm a software engineer and product manager in a small startup team. As an engineer, I can look into our GitLab and check the history, but other members of the team like designers, PMs, or even the CEO with no engineering background don't have access and wouldn't understand a commit history even if they did.
There are already tools for posting commit history on pushes: changelog tools for external users, DORA metrics for engineers. But those are either customer-facing changelog tools or raw deploy-status pings. Nothing that gives internal, non-technical teammates an automatic, plain-language summary of what just landed on staging.
So I decided to build a quick solution in my free time: StagingBrief.
Whenever a pipeline successfully runs and deploys to the infrastructure, the notify step checks the diff between the current commit and the last successful pipeline's commit. Commit messages and file changes are then sent to an LLM to summarise, and the result is posted as a Slack notification.
Just a simple GitLab CI step and a Docker image that handles everything. No separate backend, no database, no service to maintain. And no code is currently sent to the LLM, just commit messages and which files have changed.
The scratch vs. alpine issue
My goal was a single small Docker image: the Go binary plus TLS certificates for the HTTPS API calls. I used a scratch image and everything worked great on my machine and in a plain Docker container.
Then I set up the notify step in our GitLab pipeline. It failed on the first run with a vague "container unready" message. Great.
Our GitLab runners are Kubernetes-based. Turns out GitLab's Kubernetes executor does more than just run the container. Before the entrypoint executes, the runner tries to inject a small helper process into the job's container to manage the workspace. That helper needs something to work with: a shell, basic filesystem tools. The scratch image has none of that. The injection fails silently, and the pod never becomes ready.
The frustrating part was that everything worked flawlessly in every environment I tested locally. Docker Desktop runs the entrypoint directly. Even a self-hosted runner without Kubernetes should have worked fine.
The fix was switching from scratch to alpine. Image size went from ~8MB to ~18MB. Still tiny, but now compatible with GitLab's Kubernetes runner.
How it was built
Built with Go. I wrote the first pass myself, then used Claude Code for optimizations, error handling, and tests along the way.
Two things I'm still thinking about
Notification frequency. On a branch with high commit frequency, this could produce spam, countering the exact reason I built it in the first place. Too many messages lead to people ignoring some of them, muting the channel, or just losing track of what actually changed. Throttling and compacting would help, but I also want to keep the tool stateless, so this needs some thought.
Sending code instead of just metadata. Maybe sending actual code diffs to the LLM would lead to better summaries and better testing outcomes. The downside: token cost could add up quickly if not controlled, and a solid file-exclude list, things like package.json which add no value to the summary, would need to be built first.
If this sounds like your team, give it a shot. It's a five-minute setup.
notify-staging:
stage: notify
image: bytesfue/stagingbrief:latest # or pin to a specific version for reproducibility
script:
- /notify
rules:
- if: '$CI_COMMIT_BRANCH == "develop" && $CI_PIPELINE_SOURCE == "push"'
variables:
GITLAB_PROJECT_ID: $CI_PROJECT_ID
GITLAB_TOKEN: $STAGINGBRIEF_GITLAB_TOKEN
LLM_PROVIDER: openai # optional - default if unset; use "claude" to switch providers
OPENAI_API_KEY: $STAGINGBRIEF_OPENAI_KEY
SLACK_BOT_TOKEN: $STAGINGBRIEF_SLACK_BOT_TOKEN
SLACK_CHANNEL_ID: $STAGINGBRIEF_SLACK_CHANNEL_ID
GITLAB_PROJECT_NAME: "Your Project Name"
GitHub: https://github.com/bytesfue/stagingbrief
Docker Hub: https://hub.docker.com/r/bytesfue/stagingbrief

Top comments (0)