Download the latest Bitbucket Runner

Atlassian is amazingly unresponsive to users of their Bitbucket product. Since the launch of the Bitbucket Pipelines "Runners" feature more than two years ago there has been an open issue with a suggestion to auto-update runners, or at least provide a way for users to know when a new runner version is available.

In the issue comments users have suggested various work-arounds to use while waiting for Atlassian to wake up. I have created my own simple script that just parse the Changelog for the Bitbucket Pipelines Self-hosted Runner, select the lastest version number, and downloads and unpacks the zip-file with runner.

Here is the full Python script:

import re
import shutil
import subprocess
import sys

from pathlib import Path

import requests


def main():
    p = re.compile(r'\#\# (\d+\.\d+\.\d+)')

    r = requests.get('https://product-downloads.atlassian.com/software/bitbucket/'
                     'pipelines/CHANGELOG.md', timeout=10)
    runner_version = ''
    for line in r.text.splitlines():
        m = p.match(line)
        if m:
            runner_version = m.group(1)
            print('Latest runner version:', runner_version)
            break
    else:
        print('Error: Latest runner version not found!')
        sys.exit(1)

    if input('Download this runner? (y/N) ') != 'y':
        sys.exit()

    fn = f'atlassian-bitbucket-pipelines-runner-{runner_version}.zip'
    url = f'https://product-downloads.atlassian.com/software/bitbucket/pipelines/{fn}'

    print('Downloading from url:', url)

    r = requests.get(url, timeout=10)
    with open(fn, 'wb') as fd:
        fd.write(r.content)

    if sys.platform == 'win32':
        print('Manually unpack the zip-file!')
        sys.exit()

    rp = Path('atlassian-bitbucket-pipelines-runner')
    print(f'Unpacking into folder: {rp}')

    if rp.exists():
        shutil.rmtree(rp)

    subprocess.run(['unzip', str(fn), '-d', str(rp)], check=True)

    fn.unlink()

    print('Done!')


if __name__ == '__main__':
    main()

You will need the requests package for the script to work.