Saturday, April 6, 2019

BitBucket Geek: Master your Pull Requests on the Command Line (correction: API v2)

BitBucket does have quite a UI these days, but I really don't like websites that update their assets every single day; plus, why all that point-and-click, when you can manage all your BitBucket pull requests via a fabulous API?

Hmm, the API is fabulous; how 'bout the docs?

This was a real bummer. Maybe I didn't have the insight (or patience?) to look in all the right places, but I couldn't find any decent docs on the BitBucket pull requests API v2. (Worth noting that API v1 had some good resources, though.)

Luckily, many had taken my path before me, so the Atlassian forums had some good material to get me started; special thanks to this thread!

The hardest part was pull request creation but I managed to pull it off with some trial-and-error.

Some infra: to call the PR APIs via CLI (wget)

Structured code FTW!

# first, define some shortcuts:

alias dlwg='wget -S --no-check-certificate --content-on-error --header="Accept-Encoding: gzip"'
alias dl='dlwg -O -'
alias dlu='dl --http-user'

function apicall() {
        dlu janakaud --ask-password --auth-no-challenge -q "$@"
}

function confirm() {
        echo -n "Press Ctrl-C to abort $1"
        read
}


# then define some BitBucket-specific shortcuts for patch and PR operations

function bb_patch_op() {
        apicall https://bitbucket.org/api/2.0/repositories/my_org/$1/$2 | gunzip
}

function bb_pr_op() {
        confirm "$3 $1 PR $2"
        apicall --method POST https://bitbucket.org/api/2.0/repositories/my_org/$1/pullrequests/$2/$3
}

You may notice that I am using basic auth (--http-user and --ask-password) for authenticaing to the BitBucket pull request API endpoints. This avoids all the bells and whistles associated with OAuth; besides, you're dealing with life-changing pull requests here, so it actually makes sense to re-enter your password before taking any critical action.

Pull request API calls covered so far

# check the outstanding PRs of a given project; $1=repo
function bb_pr_check() {
        apicall https://bitbucket.org/api/2.0/repositories/my_org/$1/pullrequests
}

# download (to stdout) the patch for a specific PR; $1=repo, $2=PR#
function bb_pr_patch() {
        bb_patch_op $1 pullrequests/$2/patch
}

# download the patch for a specific commit; $1=repo, $2=commit hash
function bb_commit_patch() {
        bb_patch_op $1 patch/$2
}

# approve a PR; $1=repo, $2=PR#
function bb_pr_approve() {
        bb_pr_op $1 $2 approve
}

# merge a PR; $1=repo, $2=PR#
function bb_pr_merge() {
        bb_pr_op $1 $2 merge | gunzip
}

# and, last but not the least, open a PR! $1=repo, $2=title, $3=branch
function bb_pr_open() {
        confirm "opening pull request '$2' on $3 of '$1'"
        apicall https://bitbucket.org/api/2.0/repositories/my_org/$1/pullrequests --method POST --header "Content-Type: application/json" --body-data "{\"title\":\"$2\",\"source\":{\"branch\":{\"name\":\"$3\"},\"repository\":{\"full_name\":\"janakaud/$1\"}},\"destination\":{\"branch\":{\"name\":\"$3\"}},\"close_source_branch\":false,\"reviewers\":[{\"type\":\"user\",\"username\":\"supervisor_1\"},{\"type\":\"user\",\"username\":\"supervisor_2\"}]}" | gunzip
}

For future updates, visit my .bashrc repo.

So there!

So that's how you become a guru that opens, reviews and approves BitBucket pull requests via the CLI. Good luck!

No comments: