diff --git a/.github/workflows/java.yml b/.github/workflows/java.yml index ef2f2017e..2e43b527a 100644 --- a/.github/workflows/java.yml +++ b/.github/workflows/java.yml @@ -11,34 +11,68 @@ on: workflow_dispatch: jobs: - build: + build-all: name: Check if tests compile cleanly with starter sources + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-24.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - - name: Set up JDK 21 + - name: Set up JDK 25 uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 with: - java-version: 21 + java-version: 25 distribution: "temurin" - name: Check if tests compile cleanly with starter sources run: ./gradlew compileStarterTestJava --continue working-directory: exercises - lint: - name: Lint Java files using Checkstyle + build-changed: + name: Check if changed exercise tests compile cleanly with starter sources + if: github.event_name == 'pull_request' + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + fetch-depth: 0 + - name: Set up JDK 25 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 + with: + java-version: 25 + distribution: "temurin" + - name: Check if changed exercise tests compile cleanly + run: bin/build-changed-exercise + + lint-all: + name: Lint all Java files using Checkstyle + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-24.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - - name: Set up JDK 21 + - name: Set up JDK 25 uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 with: - java-version: 21 + java-version: 25 distribution: "temurin" - name: Run checkstyle run: ./gradlew check --exclude-task test --continue working-directory: exercises + lint-changed: + name: Lint changed Java exercises using Checkstyle + if: github.event_name == 'pull_request' + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + fetch-depth: 0 + - name: Set up JDK 25 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 + with: + java-version: 25 + distribution: "temurin" + - name: Lint changed exercises + run: bin/lint-changed-exercise + test-all: name: Test all exercises using java-test-runner if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' diff --git a/bin/build-changed-exercise b/bin/build-changed-exercise new file mode 100755 index 000000000..9238b6744 --- /dev/null +++ b/bin/build-changed-exercise @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +set -eo pipefail + +source "$(dirname "$0")/common.sh" + +# If any Gradle build file changed, run the full suite and exit +check_gradle_changes \ + "cd exercises && ./gradlew compileStarterTestJava --continue" \ + "Gradle build files changed, running full build suite..." + +if [ -z "$changed_exercises" ]; then + echo "No relevant exercises changed, skipping compile checks." + exit 0 +fi + +# Print exercises +echo "Changed exercises detected:" +echo "$changed_exercises" +echo "----------------------------------------" + +# Run build compile checks +exit_code=0 +for dir in $changed_exercises; do + slug=$(basename "$dir") + + echo "========================================" + echo "=== Running compileStarterTestJava for $slug ===" + echo "========================================" + + if [[ $dir == exercises/practice/* ]]; then + ./exercises/gradlew -p exercises ":practice:$slug:compileStarterTestJava" || exit_code=1 + elif [[ $dir == exercises/concept/* ]]; then + ./exercises/gradlew -p exercises ":concept:$slug:compileStarterTestJava" || exit_code=1 + fi +done + +exit $exit_code diff --git a/bin/common.sh b/bin/common.sh new file mode 100755 index 000000000..9a84eb6d8 --- /dev/null +++ b/bin/common.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -eo pipefail + +# Determine the base branch of the PR +BASE_BRANCH=${GITHUB_BASE_REF:-main} + +# Fetch full history for proper diff +git fetch origin "$BASE_BRANCH" + +# Compute merge base +MERGE_BASE=$(git merge-base HEAD origin/"$BASE_BRANCH") + +# Get changed files relative to merge base +changed_files=$(git diff --name-only "$MERGE_BASE" HEAD) + +# Function to check if Gradle build files changed and run a command +check_gradle_changes() { + local command="$1" + local message="$2" + + if echo "$changed_files" | grep -qE '(\.gradle|gradlew|\.bat|settings\.gradle|gradle-wrapper\.(properties|jar))$'; then + echo "$message" + eval "$command" + exit 0 + fi +} + +# Extract unique exercise directories +get_changed_exercises() { + echo "$changed_files" | \ + grep -E '^exercises/(practice|concept)/[^/]+/.+\.java$' | \ + cut -d/ -f1-3 | sort -u || true +} + +# Variable for reuse +changed_exercises=$(get_changed_exercises) diff --git a/bin/lint-changed-exercise b/bin/lint-changed-exercise new file mode 100755 index 000000000..bbb6efc26 --- /dev/null +++ b/bin/lint-changed-exercise @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +set -eo pipefail + +source "$(dirname "$0")/common.sh" + +# If any Gradle build file changed, run the full suite and exit +check_gradle_changes \ + "cd exercises && ./gradlew check --exclude-task test --continue" \ + "Gradle build files changed, running full lint suite..." + +if [ -z "$changed_exercises" ]; then + echo "No relevant exercises changed, skipping linting." + exit 0 +fi + +# Print exercises +echo "Changed exercises detected:" +echo "$changed_exercises" +echo "----------------------------------------" + +# Run lint checks +exit_code=0 +for dir in $changed_exercises; do + slug=$(basename "$dir") + + echo "========================================" + echo "=== Running checkstyle for $slug ===" + echo "========================================" + + if [[ $dir == exercises/practice/* ]]; then + ./exercises/gradlew -p exercises ":practice:$slug:check" --exclude-task test || exit_code=1 + elif [[ $dir == exercises/concept/* ]]; then + ./exercises/gradlew -p exercises ":concept:$slug:check" --exclude-task test || exit_code=1 + fi +done + +exit $exit_code diff --git a/bin/test-changed-exercise b/bin/test-changed-exercise index b18a488e8..4e71b25a4 100755 --- a/bin/test-changed-exercise +++ b/bin/test-changed-exercise @@ -1,29 +1,12 @@ #!/usr/bin/env bash set -eo pipefail -# Determine the base branch of the PR -BASE_BRANCH=${GITHUB_BASE_REF:-main} - -# Fetch full history for proper diff -git fetch origin "$BASE_BRANCH" - -# Compute merge base -MERGE_BASE=$(git merge-base HEAD origin/"$BASE_BRANCH") - -# Get changed files relative to merge base -changed_files=$(git diff --name-only "$MERGE_BASE" HEAD) +source "$(dirname "$0")/common.sh" # If any Gradle build file changed, run the full suite and exit -if echo "$changed_files" | grep -qE '\.(gradle|gradlew|bat)$|settings\.gradle'; then - echo "Gradle build files changed, running full test suite..." - ./bin/test-with-test-runner - exit 0 -fi - -# Extract unique exercise directories -changed_exercises=$(echo "$changed_files" | \ - grep -E '^exercises/(practice|concept)/[^/]+/.+\.java$' | \ - cut -d/ -f1-3 | sort -u) +check_gradle_changes \ + "./bin/test-with-test-runner" \ + "Gradle build files changed, running full test suite..." if [ -z "$changed_exercises" ]; then echo "No relevant exercises changed, skipping tests."