#!/usr/bin/env nix-shell #!nix-shell -i bash -p git curl python3 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. if ! ensure_changes "$SOURCE_BRANCH" "$TARGET_BRANCH"; then echo "No changes." exit 0 fi local NOTES=$(describe_update "$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 return 1 fi } describe_update() { local SOURCE_BRANCH=$1 shift local TARGET_BRANCH=$1 shift local NOTES=$(git diff origin/"$TARGET_BRANCH"...origin/"$SOURCE_BRANCH" -- DEPLOYMENT-NOTES.rst) # There often are no notes and that makes for boring reading so toss in a # diffstat as well. local DIFFSTAT=$(git diff --stat origin/"$TARGET_BRANCH"...origin/"$SOURCE_BRANCH") local WHEN=$(git log --max-count=1 --format='%cI' origin/"$TARGET_BRANCH") echo "\ Changes from $SOURCE_BRANCH since $WHEN ======================================= Deployment Notes ---------------- \`\`\` $NOTES \`\`\` Diff Stat --------- \`\`\` $DIFFSTAT \`\`\` " } 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": sys.argv[4], })) ' "$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. # # The name is slightly weird because it is shared with the update-nixpkgs job. TOKEN="$UPDATE_NIXPKGS_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_NIXPKGS_PRIVATE_TOKEN main "$TOKEN" "$@"