From 84342fb18429e8e62c035f8e8c2ccc1707a79499 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Fri, 10 Apr 2020 15:59:16 +0200 Subject: [PATCH] Refactor makefile script * Fix shellcheck issues * Fix some shell style inconsistencies. * Split out some functions. Signed-off-by: Ben Kochie --- scripts/sync_makefiles.sh | 117 +++++++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 46 deletions(-) diff --git a/scripts/sync_makefiles.sh b/scripts/sync_makefiles.sh index e3ce74a50..8def333b3 100755 --- a/scripts/sync_makefiles.sh +++ b/scripts/sync_makefiles.sh @@ -1,5 +1,5 @@ -#!/bin/bash - +#!/usr/bin/env bash +# vim: ts=2 et # Setting -x is absolutely forbidden as it could leak the GitHub token. set -uo pipefail @@ -15,59 +15,84 @@ orgs="prometheus prometheus-community" GITHUB_TOKEN="${GITHUB_TOKEN:-}" if [ -z "${GITHUB_TOKEN}" ]; then - echo -e "\e[31mGitHub token (GITHUB_TOKEN) not set. Terminating.\e[0m" - exit 1 + echo -e "\e[31mGitHub token (GITHUB_TOKEN) not set. Terminating.\e[0m" + exit 1 fi # Go to the root of the repo -cd "$(git rev-parse --show-cdup)" +cd "$(git rev-parse --show-cdup)" || exit 1 source_makefile="$(pwd)/Makefile.common" source_checksum="$(sha256sum Makefile.common | cut -d' ' -f1)" -tmp_dir=$(mktemp -d) -trap "rm -rf ${tmp_dir}" EXIT +tmp_dir="$(mktemp -d)" +trap 'rm -rf "${tmp_dir}"' EXIT -for org in $orgs -do - # Iterate over all repositories in ${org}. The GitHub API can return 100 items - # at most but it should be enough for us as there are less than 40 repositories - # currently. - curl --retry 5 --silent -u "${git_user}:${GITHUB_TOKEN}" https://api.github.com/users/${org}/repos?per_page=100 2>/dev/null | jq -r '.[] | select( .name != "prometheus" ) | .name' | while read -r; do - repo="${REPLY}" - echo -e "\e[32mAnalyzing '${repo}'\e[0m" +fetch_repos() { + local url="https://api.github.com/users/${1}/repos?per_page=100" + curl --retry 5 --silent -u "${git_user}:${GITHUB_TOKEN}" "${url}" 2>/dev/null | + jq -r '.[] | select( .name != "prometheus" ) | .name' +} - target_makefile="$(curl -s --fail "https://raw.githubusercontent.com/${org}/${repo}/master/Makefile.common")" - if [ -z "${target_makefile}" ]; then - echo "Makefile.common doesn't exist in ${repo}" - continue - fi - target_checksum="$(echo ${target_makefile} | sha256sum | cut -d' ' -f1)" - if [ "${source_checksum}" == "${target_checksum}" ]; then - echo "Makefile.common is already in sync." - continue - fi +push_branch() { + # stdout and stderr are redirected to /dev/null otherwise git-push could leak + # the token in the logs. + git push --quiet \ + "https://${GITHUB_TOKEN}:@github.com/${1}" \ + --set-upstream "${branch}" 1>/dev/null 2>&1 +} - # Clone target repo to temporary directory and checkout to new branch - git clone --quiet "https://github.com/${org}/${repo}.git" "${tmp_dir}/${repo}" - cd "${tmp_dir}/${repo}" - git checkout -b "${branch}" +post_template='{"title":"%s","base":"master","head":"%s","body":"%s"}' +post_json="$(printf "${post_template}" "${pr_title}" "${branch}" "${pr_msg}")" +post_pull_request() { + curl --show-error --silent --fail \ + -u "${git_user}:${GITHUB_TOKEN}" \ + -d "${post_json}" \ + "https://api.github.com/repos/${1}/pulls" +} - # Replace Makefile.common in target repo by one from prometheus/prometheus - cp -f "${source_makefile}" ./ - if [ -n "$(git status --porcelain)" ]; then - git config user.email "${git_mail}" - git config user.name "${git_user}" - git add . - git commit -s -m "${commit_msg}" - # stdout and stderr are redirected to /dev/null otherwise git-push could leak the token in the logs. - if git push --quiet "https://${GITHUB_TOKEN}:@github.com/${org}/${repo}" --set-upstream "${branch}" 1>/dev/null 2>&1; then - curl --show-error --silent \ - -u "${git_user}:${GITHUB_TOKEN}" \ - -X POST \ - -d "{\"title\":\"${pr_title}\",\"base\":\"master\",\"head\":\"${branch}\",\"body\":\"${pr_msg}\"}" \ - "https://api.github.com/repos/${org}/${repo}/pulls" - fi - fi - done +process_repo() { + local org_repo="$1" + echo -e "\e[32mAnalyzing '${org_repo}'\e[0m" + + target_makefile="$(curl -s --fail "https://raw.githubusercontent.com/${org_repo}/master/Makefile.common")" + if [ -z "${target_makefile}" ]; then + echo "Makefile.common doesn't exist in ${org_repo}" + return + fi + target_checksum="$(echo "${target_makefile}" | sha256sum | cut -d' ' -f1)" + if [ "${source_checksum}" == "${target_checksum}" ]; then + echo "Makefile.common is already in sync." + return + fi + + # Clone target repo to temporary directory and checkout to new branch + git clone --quiet "https://github.com/${org_repo}.git" "${tmp_dir}/${org_repo}" + cd "${tmp_dir}/${org_repo}" || return 1 + git checkout -b "${branch}" || return 1 + + # Replace Makefile.common in target repo by one from prometheus/prometheus + cp -f "${source_makefile}" ./ + if [ -n "$(git status --porcelain)" ]; then + git config user.email "${git_mail}" + git config user.name "${git_user}" + git add . + git commit -s -m "${commit_msg}" + if push_branch "${org_repo}"; then + post_pull_request "${org_repo}" + fi + fi +} + +for org in ${orgs}; do + mkdir -p "${tmp_dir}/${org}" + # Iterate over all repositories in ${org}. The GitHub API can return 100 items + # at most but it should be enough for us as there are less than 40 repositories + # currently. + fetch_repos "${org}" | while read -r repo; do + if ! process_repo "${org}/${repo}"; then + echo "Failed to process '${org}/${repo}'" + exit 1 + fi + done done