#!/usr/bin/env bash # # Usage: affected-projects.sh [base-commit] # # Runs the checkAffected task of every project for the changes between the base commit and HEAD # and writes the result to $GITHUB_OUTPUT: # projects - space separated paths of the affected projects # tasks - space separated Gradle tasks to run (empty if nothing is affected) # # The projects exchange files with this script through the state directory. If it contains # previous-dependency-versions (deploys only), projects whose resolved dependency versions changed are # affected as well and the collected dependency-versions, deploy-artifacts and deploy-commands of all # projects are written to it. Without a known base commit everything is affected. set -euo pipefail shopt -s nullglob mkdir -p "$1" state="$(realpath "$1")" base="${2:-}" deploy=false if [[ -f "${state}/previous-dependency-versions" ]]; then deploy=true fi # Whether the diff of settings.gradle.kts only touches library versions of the version catalog catalog_only() { ! git diff -U0 --no-renames "$base" HEAD -- settings.gradle.kts \ | grep -E '^[+-]' \ | grep -vE '^(\+\+\+|---) ' \ | grep -qvE '^[+-][[:space:]]*(library\("|val [A-Za-z]+Version = "|$)' } # All lines the projects wrote for the given kind collect() { local files=("${state}/projects/$1"/*) if (( ${#files[@]} )); then sort "${files[@]}" fi } rm -f "${state}/changed-files" if [[ -z "$base" ]]; then echo "No base commit, everything is affected" elif ! git cat-file -e "${base}^{commit}" 2>/dev/null; then echo "Base commit ${base} is unknown, everything is affected" else echo "Changed files since ${base}:" git diff --name-only --no-renames "$base" HEAD | tee "${state}/changed-files" # Library version changes are detected through the resolved dependency versions of the projects using them if [[ "$deploy" == "true" ]] && grep -qx 'settings.gradle.kts' "${state}/changed-files" && catalog_only; then echo "settings.gradle.kts only changed library versions, relying on the dependency versions" grep -vx 'settings.gradle.kts' "${state}/changed-files" > "${state}/changed-files.filtered" || true mv "${state}/changed-files.filtered" "${state}/changed-files" fi fi args=(-q --no-daemon checkAffected -PciDir="$state") if [[ "$deploy" == "true" ]]; then args+=(deployInfo --refresh-dependencies) fi ./gradlew "${args[@]}" if [[ "$deploy" == "true" ]]; then collect dependency-versions > "${state}/dependency-versions" collect deploy-artifacts > "${state}/deploy-artifacts" collect deploy-commands > "${state}/deploy-commands" fi projects="$(collect affected | cut -d ' ' -f 1 | sort -u | paste -sd ' ' -)" tasks="$(collect affected | cut -d ' ' -f 1 | sort -u | sed 's/$/:build/' | paste -sd ' ' -)" echo "projects=${projects}" echo "tasks=${tasks}" { echo "projects=${projects}" echo "tasks=${tasks}" } >> "$GITHUB_OUTPUT"