Bitbucket and CodeWords: automating around the repository
What belongs in Pipelines and what does not, pull request hygiene, release notes assembled from merges, and keeping the tracker in step without anyone updating it.
On this page
Bitbucket Pipelines handles continuous integration properly, and the first rule of automating around a repository is not to rebuild what Pipelines already does. Building, testing, and deploying belong there: they are tied to a commit, they should block a merge, and they benefit from running in the same place as the code.
What Pipelines is poor at is everything that is not tied to a single commit. Weekly summaries, chasing a review that has gone quiet, keeping the issue tracker honest, and assembling release notes from what actually merged. That work spans commits, spans repositories, and frequently involves systems the pipeline has no business holding credentials for.
What we'll cover
- The line between Pipelines and everything else
- What the Bitbucket API reaches
- Connecting it to CodeWords
- Eight automations worth building
- Review hygiene without nagging
- Building it so it survives
- Limits worth knowing about
- Frequently asked questions
The line between Pipelines and everything else
Put it in Pipelines when it is about one commit, should block or gate a merge, needs to run in the repository's own environment, or is part of building and shipping the artifact.
Put it outside when it spans time rather than commits, spans repositories, needs credentials for systems unrelated to building, involves judgement rather than a check, or produces something for people rather than for the build.
The mistake worth avoiding is a pipeline step that posts to chat, updates a tracker, and calls three external APIs. It works, it now holds credentials for all of those, and it runs on every commit whether or not any of that was needed.
What the Bitbucket API reaches
Repositories can be listed and read, including branches, tags, and commits, across a workspace.
Pull requests can be listed, read, created, commented on, approved, and merged, with their diffs and activity available. This is where most repository automation concentrates.
Commits can be listed with messages and authors, which is what makes release note assembly possible.
Pipelines can be triggered and their status read, so an external automation can start a build or wait on one without living inside it.
Issues exist on repositories that use Bitbucket's own tracker, and Jira integration covers the more common case.
Webhooks fire on pushes, pull request events, and pipeline results, which is what lets automation react.
The shape to notice: you can see everything about what merged and when, which is the raw material for almost every useful summary.
Connecting it to CodeWords
CodeWords connects to more than 3,000 integrations, and the connection is made once and reused.
- Open CodeWords and start a new automation.
- Describe what should happen in plain language to Cody, the automation builder, naming Bitbucket and the other systems involved.
- Authorize the connection when prompted, scoping access to the repositories the automation needs rather than the whole workspace.
- Describe the exceptions: a pull request with no reviewers, a commit message that does not reference an issue, a repository with no activity that week.
- Run it in report-only mode first, so you can read what it would have done before it does anything.
You describe the outcome; Cody builds it, connects it, and deploys it. When the process changes you describe the change. The free plan covers light use, with Pro at $39 per month and Business at $100 per month as usage grows; details are on the pricing page.
Eight automations worth building
Stalled review detection. Pull requests open past a threshold with no activity, reported daily with the author and the reviewer named. Most review delay is not refusal, it is nobody realising the request is waiting.
Release notes from merges. Assemble what merged since the last tag, grouped by type, with the issue references resolved to their titles. This turns a job nobody wants into something that already exists by the time anybody asks.
Tracker synchronisation. A merged pull request moves its linked issue to the right state. The alternative is asking humans to update two systems, which produces a tracker nobody trusts.
Weekly repository digest. What merged, what is open, what has been waiting longest, and who reviewed what. Sent to a channel, not waiting in a dashboard nobody opens.
Branch hygiene. Branches merged long ago and never deleted, and branches with no commits for months, reported for cleanup rather than deleted automatically.
Cross-repository change detection. When a shared library merges a breaking change, find the repositories that depend on it and raise it. This is the one that is genuinely hard inside a pipeline and straightforward outside it.
Deployment correlation. Record what was deployed and when, alongside what merged, so that when something breaks the question of what changed has an answer rather than an investigation.
Pull request description completeness. A polite comment when a request arrives with no description, no linked issue, or no test notes. Worth setting carefully, which the next section covers.
Review hygiene without nagging
Automation aimed at people's behaviour goes wrong more often than automation aimed at systems, and the failure mode is predictable: it becomes noise and people mute it.
Report to a place, not to a person, at first. A daily digest of stalled reviews in a team channel is information. An individual message to a named developer is a nudge, and nudges wear out.
Set the threshold generously. A pull request open for four hours is not stalled, it is normal. Two working days is a reasonable starting point, and it is better to raise it than to have people learn to ignore the alert.
Exclude drafts and anything explicitly marked as waiting. An automation that chases a request the author deliberately parked is an automation that gets muted within a week.
Report the queue, not the individual. "Six requests have been waiting more than two days" prompts a team conversation. "Your request has been waiting" prompts defensiveness, particularly when the person waiting is not the person who could act.
Review what it fires monthly and remove what nobody acts on. Any rule that has produced twenty notifications and zero actions is training people to ignore the channel, which costs you the alerts that matter.
Building it so it survives
Make it safe to run twice. Webhooks retry. An automation that comments on a pull request needs to check whether it already commented, or the request accumulates identical notes.
Never merge or close automatically without a deliberate decision. Automating the reporting is safe; automating the action is a different risk and should be chosen rather than drifted into.
Scope credentials to repositories. An automation with workspace-wide write access is a credential worth more than the automation, and it will outlive the reason it was created.
Report the outcome. A confirmation that the daily check ran, with counts, makes silence meaningful.
Handle the empty case. A weekly digest for a quiet week should say it was quiet rather than sending an empty message, which reads like a broken automation.
Limits worth knowing about
Rate limits apply per authenticated user, so automation walking many repositories needs pacing. Requesting only the fields you need helps more than it sounds.
Pagination is easy to get wrong. An automation that reads the first page of pull requests works perfectly in testing on a small repository and silently under-reports in production. Always exhaust pagination, and log the count so a sudden drop is visible.
Diffs can be very large. An automation reading the full diff of every pull request will meet a generated file eventually. Cap what you read, or read the file list rather than the content.
App passwords and access tokens have different scopes and lifetimes. Choose deliberately, rotate on a schedule, and revoke when the automation is retired.
Bitbucket Cloud and Data Center have different APIs. Material written for one does not necessarily apply to the other, which is worth checking before following any example.
Frequently asked questions
Why not do all of this in Pipelines?
Because most of it is not about a commit. A weekly digest, a stalled-review check, and cross-repository dependency detection have no natural commit to hang on, and putting them in a pipeline means they run on every push and hold credentials they do not need. Keep Pipelines for build, test, and deploy.
Can an automation approve or merge pull requests?
The API permits it. Whether it should is a decision about your review culture rather than a technical question. Auto-merging a dependency bump that passed all checks is defensible; auto-approving anything that changed behaviour is not.
How do I generate release notes people will read?
Group by type rather than listing commits chronologically, resolve issue references to titles, and omit the noise — merge commits, formatting-only changes, dependency bumps unless they matter. The useful release note answers "what changed for users", which is a subset of what merged.
What about keeping Jira in step?
Merged pull requests moving their linked issues is the pattern worth building, because the alternative is asking people to update two systems and the tracker becomes untrustworthy within a month. Reference the issue key in branch names or pull request titles and have the automation read it from there.
Does this work across a whole workspace?
Yes, and be deliberate about scope. Cross-repository automation is where the real value sits, particularly dependency detection, and it is also where an over-permissioned credential does the most damage. Grant per repository where you can.
How do I avoid alert fatigue?
Report to channels rather than individuals, set generous thresholds, exclude drafts, and delete any rule nobody has acted on in a month. The number of alerts is not the measure; the proportion that produce an action is.
Can it detect which repositories depend on a library?
Yes, by reading manifest files across the workspace and matching. This is genuinely difficult to do from inside a single repository's pipeline and straightforward from outside it, which makes it one of the clearest cases for automating at the workspace level.
How do I stop this becoming noise nobody reads?
Report to a channel rather than to individuals, set thresholds generously, exclude drafts and anything explicitly parked, and delete every rule that has fired repeatedly without anyone acting. The measure is the proportion of alerts that produce an action, not the number of alerts.
Can it work across Bitbucket and other hosts?
Yes, and cross-host automation is common in organizations that acquired their way into two. The work is normalising the shapes, since a pull request and a merge request carry different fields, and it is worth doing in one place rather than in each automation.
What about repositories nobody maintains?
Detecting them is one of the more useful things here: repositories with no commits for a long period, no open work, and no recent releases. Report them for a decision rather than acting, since an unmaintained repository is sometimes finished rather than abandoned.
Should automation enforce commit message format?
Reporting on it is reasonable; blocking on it belongs in Pipelines if you want it at all. An external automation rejecting work after the fact is the worst of both, since the person has already moved on and now has to come back.
What to build first
Start with stalled review detection, in report-only mode, to a channel. It is one query, it surfaces a real and slightly uncomfortable number, and it needs no write permissions at all.
Two things make the difference between a first automation that sticks and one that gets abandoned. Run it alongside whatever happens now for a cycle or two and compare the outputs, since the differences are nearly always genuine discoveries rather than bugs. And have it report that it ran even when it found nothing, because an automation whose only output is silence is one nobody can distinguish from a broken one.