Change Many Repositories¶
Bitbucket keeps some settings on the project and applies them to every
repository in it: permissions, webhooks, default tasks and branch restrictions.
Set those once, with bb project, and there
is nothing to repeat.
For a change Bitbucket keeps per repository, or one for only some of a project's repositories, run the command once per repository: list the repositories, preview the change in each, then make it.
List the repositories¶
bb repo list --json lists each repository with its slug. Pick the ones the
change is for, here those whose slug starts with svc-:
bb repo list --project PAY --all --json |
jq -r '.data[].slug | select(startswith("svc-"))'
(bb repo list --project PAY --all --json | ConvertFrom-Json).data.slug |
Where-Object { $_ -like 'svc-*' }
--all lists every repository, rather than the first 25.
Preview, then change¶
Run the change with --dry-run in every repository before making it in any. A
dry run exits as the real run would, so the script stops at the first
repository that would refuse the change, before anything has changed:
#!/usr/bin/env bash
set -euo pipefail
project=PAY
slugs=$(bb repo list --project "$project" --all --json |
jq -r '.data[].slug | select(startswith("svc-"))')
# Preview every repository first. A dry run exits as the real run would, so
# set -e stops the script at the first repository that would be refused.
for slug in $slugs; do
bb webhook create ci https://ci.example.com/hooks/bitbucket \
--repo "$project/$slug" --dry-run
done
for slug in $slugs; do
bb webhook create ci https://ci.example.com/hooks/bitbucket \
--repo "$project/$slug"
done
$ErrorActionPreference = 'Stop'
$project = 'PAY'
$slugs = (bb repo list --project $project --all --json | ConvertFrom-Json).data.slug |
Where-Object { $_ -like 'svc-*' }
# Preview every repository first, and stop at the first that would be refused.
foreach ($slug in $slugs) {
bb webhook create ci https://ci.example.com/hooks/bitbucket --repo "$project/$slug" --dry-run
if ($LASTEXITCODE -ne 0) { throw "bb would refuse the change in $project/$slug" }
}
foreach ($slug in $slugs) {
bb webhook create ci https://ci.example.com/hooks/bitbucket --repo "$project/$slug"
if ($LASTEXITCODE -ne 0) { throw "bb did not make the change in $project/$slug" }
}
Each preview names the repository and what would happen there:
Dry run: bb webhook create would go through (preconditions-checked)
- create PAY/svc-orders active=true events=[repo:refs_changed] name=ci url=https://ci.example.com/hooks/bitbucket: would apply
webhook will be created
What each command's dry run checks is under "Dry run" in its --help, and
Dry-Run Planning says how far to trust it.
Run it again¶
A script like this can be run again, after a failure or for a repository added
since. bb webhook create finds a webhook with the same name, URL and settings
and creates nothing, and its dry run says so:
Dry run: bb webhook create would change nothing (preconditions-checked)
- create PAY/svc-billing active=true events=[repo:refs_changed] name=ci url=https://ci.example.com/hooks/bitbucket: no change
webhook 33 already exists with this name, URL and settings, so nothing will be created
Before you loop another command, check what it does the second time: its dry
run in a repository where the change is already made says no change, or that
it would make the change again.
Read what changed¶
Under --json each run is one document, which says what it did. For
bb webhook create, created is false where the webhook was already there:
bb webhook create ci https://ci.example.com/hooks/bitbucket --repo PAY/svc-orders --json |
jq '.data.created'
bb <command> --describe lists the fields a command's document has.