#!/usr/bin/env bash # Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -e set -o pipefail if [[ -z "${JOB_TYPE:-}" ]] && [[ -z "${CODEBUILD_CI:-}" ]]; then exit 0 fi SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" source $SCRIPT_ROOT/../lib/common.sh SKIP_PR="${1:-false}" ORIGIN_ORG="eks-distro-pr-bot" UPSTREAM_ORG="aws" REPO="eks-anywhere-build-tooling" MAIN_BRANCH="main" if [[ -n "${CODEBUILD_SOURCE_VERSION:-}" ]]; then MAIN_BRANCH="$CODEBUILD_SOURCE_VERSION" fi if [[ -n "${PULL_BASE_REF:-}" ]]; then MAIN_BRANCH="$PULL_BASE_REF" fi function pr::github::should_auth() { [[ "${JOB_TYPE:-}" == "periodic" ]] || [[ -n "${CODEBUILD_CI:-}" ]] } function commit_push() { local -r pr_branch="$1" local force_push="$2" if [[ "$force_push" = "true" ]]; then force_push="-f" else force_push="" fi if build::common::echo_and_run git push $force_push -u bot $pr_branch; then echo "Commit pushed" return fi # Other jobs could be running and updating the same branch, which is expected # attempt to rebase and retry build::common::echo_and_run git fetch -q bot build::common::echo_and_run git branch --set-upstream-to=bot/$pr_branch $pr_branch # rebase succeeded, return 1 to retry the push if build::common::echo_and_run git rebase bot/$pr_branch; then echo "Rebased local branch, retrying" return 1 fi git status git diff HEAD -- $(git diff --name-only --diff-filter=U) # rebase failed with conflict, exit with error exit 1 } function pr::commit::push() { local -r commit_message="$1" local -r pr_branch="$2" local -r force_push="${3:-true}" build::common::echo_and_run git checkout -B $pr_branch git diff --staged local -r files_added=$(git diff --staged --name-only) if [ "$files_added" = "" ]; then echo "No files changed to commit" return 1 fi build::common::echo_and_run git status build::common::echo_and_run git commit -m "$commit_message" || true if ! pr::github::should_auth; then echo "Skipping commit push due to missing correct job type" return 1 fi if pr::github::auth; then retry commit_push "$pr_branch" "$force_push" fi } function pr::create() { local -r pr_title="$1" local -r pr_branch="$2" local -r pr_body="$3" if ! pr::github::should_auth; then echo "Skipping PR creation due to missing correct job type" return fi if [[ "${SKIP_PR}" == "true" ]]; then echo "Skipping PR creation" return fi if ! pr::github::auth; then echo "Skipping PR creation due to missing Github auth creds" return fi if ! git ls-remote --exit-code bot $pr_branch; then echo "Skipping PR creation due to missing upstream branch: $pr_branch" return fi local pr_exists=$(GH_PAGER='' gh pr list --json number -H "$pr_branch") if [ "$pr_exists" != "[]" ]; then # already exists echo "PR already exists." return fi build::common::echo_and_run gh pr create --title "$pr_title" --body "$pr_body" --base $MAIN_BRANCH --head $ORIGIN_ORG:$pr_branch } function pr::github::auth() { if [[ -z "${GITHUB_TOKEN:-}" ]] && [[ ! -f /secrets/github-secrets/token ]]; then echo "Missing GITHUB_TOKEN or /secrets/github-secrets/token, cannot authenticate" return 1 fi if [ -f /secrets/github-secrets/token ]; then gh auth login --with-token < /secrets/github-secrets/token fi gh auth setup-git gh api rate_limit gh repo set-default "${UPSTREAM_ORG}/${REPO}" } function pr::create::pr_body(){ pr_body="" case $1 in attribution) pr_body=$(cat <<'EOF' This PR updates the ATTRIBUTION.txt files across all dependency projects if there have been changes. These files should only be changing due to project GIT_TAG bumps or Golang version upgrades. If changes are for any other reason, please review carefully before merging! EOF ) ;; checksums) pr_body=$(cat <&- || git remote add upstream https://github.com/${UPSTREAM_ORG}/${REPO}.git git config remote.bot.url >&- || git remote add bot https://github.com/${ORIGIN_ORG}/${REPO}.git # Files have already changed, stash to perform rebase build::common::echo_and_run git stash build::common::echo_and_run git checkout $MAIN_BRANCH # avoid hitting github limits in presubmits if pr::github::should_auth; then build::common::echo_and_run retry git fetch -q upstream # there will be conflicts before we are on the bots fork at this point # -Xtheirs instructs git to favor the changes from the current branch build::common::echo_and_run git rebase -Xtheirs upstream/$MAIN_BRANCH fi pr::stash::pop echo -e "\n-------------------------- Adding Checksum files ---------------------------\n" pr::create::checksums echo -e "\n----------------------------------------------------------------------------\n" build::common::echo_and_run git checkout $MAIN_BRANCH pr::stash::pop echo -e "\n-------------------------- Adding ATTRIBUTION files ------------------------\n" # Add attribution files for FILE in $(find . -type f \( -name "*ATTRIBUTION.txt" ! -path "*/_output/*" \)); do pr::file:add $FILE done # stash help.mk files git stash --keep-index pr::create::attribution echo -e "\n----------------------------------------------------------------------------\n" build::common::echo_and_run git checkout $MAIN_BRANCH pr::stash::pop echo -e "\n-------------------------- Adding Help.mk files -----------------------------\n" # Add help.mk/Makefile files for FILE in $(find . -type f \( -name Help.mk -o -name Makefile \)); do pr::file:add $FILE done pr::create::help echo -e "\n----------------------------------------------------------------------------\n"