diff --git a/bin/comment_with_dependency_diff b/bin/comment_with_dependency_diff index fe5b5b32..d0c3dfa2 100755 --- a/bin/comment_with_dependency_diff +++ b/bin/comment_with_dependency_diff @@ -43,19 +43,20 @@ if [ "${BUILDKITE_PULL_REQUEST:-false}" == "false" ]; then exit 2 fi -DIFF_DEPENDENCIES_FOLDER="./build/reports/diff" +export DIFF_DEPENDENCIES_FOLDER="./build/reports/diff" +export COMMENT_FILE="$DIFF_DEPENDENCIES_FOLDER/comment_body.txt" BASE_BRANCH_DEPENDENCIES_FILE="$DIFF_DEPENDENCIES_FOLDER/base_branch_dependencies.txt" HEAD_BRANCH_DEPENDENCIES_FILE="$DIFF_DEPENDENCIES_FOLDER/head_branch_dependencies.txt" BASE_BRANCH_BUILD_ENV_FILE="$DIFF_DEPENDENCIES_FOLDER/base_branch_build_env.txt" HEAD_BRANCH_BUILD_ENV_FILE="$DIFF_DEPENDENCIES_FOLDER/head_branch_build_env.txt" -DIFF_DEPENDENCIES_FILE="$DIFF_DEPENDENCIES_FOLDER/diff_dependencies.txt" -DIFF_BUILD_ENV_FILE="$DIFF_DEPENDENCIES_FOLDER/diff_build_env.txt" +export DIFF_DEPENDENCIES_FILE="$DIFF_DEPENDENCIES_FOLDER/diff_dependencies.txt" +export DIFF_BUILD_ENV_FILE="$DIFF_DEPENDENCIES_FOLDER/diff_build_env.txt" DEPENDENCY_TREE_VERSION="1.2.1" DEPENDENCY_TREE_CHECKSUM="39c50f22cd4211a3e52afec43120b7fdf90f9890" -TLDR_DIFF_DEPENDENCIES_FILE="$DIFF_DEPENDENCIES_FOLDER/tldr_diff_dependencies.txt" -TLDR_DIFF_BUILD_ENV_FILE="$DIFF_DEPENDENCIES_FOLDER/tldr_diff_build_env.txt" +export TLDR_DIFF_DEPENDENCIES_FILE="$DIFF_DEPENDENCIES_FOLDER/tldr_diff_dependencies.txt" +export TLDR_DIFF_BUILD_ENV_FILE="$DIFF_DEPENDENCIES_FOLDER/tldr_diff_build_env.txt" git config --global user.email "mobile@automattic.com" git config --global user.name "Dependency Tree Diff Tool" @@ -121,90 +122,15 @@ java -jar "$JAR_DIR/dependency-diff-tldr-0.0.6.jar" $BASE_BRANCH_DEPENDENCIES_FI ./dependency-tree-diff.jar $BASE_BRANCH_BUILD_ENV_FILE $HEAD_BRANCH_BUILD_ENV_FILE >$DIFF_BUILD_ENV_FILE java -jar "$JAR_DIR/dependency-diff-tldr-0.0.6.jar" $BASE_BRANCH_BUILD_ENV_FILE $HEAD_BRANCH_BUILD_ENV_FILE >$TLDR_DIFF_BUILD_ENV_FILE -generate_project_dependencies_comment_body() { - cat < Preparing comment for GitHub" -The following changes in project dependencies were detected (configuration \`$CONFIGURATION\`): - -
list - -\`\`\` -$(cat "$TLDR_DIFF_DEPENDENCIES_FILE") -\`\`\` - -
- -
tree - -\`\`\`diff -$(cat "$DIFF_DEPENDENCIES_FILE") -\`\`\` - -
- - -EOF -} - -generate_build_dependencies_comment_body() { - cat <list - -\`\`\` -$(cat "$TLDR_DIFF_BUILD_ENV_FILE") -\`\`\` - - - -
tree - -\`\`\`diff -$(cat "$DIFF_BUILD_ENV_FILE") -\`\`\` - -
- -EOF -} - -if [ -n "$DIFF_DEPENDENCIES_FILE" ] || [ -n "$DIFF_BUILD_ENV_FILE" ]; then - echo "--> Commenting result to GitHub" - - # Create or clear the comment body file - COMMENT_FILE="$DIFF_DEPENDENCIES_FOLDER/comment_body.txt" - true > $COMMENT_FILE # 'true' used to clear the file as a no-op - - append_content() { - local header="$1" - local content="$2" - local github_comment_max_size=65400 # GitHub constraint is 65536, but we decrease this value slightly to reserve for hidden comment_on_pr content and line breaks - local warning_message="Content exceeds $github_comment_max_size characters. [Navigate to Buildkite build artifacts](${BUILDKITE_BUILD_URL}#${BUILDKITE_JOB_ID}) to see details." - - local current_size - current_size=$(wc -c < "$COMMENT_FILE") - - # Calculate if there's enough space for the content and header - if (( current_size + ${#header} + ${#content} > github_comment_max_size - ${#header} - ${#warning_message})); then - printf "\n%s\n%s\n" "$header" "$warning_message" > $COMMENT_FILE - return - fi - - printf "\n%s\n" "$header" >> $COMMENT_FILE - printf "%s\n" "$content" >> $COMMENT_FILE - } - - if [ -s "$DIFF_DEPENDENCIES_FILE" ]; then - append_content "## Project dependencies changes" "$(generate_project_dependencies_comment_body)" - fi +# Check if any dependency changes were found +if [ ! -s "$TLDR_DIFF_DEPENDENCIES_FILE" ] && [ ! -s "$TLDR_DIFF_BUILD_ENV_FILE" ]; then + echo "No dependency changes found" + comment_on_pr --id "dependency-diff" --if-exist delete + exit 0 +fi - if [ -s "$DIFF_BUILD_ENV_FILE" ]; then - append_content "## Build environment changes" "$(generate_build_dependencies_comment_body)" - fi +craft_comment_with_dependency_diff - comment_on_pr --id "dependency-diff" --if-exist update "$COMMENT_FILE" -else - comment_on_pr --id "dependency-diff" --if-exist delete -fi +comment_on_pr --id "dependency-diff" --if-exist update "$COMMENT_FILE" diff --git a/bin/craft_comment_with_dependency_diff b/bin/craft_comment_with_dependency_diff new file mode 100755 index 00000000..0a71ef35 --- /dev/null +++ b/bin/craft_comment_with_dependency_diff @@ -0,0 +1,88 @@ +#!/bin/bash + +# This script is used to craft a comment with a dependency diff and a build environment diff. +# It's extracted from comment_with_dependency_diff to be tested in isolation. + +set -euo pipefail + +true > "$COMMENT_FILE" # Clear the file +MAX_COMMENT_SIZE=65400 +current_size=0 + +# Templates for content formatting +print_header() { + printf "## %s changes\n\n" "$1" +} + +print_tldr() { + printf "
list + +\`\`\` +%s +\`\`\` + +
+" "$1" +} + +print_tree() { + printf "
tree + +\`\`\`diff +%s +\`\`\` + +
" "$1" +} + +print_tree_too_large() { + printf "\n ⚠️ %s tree is too large. [View it in Buildkite artifacts](%s#%s)\n" "$1" "$2" "$3" +} + +# Calculate total size needed for TLDRs +# This assumes that TLDRs are never too large to fit in the comment +tldr_size=0 +for section in "Project dependencies" "Build environment"; do + tldr_file="$TLDR_DIFF_DEPENDENCIES_FILE" + [[ $section == "Build environment" ]] && tldr_file="$TLDR_DIFF_BUILD_ENV_FILE" + + if [ -s "$tldr_file" ]; then + content=$(print_header "$section"; print_tldr "$(cat "$tldr_file")") + tldr_size=$(( tldr_size + ${#content} )) + fi +done + +# Function to check if content would fit +would_content_fit() { + if (( current_size + $1 < MAX_COMMENT_SIZE )); then + return 0 # Success/true - content will fit + else + return 1 # Failure/false - content won't fit + fi +} + +# Print content in order +for section in "Project dependencies" "Build environment"; do + tldr_file="$TLDR_DIFF_DEPENDENCIES_FILE" + tree_file="$DIFF_DEPENDENCIES_FILE" + [[ $section == "Build environment" ]] && tldr_file="$TLDR_DIFF_BUILD_ENV_FILE" && tree_file="$DIFF_BUILD_ENV_FILE" + + if [ -s "$tldr_file" ]; then + # Print section header and TLDR + print_header "$section" >> "$COMMENT_FILE" + print_tldr "$(cat "$tldr_file")" >> "$COMMENT_FILE" + current_size=$(wc -c < "$COMMENT_FILE") + + # Try to add tree if it exists + if [ -s "$tree_file" ]; then + tree_content=$(cat "$tree_file") + content=$(print_tree "$tree_content") + if would_content_fit ${#content}; then + echo -e "$content" >> "$COMMENT_FILE" + current_size=$(wc -c < "$COMMENT_FILE") + else + print_tree_too_large "$section" "$BUILDKITE_BUILD_URL" "$BUILDKITE_JOB_ID" >> "$COMMENT_FILE" + fi + fi + fi +done diff --git a/tests/test_craft_comment_with_dependency_diff.bats b/tests/test_craft_comment_with_dependency_diff.bats new file mode 100644 index 00000000..3c72108e --- /dev/null +++ b/tests/test_craft_comment_with_dependency_diff.bats @@ -0,0 +1,108 @@ +#!/usr/bin/env bats + +setup() { + # Get the directory of the test file + DIR="$( cd "$( dirname "$BATS_TEST_FILENAME" )" >/dev/null 2>&1 && pwd )" + + # Create a temporary directory for test artifacts + export TEMP_DIR="$(mktemp -d)" + export DIFF_DEPENDENCIES_FOLDER="$TEMP_DIR" + export COMMENT_FILE="$DIFF_DEPENDENCIES_FOLDER/comment_body.txt" + export TLDR_DIFF_DEPENDENCIES_FILE="$TEMP_DIR/tldr_dependencies.txt" + export TLDR_DIFF_BUILD_ENV_FILE="$TEMP_DIR/tldr_build_env.txt" + export DIFF_DEPENDENCIES_FILE="$TEMP_DIR/dependencies.txt" + export DIFF_BUILD_ENV_FILE="$TEMP_DIR/build_env.txt" + + # Mock Buildkite environment variables + export BUILDKITE_BUILD_URL="https://buildkite.com/test/build" + export BUILDKITE_JOB_ID="job123" +} + +teardown() { + rm -rf "$TEMP_DIR" +} + +@test "should create comment with both TLDRs and trees when content is small" { + # Create test dependency files with small content + echo "org.test:library:2.0.0 (from 1.0.0)" > "$TLDR_DIFF_DEPENDENCIES_FILE" + echo "org.test:build-tool:3.0.0 (from 2.0.0)" > "$TLDR_DIFF_BUILD_ENV_FILE" + + echo "+org.test:library:2.0.0 +-org.test:library:1.0.0" > "$DIFF_DEPENDENCIES_FILE" + + echo "+org.test:build-tool:3.0.0 +-org.test:build-tool:2.0.0" > "$DIFF_BUILD_ENV_FILE" + + # Run the script + run "$DIR/../bin/craft_comment_with_dependency_diff" + + # Assert success + [ "$status" -eq 0 ] + + # Read generated comment + local comment_content=$(<"$COMMENT_FILE") + + # Assert both sections are present + [[ "$comment_content" =~ "## Project dependencies changes" ]] + [[ "$comment_content" =~ "## Build environment changes" ]] + + # Assert both TLDRs are present + [[ "$comment_content" =~ "org.test:library:2.0.0 (from 1.0.0)" ]] + [[ "$comment_content" =~ "org.test:build-tool:3.0.0 (from 2.0.0)" ]] + + # Assert both trees are present + [[ "$comment_content" =~ "+org.test:library:2.0.0" ]] + [[ "$comment_content" =~ "+org.test:build-tool:3.0.0" ]] + + # Assert no "too large" warnings + [[ ! "$comment_content" =~ "tree is too large" ]] +} + +@test "should handle mixed tree sizes with large project dependencies" { + # Create large project dependencies tree + echo "org.test:library:2.0.0 (from 1.0.0)" > "$TLDR_DIFF_DEPENDENCIES_FILE" + + # Generate a large tree for project dependencies + local large_tree="" + for i in {1..1100}; do + large_tree+="+org.test:large-lib-${i}:2.0.0 +-org.test:large-lib-${i}:1.0.0 +" + done + echo "$large_tree" > "$DIFF_DEPENDENCIES_FILE" + + # Create small build environment changes + echo "org.test:build-tool:3.0.0 (from 2.0.0)" > "$TLDR_DIFF_BUILD_ENV_FILE" + echo "+org.test:build-tool:3.0.0 +-org.test:build-tool:2.0.0" > "$DIFF_BUILD_ENV_FILE" + + # Run the script + run "$DIR/../bin/craft_comment_with_dependency_diff" + + # Assert success + [ "$status" -eq 0 ] + + # Read generated comment + local comment_content=$(<"$COMMENT_FILE") + + echo "$comment_content"; + + # Assert both sections are present + [[ "$comment_content" =~ "## Project dependencies changes" ]] + [[ "$comment_content" =~ "## Build environment changes" ]] + + # Assert both TLDRs are present + [[ "$comment_content" =~ "org.test:library:2.0.0 (from 1.0.0)" ]] + [[ "$comment_content" =~ "org.test:build-tool:3.0.0 (from 2.0.0)" ]] + + # Assert small build environment tree is present + [[ "$comment_content" =~ "+org.test:build-tool:3.0.0" ]] + [[ "$comment_content" =~ "-org.test:build-tool:2.0.0" ]] + + # Assert large project dependencies tree is replaced with warning + [[ "$comment_content" =~ "Project dependencies tree is too large" ]] + [[ "$comment_content" =~ "View it in Buildkite artifacts" ]] + + # Assert only one "too large" warning + [[ ! "$comment_content" =~ "Build environment tree is too large" ]] +}