diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 589a447..5043566 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -1,7 +1,6 @@ name: Check on: - pull_request_target: - types: [edited, opened, reopened, synchronize] + pull_request: concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -39,21 +38,29 @@ jobs: if [[ $INPUT_TITLE =~ \[(.*)\] ]]; then NEW_BUMP_TYPE="${BASH_REMATCH[1]}" else - echo "Bump type not found" >&2; exit 1; - fi - if [[ "$NEW_BUMP_TYPE" == "none" ]]; then - echo "Bump type none, skip compare" - exit 0 + echo "Bump type not found. Please specify bump type in your pull request title. Example: [patch] fix very annoying bug." >&2; exit 1; fi + git fetch + base_branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}} target_branch=${{ github.event.pull_request.base.ref }} + chmod +x ./scripts/helpers/build_and_dump.sh chmod +x ./scripts/helpers/abi_comparator.sh + base_tmp_dir=$(mktemp -d) - base_abi_dump_path=$(./scripts/helpers/build_and_dump.sh $base_tmp_dir) - git checkout -b target_branch + IFS=$'\n' read -r -d '' base_abi_dump_path base_api_dump_path < <(./scripts/helpers/build_and_dump.sh $base_tmp_dir) + + git checkout $target_branch target_tmp_dir=$(mktemp -d) - target_abi_dump_path=$(./scripts/helpers/build_and_dump.sh $target_tmp_dir) - ./scripts/helpers/abi_comparator.sh $base_tmp_dir $target_abi_dump_path $base_abi_dump_path $NEW_BUMP_TYPE - + IFS=$'\n' read -r -d '' target_abi_dump_path target_api_dump_path < <(./scripts/helpers/build_and_dump.sh $target_tmp_dir) + + git checkout $base_branch + + sources_changed=false + if git diff --name-only $target_branch $base_branch | grep -q "^Sources/ProjectDescription/"; then + sources_changed=true + fi + + ./scripts/helpers/abi_comparator.sh $base_tmp_dir $target_abi_dump_path $base_abi_dump_path $target_api_dump_path $base_api_dump_path $sources_changed $NEW_BUMP_TYPE diff --git a/scripts/helpers/abi_comparator.sh b/scripts/helpers/abi_comparator.sh index eb9df0c..6dadeb4 100755 --- a/scripts/helpers/abi_comparator.sh +++ b/scripts/helpers/abi_comparator.sh @@ -11,10 +11,12 @@ log_info() { echo "ℹ️ $1"; } # Input TMP_DIR=$1 -PREV_DUMP_PATH=$2 +PREV_ABI_DUMP_PATH=$2 CURRENT_ABI_DUMP_PATH=$3 -BUMP_TYPE=$4 - +PREV_API_DUMP_PATH=$4 +CURRENT_API_DUMP_PATH=$5 +SOURCES_CHANGED=$6 +BUMP_TYPE=$7 get_priority() { case "$1" in @@ -33,71 +35,85 @@ prepare_dump() { jq 'walk(if type == "object" then del(.deprecated) else . end)' "$input_path" > "$output_path" } -bump_type_from_report() { - local report_path=$1 - local bump_type=$2 - local suitable_bump="patch" - - while IFS= read -r line; do - # Skip system messages - [[ $line =~ ^[0-9]+\ (error|warning)s?\ generated\. ]] && continue - [[ $line =~ xcodebuild\[.*\]\ Requested\ but\ did\ not\ find\ extension\ point ]] && continue - [[ -z "$line" ]] && continue - - # Parse: :: : - if [[ $line =~ :([0-9]+):\ (error|warning):\ (.+)$ ]]; then - local type="${BASH_REMATCH[2]}" - local message="${BASH_REMATCH[3]}" - - if [[ "$type" == "warning" ]]; then - echo "⚠️ $message" - elif [[ "$type" == "error" ]]; then - echo "⛔️ $message" - suitable_bump="minor" - fi - else - log_error "Invalid output line: $line" - fi - done < $report_path - - # Validate real and expected bump types - weight_bump_type=$(get_priority "$bump_type") - weight_suitable_bump=$(get_priority "$suitable_bump") - if (( weight_bump_type < weight_suitable_bump )); then - log_error "Wrong bump_type '$bump_type' specified. Suitable is '$suitable_bump'." - else - log_success "Suitable bump_type is '$suitable_bump', specified is '$bump_type'" - fi +validate_bump_type() { + local abi_report_path=$1 + local api_report_path=$2 + local bump_type=$3 + local suitable_bump="none" + + if [ $SOURCES_CHANGED = true ]; then + suitable_bump="patch" + fi + + while IFS= read -r line; do + # Skip system messages + [[ $line =~ ^[0-9]+\ (error|warning)s?\ generated\. ]] && continue + [[ $line =~ xcodebuild\[.*\]\ Requested\ but\ did\ not\ find\ extension\ point ]] && continue + [[ -z "$line" ]] && continue + + # Parse: :: : + if [[ $line =~ :([0-9]+):\ (error|warning):\ (.+)$ ]]; then + local type="${BASH_REMATCH[2]}" + local message="${BASH_REMATCH[3]}" + + if [[ "$type" == "warning" ]]; then + echo "⚠️ $message" + elif [[ "$type" == "error" ]]; then + echo "⛔️ $message" + suitable_bump="minor" + fi + else + log_error "Invalid output line: $line" + fi + done < $abi_report_path + + #TODO: Implement API comparison + + # Validate real and expected bump types + weight_bump_type=$(get_priority "$bump_type") + weight_suitable_bump=$(get_priority "$suitable_bump") + if (( weight_bump_type < weight_suitable_bump )); then + log_error "Wrong bump_type '$bump_type' specified. Suitable is '$suitable_bump'." + else + log_success "Suitable bump_type is '$suitable_bump', specified is '$bump_type'" + fi } -if [[ -f "$FILE_VAR" ]]; then - echo "$FILE_VAR exists and is a regular file." -else - echo "$FILE_VAR is not a regular file or does not exist." -fi - -# Loading an old dump - # Prepare old dump (remove all "deprecated") -log_info "Prepare old dump" -old_prepared_path="$TMP_DIR/old-prepared.json" -prepare_dump "$PREV_DUMP_PATH" "$old_prepared_path" -log_success "Dump prepared" +# log_info "Prepare old dump" +# old_prepared_path="$TMP_DIR/old-prepared.json" +# prepare_dump "$PREV_ABI_DUMP_PATH" "$old_prepared_path" +# log_success "Dump prepared" # ABI compare -report_path="$TMP_DIR/breakage-report.log" +abi_report_path="$TMP_DIR/abi_breakage-report.log" log_info "Comparing ABI..." -# WARNING: not work on x86_64 +# WARNING: does not work for x86_64 set +e # Allow swift-api-digester to return a non-zero code xcrun swift-api-digester \ -diagnose-sdk \ - -input-paths "$old_prepared_path" \ + -input-paths "$PREV_ABI_DUMP_PATH" \ -input-paths "$CURRENT_ABI_DUMP_PATH" \ -disable-fail-on-error \ -compiler-style-diags \ -abi \ - -error-on-abi-breakage 2> "$report_path" + -error-on-abi-breakage 2> "$abi_report_path" +set -e + +# API compare +api_report_path="$TMP_DIR/api_breakage-report.log" +log_info "Comparing API..." + +# WARNING: does not work for x86_64 +set +e # Allow swift-api-digester to return a non-zero code +xcrun swift-api-digester \ + -diagnose-sdk \ + -input-paths "$PREV_API_DUMP_PATH" \ + -input-paths "$CURRENT_API_DUMP_PATH" \ + -disable-fail-on-error \ + -compiler-style-diags \ + -error-on-abi-breakage 2> "$api_report_path" set -e -bump_type_from_report $report_path $BUMP_TYPE +validate_bump_type $abi_report_path $api_report_path $BUMP_TYPE diff --git a/scripts/helpers/build_and_dump.sh b/scripts/helpers/build_and_dump.sh index 8bcd599..4a96ed2 100755 --- a/scripts/helpers/build_and_dump.sh +++ b/scripts/helpers/build_and_dump.sh @@ -12,7 +12,8 @@ tmp_build_dir="$tmp_dir/build" module_name="ProjectDescription" configuration="Release" framework_path="${tmp_build_dir}/${configuration}" -output_path="$tmp_dir/current-abi.json" +output_abi_path="$tmp_dir/current-abi.json" +output_api_path="$tmp_dir/current-api.json" xcrun xcodebuild -scheme ProjectDescription \ -configuration "$configuration" \ @@ -37,6 +38,21 @@ xcrun swift-api-digester \ -abi \ -sdk "$sdk_path" \ -target "arm64-apple-macos" \ - -o "$output_path" + -o "$output_abi_path" -echo $output_path \ No newline at end of file +xcrun swift-api-digester \ + -dump-sdk \ + -abort-on-module-fail \ + -module "$module_name" \ + -use-interface-for-module "$module_name" \ + -F "$framework_path" \ + -I "$framework_path" \ + -avoid-tool-args \ + -avoid-location \ + -sdk "$sdk_path" \ + -target "arm64-apple-macos" \ + -o "$output_api_path" + +echo $output_abi_path +echo $output_api_path +printf '\0'