For a project in my company I had to synchronize an own Bitbucket repository with an external one. My idea was to accomplish this using Bitbucket Pipelines. Here is an explanation how its possible to synchronize two Bitbucket repositories using Bitbucket Pipelines.
To access your Bitbucket repository without an real user account you can add an access key directly in your repository settings on Bitbucket. Basically the access key is a public key created using the command
ssh-keygen . If you want to directly pass a file name for the keys you can use the parameter
-f , e.g.
ssh-keygen -f example .
Once you have created your access keys, you have to add them into your Bitbucket repositories. You can use the same access key for both repositories but I generated two different keys and called them source and target . So just head to
Settings > Access keys and add your keys.
bitbucket-pipelines.yml contains this little script. I use
php:7.1-fpm as image since my pipeline runs some more application-specific stuff for some php application deployment.
image: php:7.1-fpm pipelines: default: - step: script: - apt-get update && apt-get install -y unzip git - sh .pipelines/synchronize-repositories.sh - echo "Repository has been successfully synchronized"
.pipelines/synchronize-repositories.sh then looks like the following:
#!/bin/sh SOURCE_REPOSITORY_NAME=source-repository.git SOURCE_URLemail@example.com:team1/$SOURCE_REPOSITORY_NAME TARGET_REPOSITORY_NAME=target-repository.git TARGET_URLfirstname.lastname@example.org:team2/$TARGET_REPOSITORY_NAME echo "Current path is" pwd eval "$(ssh-agent)" echo "Enabling source ssh key" chmod 600 .ssh/source # Only for local debugging # git config --local core.sshCommand "/usr/bin/ssh -i .ssh/source" ssh-add .ssh/source if [ "$?" != "0" ]; then echo "Failed to load source ssh key" exit 1 fi echo "Deleting any old source that may exist" rm -rf $SOURCE_REPOSITORY_NAME echo "Checking out the source repository" git clone --bare $SOURCE_URL if [ "$?" != "0" ]; then echo "Failed to clone source" exit 1 fi echo "Entering the checked out repository" cd $SOURCE_REPOSITORY_NAME echo "Downloading the source repository" git fetch origin --tags if [ "$?" != "0" ]; then echo "Failed to fetch origin" exit 1 fi echo "Enabling the target ssh key" chmod 600 ../.ssh/target # Only for local debugging # git config --local core.sshCommand "/usr/bin/ssh -i ../.ssh/target" ssh-add ../.ssh/target if [ "$?" != "0" ]; then echo "Failed to load target ssh key" exit 1 fi echo "Adding the target as mirror remote" git remote add --mirror=fetch target $TARGET_URL if [ "$?" != "0" ]; then echo "Failed to add target as remote: $TARGET_URL" exit 1 fi if [ "$?" != "0" ]; then echo "Failed to fetch target" exit 1 fi echo "Copying all data from the source to the target repository" git push target --all git push target --tags if [ "$?" != "0" ]; then echo "Failed to push to target" exit 1 fi cd .. echo "Deleting any old source that may exist" rm -rf $SOURCE_REPOSITORY_NAME # Only for local debugging # git config --local core.sshCommand "/usr/bin/ssh"
At the end this script just does a one-way synchronization from
TARGET_URL/TARGET_REPOSITORY_NAME . Make sure you add the correct values matching your environment and place your ssh keys generated in step 1 in
.ssh/target . Of course you can modify this script to use environment-variables but this was not necessary in my case since the access keys are only used for the synchronization of the same application code.
So with the pipeline configuration shown above, the repository in
TARGET_URL gets completely synchronized with the repository in
SOURCE_URL whenever a branch was pushend in
SOURCE_URL . In other words: The copied code in the backup repository of our customer is up to date in realtime.