Last active
February 10, 2023 15:14
-
-
Save 22phuber/195e6929324e0490eacb3e039f25fad1 to your computer and use it in GitHub Desktop.
Automating Pull Requests on Bitbucket with new Strapi Github releases, Blog Post: https://supportblog.ch/scheduled-bitbucket-pipeline-automatically-create-a-pull-request-on-new-strapi-github-release/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# StoneAge IT | |
# Author: Patrick Huber (22phuber@gmail.com) | |
# | |
# Description: Automate Your PR Process with Bitbucket and Strapi | |
# | |
# This script streamlines the process of creating a pull request in a Bitbucket repository when a | |
# new release is available in the Strapi Github repository. Simply run the script within the | |
# Bitbucket pipeline, such as through a daily scheduled pipeline, to stay up-to-date with | |
# the latest releases from Strapi (strapi.io). | |
# | |
# Access Token and Repository Variable: | |
# | |
# This script requires certain setup steps before it can be executed successfully. To start, | |
# an access token with the "pullrequest:write" permission must be generated in the repository's | |
# "Security" settings under "Access Tokens". Additionally, the git config user.email must be | |
# set to a specific value in the format of "<USEREMAILVALUE>@bots.bitbucket.org". Lastly, a | |
# repository variable named "BITBUCKET_API_TOKEN_STRAPI_RELEASE_BOT" must be created and | |
# assigned the generated access token. | |
# | |
# This script uses non-standard binaries: | |
# - jq (cli JSON processor) | |
# - curl | |
# | |
[[ "${SCRIPT_DEBUG}" = "true" ]] && set -x | |
set -e | |
set -o pipefail | |
scriptFolderPath=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P) | |
# CHECK access token ENV variable BITBUCKET_API_TOKEN_STRAPI_RELEASE_BOT | |
if [[ "${BITBUCKET_API_TOKEN_STRAPI_RELEASE_BOT}empty" == "empty" ]]; then | |
# shellcheck disable=SC2016 | |
printf 'Bitbucket API access token `BITBUCKET_API_TOKEN_STRAPI_RELEASE_BOT` is not set.\n' | |
exit 1 | |
fi | |
# VARIABLES | |
# Location of the `package.json`` file from strapi containing the current version | |
declare -r strapiPackageJsonFileName="package.json" | |
declare -r strapiPackageJsonFile="backend/${strapiPackageJsonFileName}" # REPLACE the location of your package.json file | |
# Bitbucket user.email from access token creation | |
declare -r bitbucketGitConfigUserEmail="<bitbucketGitConfigUserEmail>" # REPLACE: <bitbucketGitConfigUserEmail> | |
# Set variables for the GitHub repository and Bitbucket repository | |
declare -r githubRepoApi="https://api.github.com/repos/strapi/strapi" | |
declare -r bitbucketRepoApi="https://api.bitbucket.org/2.0/repositories/<workspace>/<repo_slug>" # REPLACE: <workspace> and <repo_slug> | |
declare -r sourceBranch="develop" # Source branch to checkout (you may REPLACE this value as well) | |
declare -r targetBranch="${sourceBranch}" # Target branch for the pull request (you may REPLACE this value as well) | |
# Fetch new release on GitHub repository | |
strapiLatestRelease=$( | |
set -o pipefail | |
curl --silent "${githubRepoApi}/releases/latest" | jq -r '.tag_name' | |
) | |
strapiLatestRelease="${strapiLatestRelease/v/}" # Removes `v` if any (e.g. `v4.6.0` => `4.6.0`) | |
declare -r strapiLatestRelease | |
# Get current release from Strapi `package.json` | |
strapiCurrentRelease=$(jq -r '.dependencies."@strapi/strapi"' "../${strapiPackageJsonFile}") # REPLACE the path to your package.json file | |
declare -r strapiCurrentRelease | |
printf 'Releases found: | |
strapiLatestRelease: %s | |
strapiCurrentRelease: %s | |
\n' "${strapiLatestRelease}" "${strapiCurrentRelease}" | |
# branch name for pull request | |
branchName="bot/strapi-update-to-${strapiLatestRelease}" # You may REPLACE this value as well | |
# Pull request POST payload for Bitbucket API request | |
payloadBitbucketPullRequest=$( | |
cat <<EOFPayloadBitbucketPullRequest | |
{ | |
"title": "Update Strapi to version ${strapiLatestRelease}", | |
"description": "This pull request has been automatically created by the \`$(basename "${0}")\` script using a pipeline schedule", | |
"close_source_branch": true, | |
"source": { | |
"branch": { | |
"name": "${branchName}" | |
} | |
}, | |
"destination": { | |
"branch": { | |
"name": "${targetBranch}" | |
} | |
} | |
} | |
EOFPayloadBitbucketPullRequest | |
) | |
# MAIN | |
# If a new release is found | |
if [[ "$strapiLatestRelease" != "$strapiCurrentRelease" ]]; then | |
cd "${scriptFolderPath}/.." # Change directory to root of repo (you may REPLACE or even REMOVE this cd command as well) | |
# Git: Set git user.email | |
git config user.email "${bitbucketGitConfigUserEmail}@bots.bitbucket.org" | |
# Git: Check for existing update branch | |
if gitLsRemoteResponse=$(git ls-remote --exit-code --head origin "${branchName}"); then | |
printf 'Strapi update branch with name "%s" already exists.\n%s\n' "${branchName}" "${gitLsRemoteResponse}" | |
exit 0 | |
fi | |
printf "New Strapi release found: %s\n" "${strapiLatestRelease}" | |
# Git: Checkout source branch | |
git checkout "${sourceBranch}" || { | |
printf 'Failed to checkout source branch "%s"\n' "${sourceBranch}" | |
exit 1 | |
} | |
# Git: Create a new branch for the release | |
git checkout -b "${branchName}" | |
# Determine & handle package.json updates | |
updatedStrapiPackageJsonFile=$(STRAPI_LATEST_RELEASE="${strapiLatestRelease}" jq '.dependencies |= with_entries(if .key | startswith("@strapi/") then .value = env.STRAPI_LATEST_RELEASE else . end)' "${strapiPackageJsonFile}") | |
# Also update the "app" version (optional, can be removed) | |
updatedStrapiPackageJsonFile=$( | |
set -o pipefail | |
printf '%s' "${updatedStrapiPackageJsonFile}" | jq --arg version "${strapiLatestRelease}" '.version = $version' | |
) | |
# Override the original package.json with the updated content | |
printf '%s' "${updatedStrapiPackageJsonFile}" >"${strapiPackageJsonFile}" | |
# Git: Add the changes and commit them | |
git add . | |
git commit -m "Update Strapi to version ${strapiLatestRelease}" | |
# Git: Push the changes to the Bitbucket repository | |
git push origin "${branchName}" | |
# Curl: Create a pull request (Bitbucket API) for the release branch | |
if curlResponse=$(curl \ | |
--header "Authorization: Bearer ${BITBUCKET_API_TOKEN_STRAPI_RELEASE_BOT}" \ | |
--header 'Accept: application/json' \ | |
--header 'Content-Type: application/json' \ | |
--request POST \ | |
--data "${payloadBitbucketPullRequest}" \ | |
"${bitbucketRepoApi}/pullrequests"); then | |
printf "Pull request created.\n" | |
else | |
printf "Failed to create pull request.\n" | |
fi | |
# Print reponse from curl | |
printf '\nCurl response:\n' | |
if printf '%s' "${curlResponse}" | jq . >/dev/null 2>&1; then | |
# Contains a JSON reponse | |
printf '%s\n' "${curlResponse}" | jq . | |
else | |
printf '%s\n' "${curlResponse}" | |
fi | |
else | |
printf "No new Strapi release found.\n" | |
fi | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment