diff --git a/.github/workflows/build-check-install.yaml b/.github/workflows/build-check-install.yaml index 681b227f..17a41638 100644 --- a/.github/workflows/build-check-install.yaml +++ b/.github/workflows/build-check-install.yaml @@ -246,6 +246,14 @@ on: required: false type: boolean default: false + fast-tests: + description: | + Should shinytests2 tests only run per modified module? + If enabled and there is a module modificated only that shinytest2 file will be tested. + Can be ignored if used [run-all-tests] on the commit message. + required: false + type: boolean + default: false concurrency: group: r-cmd-${{ inputs.concurrency-group }}-${{ github.event.pull_request.number || github.ref }} @@ -294,7 +302,6 @@ jobs: uses: actions/checkout@v4.1.1 if: github.event_name == 'pull_request' with: - ref: ${{ steps.branch-name.outputs.head_ref_branch }} path: ${{ github.event.repository.name }} repository: ${{ github.event.pull_request.head.repo.full_name }} fetch-depth: 0 @@ -514,6 +521,80 @@ jobs: with: path: "${{ inputs.additional-caches }}" key: additional-caches-${{ runner.os }} + steps: + - name: Get changed files 📃 + id: changed-files + uses: tj-actions/changed-files@v45 + with: + path: ${{ github.event.repository.name }}/${{ inputs.package-subdirectory }} + files: | + tests/testthat/**.R + R/**.R + + - name: Check only affected modules 🎯 + if: inputs.fast-tests == true + working-directory: ${{ github.event.repository.name }}/${{ inputs.package-subdirectory }} + env: + ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} + run: | + # Bash script run + commit_msg=$( git log -1 --pretty=%B ) + + echo "Commit msg is ${commit_msg}" + # Exit early if tag is on commit message even if it set to true + test_all=$( echo "${commit_msg}" | grep -zvF "[run-all-tests]" | tr -d '\0') + + if [ -z "$test_all" ] + then { + echo "Last commit message forces to test everything." + exit 0 + } fi + + test_dir="tests/testthat/" + + if [ -z "${ALL_CHANGED_FILES} ] + then { + echo "No R files affected: test everything." + exit 0 + } fi + + # Loop through each modified file and determine which tests to run + for file in "${ALL_CHANGED_FILES}"; do + + echo "Check for $file" + + # Extract the base name of the file, examples: + # tests/testthat/test-shinytest2-foo.R -> foo + # R/foo.R -> foo + base_name=$(basename "$file" .R | sed s/test-shinytest2-//g) + # Find matching test files (parenthesis to not match arguments) + test_files=$(grep -l "$base_name(" "$test_dir"test-shinytest2-*.R) + td=$TESTING_DEPTH + + # Modify in place so that only modified modules are tested. + if [ -n "$test_files" ] && [ -n "$test_all" ]; + then { + sed -i 's/skip_if_too_deep(5)/skip_if_too_deep(3)/g' "$test_files" + export TESTING_DEPTH="3" + echo "Testing with shinytest2 for $test_files"; + echo "Settin testing_depth=$TESTING_DEPTH" + } else { + # Flag for helpers + helper_modified="yes" + git restore $test_dir + echo "Run all tests" + break; + } fi + + # R file without corresponding test file: reset the testing depth + if [ -n "$helper_modified" ] || [ -z "$test_all" ]; + then { + echo "Skip step or helper modifications detected." + export TESTING_DEPTH="$td"; + } fi + done + echo Using "TESTING_DEPTH=${TESTING_DEPTH}" + shell: bash - name: Build R package 🏗 run: |