Changeset View
Changeset View
Standalone View
Standalone View
contrib/source-control-tools/automated-commits.sh
#!/usr/bin/env bash | #!/usr/bin/env bash | ||||
# Note: Any bot running this script must have the appropriate permissions to | # Note: Any bot running this script must have the appropriate permissions to | ||||
# push commits upstream. When running locally, this script will git push in a | # push commits upstream. When running locally, this script will git push in a | ||||
# dry run by default. | # dry run by default. | ||||
export LC_ALL=C.UTF-8 | export LC_ALL=C.UTF-8 | ||||
set -euxo pipefail | set -euxo pipefail | ||||
DEFAULT_PARENT_COMMIT="origin/master" | |||||
help_message() { | help_message() { | ||||
cat <<EOF | cat <<EOF | ||||
$0 [options] [script] [script_args...] | $0 [options] [script] [script_args...] | ||||
Generate a commit from available recipes. | Generate a commit from available recipes. | ||||
The given script may produce a commit. If a commit is generated this way, it will be landed. | The given script may produce a commit. If a commit is generated this way, it will be landed. | ||||
Options: | Options: | ||||
-p, --parent The parent commit to build ontop of. Default: '${DEFAULT_PARENT_COMMIT}' | |||||
Note: This should only be used for testing since the behavior of setting | |||||
this to a particular commit varies slightly from the default. | |||||
-h, --help Display this help message. | -h, --help Display this help message. | ||||
Environment Variables: | Environment Variables: | ||||
COMMIT_TYPE (required) The commit recipe to run. | COMMIT_TYPE (required) The commit recipe to run. | ||||
DRY_RUN If set to 'no', this script will push the generated changes upstream. Default: 'yes' | DRY_RUN If set to 'no', this script will push the generated changes upstream. Default: 'yes' | ||||
EOF | EOF | ||||
} | } | ||||
SCRIPT="" | SCRIPT="" | ||||
SCRIPT_ARGS=() | SCRIPT_ARGS=() | ||||
PARENT_COMMIT="${DEFAULT_PARENT_COMMIT}" | |||||
# Parse command line arguments | # Parse command line arguments | ||||
while [[ $# -gt 0 ]]; do | while [[ $# -gt 0 ]]; do | ||||
case $1 in | case $1 in | ||||
-p|--parent) | |||||
PARENT_COMMIT=$(git rev-parse "$2") | |||||
shift # shift past argument | |||||
shift # shift past value | |||||
;; | |||||
-h|--help) | -h|--help) | ||||
help_message | help_message | ||||
exit 0 | exit 0 | ||||
;; | ;; | ||||
*) | *) | ||||
SCRIPT="$1" | SCRIPT="$1" | ||||
shift | shift | ||||
SCRIPT_ARGS=("$@") | SCRIPT_ARGS=("$@") | ||||
break | break | ||||
;; | ;; | ||||
esac | esac | ||||
done | done | ||||
: "${COMMIT_TYPE:=}" | : "${COMMIT_TYPE:=}" | ||||
if [ -z "${COMMIT_TYPE}" ]; then | if [ -z "${COMMIT_TYPE}" ]; then | ||||
echo "Error: Environment variable COMMIT_TYPE must be set" | echo "Error: Environment variable COMMIT_TYPE must be set" | ||||
exit 2 | exit 2 | ||||
fi | fi | ||||
LAND_PATCH_ARGS=() | LAND_PATCH_ARGS=() | ||||
case ${DRY_RUN:=yes} in | case ${DRY_RUN:=yes} in | ||||
no|NO|false|FALSE) | no|NO|false|FALSE) | ||||
if [ "${PARENT_COMMIT}" != "${DEFAULT_PARENT_COMMIT}" ]; then | # Nothing to do | ||||
echo "Error: Running with DRY_RUN=no on a commit parent other than '${DEFAULT_PARENT_COMMIT}'" | |||||
exit 3 | |||||
fi | |||||
;; | ;; | ||||
*) | *) | ||||
LAND_PATCH_ARGS+=("--dry-run") | LAND_PATCH_ARGS+=("--dry-run") | ||||
;; | ;; | ||||
esac | esac | ||||
OLD_HEAD="$(git rev-parse HEAD)" | |||||
echo "Building automated commit '${COMMIT_TYPE}'..." | echo "Building automated commit '${COMMIT_TYPE}'..." | ||||
BOT_PREFIX="[Automated]" | BOT_PREFIX="[Automated]" | ||||
TOPLEVEL=$(git rev-parse --show-toplevel) | TOPLEVEL=$(git rev-parse --show-toplevel) | ||||
BUILD_DIR="${TOPLEVEL}/abc-ci-builds/automated-commit-${COMMIT_TYPE}" | BUILD_DIR="${TOPLEVEL}/abc-ci-builds/automated-commit-${COMMIT_TYPE}" | ||||
mkdir -p "${BUILD_DIR}" | mkdir -p "${BUILD_DIR}" | ||||
export BUILD_DIR | export BUILD_DIR | ||||
DEVTOOLS_DIR="${TOPLEVEL}"/contrib/devtools | DEVTOOLS_DIR="${TOPLEVEL}"/contrib/devtools | ||||
# Make sure tree is clean | # Make sure tree is clean | ||||
git checkout master | if [ -n "$(git status --porcelain)" ]; then | ||||
git reset --hard "${PARENT_COMMIT}" | echo "Error: The source tree has unexpected changes. Clean up any changes (try 'git stash') and try again." | ||||
exit 10 | |||||
fi | |||||
case "${COMMIT_TYPE}" in | case "${COMMIT_TYPE}" in | ||||
archive-release-notes) | archive-release-notes) | ||||
# shellcheck source=../utils/compare-version.sh | # shellcheck source=../utils/compare-version.sh | ||||
source "${TOPLEVEL}"/contrib/utils/compare-version.sh | source "${TOPLEVEL}"/contrib/utils/compare-version.sh | ||||
RELEASE_NOTES_FILE="${TOPLEVEL}/doc/release-notes.md" | RELEASE_NOTES_FILE="${TOPLEVEL}/doc/release-notes.md" | ||||
RELEASE_NOTES_VERSION=$(sed -n "1s/^Bitcoin ABC version \([0-9]\+\.[0-9]\+\.[0-9]\+\).\+$/\1/p" "${RELEASE_NOTES_FILE}") | RELEASE_NOTES_VERSION=$(sed -n "1s/^Bitcoin ABC version \([0-9]\+\.[0-9]\+\.[0-9]\+\).\+$/\1/p" "${RELEASE_NOTES_FILE}") | ||||
RELEASE_NOTES_ARCHIVE="${TOPLEVEL}/doc/release-notes/release-notes-${RELEASE_NOTES_VERSION}.md" | RELEASE_NOTES_ARCHIVE="${TOPLEVEL}/doc/release-notes/release-notes-${RELEASE_NOTES_VERSION}.md" | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | if [ ! -f "${SCRIPT}" ]; then | ||||
exit 10 | exit 10 | ||||
fi | fi | ||||
"${SCRIPT}" "${SCRIPT_ARGS[@]}" | "${SCRIPT}" "${SCRIPT_ARGS[@]}" | ||||
;; | ;; | ||||
esac | esac | ||||
# Bail early if there's nothing to land | # Bail early if there's nothing to land | ||||
if [ "$(git rev-parse HEAD)" == "$(git rev-parse ${PARENT_COMMIT})" ]; then | if [ "$(git rev-parse HEAD)" == "${OLD_HEAD}" ]; then | ||||
echo "No new changes. Nothing to do." | echo "No new changes. Nothing to do." | ||||
exit 0 | exit 0 | ||||
fi | fi | ||||
# Land the generated commit | # Land the generated commit | ||||
"${TOPLEVEL}"/contrib/source-control-tools/land-patch.sh "${LAND_PATCH_ARGS[@]}" | "${TOPLEVEL}"/contrib/source-control-tools/land-patch.sh "${LAND_PATCH_ARGS[@]}" |