Skip to content
Snippets Groups Projects
update-production 2.2 KiB
Newer Older
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p git curl

set -eux -o pipefail

main() {
    local TOKEN=$1
    shift
    local SERVER_URL=$1
    shift
    local PROJECT_ID=$1
    shift
    local SOURCE_BRANCH=$1
    shift
    local TARGET_BRANCH=$1
    shift

    # If there have been no changes we'll just abandon this update.
    ensure_changes "$SOURCE_BRANCH" "$TARGET_BRANCH"

    local NOTES=$(compute_notes_diff "$SOURCE_BRANCH" "$TARGET_BRANCH")

    create_merge_request "$TOKEN" "$SERVER_URL" "$PROJECT_ID" "$SOURCE_BRANCH" "$TARGET_BRANCH" "$NOTES"
}

ensure_changes() {
    local SOURCE_BRANCH=$1
    shift
    local TARGET_BRANCH=$1
    shift

    if [ $(git rev-parse "$SOURCE_BRANCH") -eq $(git rev-parse "$TARGET_BRANCH") ]; then
	echo "No changes."
	exit 0
    fi
}

compute_notes_diff() {
    local SOURCE_BRANCH=$1
    shift
    local TARGET_BRANCH=$1
    shift

    git diff origin/"$SOURCE_BRANCH"...origin/"$TARGET_BRANCH" -- DEPLOYMENT-NOTES.rst
}

create_merge_request() {
    local TOKEN=$1
    shift
    local SERVER_URL=$1
    shift
    local PROJECT_ID=$1
    shift
    # THe source branch of the MR.
    local SOURCE_BRANCH=$1
    shift
    # The target branch of the MR.
    local TARGET_BRANCH=$1
    shift
    local NOTES=$1
    shift

    local BODY=$(python3 -c '
import sys, json
print(json.dumps({
    "id": sys.argv[1],
    "source_branch": sys.argv[2],
    "target_branch": sys.argv[3],
    "remove_source_branch": True,
    "title": f"update {sys.argv[3]}",
    "description": f"```diff\n{sys.argv[4]}\n```",
}))
' "$PROJECT_ID" "$SOURCE_BRANCH" "$TARGET_BRANCH" "$NOTES")

    curl --verbose -X POST --data "${BODY}" --header "Content-Type: application/json" --header "PRIVATE-TOKEN: ${TOKEN}" "${SERVER_URL}/api/v4/projects/${PROJECT_ID}/merge_requests"
}

# Pull the GitLab token from the environment here so we can work with them as
# arguments everywhere else.  They're passed to us in the environment because
# *maybe* this is *slightly* safer than passing them in argv.
TOKEN="$UPDATE_PRODUCTION_PRIVATE_TOKEN"

# Before proceeding, remove the secrets from our environment so we don't pass
# them to child processes - none of which need them.
unset UPDATE_PRODUCTION_PRIVATE_TOKEN

main "$TOKEN" "$@"