From 7ac7a03e15e9f8eb00526252117634faf620ac4c Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Wed, 6 Nov 2024 13:44:33 -0700 Subject: [PATCH] Workflows: reworked how to skip eamxx testing jobs * Remove check-skip-labels action * For each eamxx workflow * Run two "generic" jobs on ubuntu-latest to - retrieve labels - check touched files Then, add skip logic to other jobs to avoid running if labels or touched files are not right --- .github/actions/check-skip-labels/README.md | 24 ----- .github/actions/check-skip-labels/action.yml | 48 --------- .github/workflows/eamxx-sa-testing.yml | 101 +++++++++++++------ .github/workflows/eamxx-scripts-tests.yml | 66 +++++++++--- .github/workflows/eamxx-v1-testing.yml | 70 +++++++++---- 5 files changed, 169 insertions(+), 140 deletions(-) delete mode 100644 .github/actions/check-skip-labels/README.md delete mode 100644 .github/actions/check-skip-labels/action.yml diff --git a/.github/actions/check-skip-labels/README.md b/.github/actions/check-skip-labels/README.md deleted file mode 100644 index 42d1e3bc64e..00000000000 --- a/.github/actions/check-skip-labels/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Composite action to check if we can skip a job for a PR - -This action is meant to be used inside a PR testing workflow, as - -```yaml -jobs: - my-testing: - steps: - ... - - name: check-pr-labels - if: github.event_name == "pull_request" || github.event_name == "pull_request_review" - uses: ./.github/actions/check-skip-labels - with: - skip_labels: label1,label2,label3 -``` - -The input skip_label is a comma-separated list of labels that, if found -on the PR, will cause this job to terminate immediately with a PASS state. - -Ideally, we would like to run this check at the job level, so that we can -skip the job altogether (without using runner time). But while for the -pull_request event we DO have access to the labels from the gh context -(and therefore can check), for pull_request_review we don't, so we need -to ping github for some information diff --git a/.github/actions/check-skip-labels/action.yml b/.github/actions/check-skip-labels/action.yml deleted file mode 100644 index 55d35bfa2b0..00000000000 --- a/.github/actions/check-skip-labels/action.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: 'Check Skip Labels' -description: 'Check for specific skip labels in a pull request' -inputs: - skip_labels: - description: 'Comma-separated list of skip labels' - required: true - token: - description: 'GitHub token for authentication' - required: true - pr_number: - description: 'Pull request number' - required: true - -# Note: inputs are available as env vars in the shell run steps, convertet to uppercase - -runs: - using: "composite" - steps: - - name: Get Pull Request Labels - run: | - echo "Fetching pull request labels..." - if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then - LABELS="$SKIP_LABELS" - elif [[ "$GITHUB_EVENT_NAME" == "pull_request_review" ]]; then - response=$(curl -s -H "Authorization: token $TOKEN" \ - "https://api.github.com/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER") - # TODO: reinstante jq once the SNL image is rebuilt! - # LABELS=$(echo "$response" | jq -r '.labels | map(.name) | join(",")') - LABELS=$(echo "$response" | grep -o '"name": *"[^"]*"' | sed 's/"name": *//;s/"//g' | tr '\n' ',' | sed 's/,$//') - fi - echo "labels=$LABELS" >> $GITHUB_ENV - shell: sh - - name: Check for Skip Labels - run: | - echo "Checking for skip labels..." - IFS=',' read -r -a SKIP_LABELS <<< "$SKIP_LABELS" - IFS=',' read -r -a LABEL_ARRAY <<< "$labels" - - for label in "${SKIP_LABELS[@]}"; do - for pr_label in "${LABEL_ARRAY[@]}"; do - if [[ "$pr_label" == "$label" ]]; then - echo "Found skip label '$label'. Skipping this job." - exit 0 # Exit with success status - fi - done - done - echo "No relevant skip labels found. Continuing with the job." - shell: sh diff --git a/.github/workflows/eamxx-sa-testing.yml b/.github/workflows/eamxx-sa-testing.yml index 12e45514ad0..2904a91b20f 100644 --- a/.github/workflows/eamxx-sa-testing.yml +++ b/.github/workflows/eamxx-sa-testing.yml @@ -5,17 +5,6 @@ on: pull_request: branches: [ master ] types: [opened, synchronize, ready_for_review, reopened] - paths: - - components/eamxx/** - - components/eam/src/physics/rrtmgp/** - - components/eam/src/physics/p3/scream/** - - components/eam/src/physics/cam/** - - .github/workflows/eamxx-standalone-testing.yml - - externals/ekat/** - - externals/scorpio/** - - externals/haero/** - - externals/YAKL/** - - components/eam/src/physics/rrtmgp/external/** # Manual run is used to bless workflow_dispatch: @@ -48,15 +37,70 @@ env: submit: ${{ github.event_name == 'schedule' && 'true' || 'false' }} # Submit to cdash only for nightlies jobs: + pr_relevant: + if: ${{ github.event_name == 'pull_request' }} + runs-on: ubuntu-latest # This job can run anywhere + outputs: + value: ${{ steps.check_paths.outputs.touched }} + steps: + - name: check_paths + run: | + paths=( + components/eamxx + components/eam/src/physics/rrtmgp + components/eam/src/physics/p3/scream + components/eam/src/physics/cam + components/eam/src/physics/rrtmgp/external + externals/ekat + externals/scorpio + externals/haero + externals/YAKL + .github/workflows/eamxx-sa-testing.yml + ) + pattern=$(IFS=\|; echo "${paths[*]}") + + # Use the GitHub API to get the list of changed files + response=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.number }}/files") + changed_files=$(echo "$response" | grep -o '"filename": *"[^"]*"' | sed 's/"filename": *//; s/"//g') + + # Check for matches and echo the matching files (or "" if none) + matching_files=$(echo "$changed_files" | grep -E "^($pattern)" || echo "") + if [[ -n "$matching_files" ]]; then + echo "Found relevant files: $matching_files" + echo "touched=true" >> $GITHUB_OUTPUT + else + echo "No relevant files touched by this PR." + echo "touched=false" >> $GITHUB_OUTPUT + fi + get_labels: + if: ${{ github.event_name == 'pull_request' }} + runs-on: ubuntu-latest + outputs: + labels: ${{ steps.get_labels.outputs.labels }} + steps: + - name: get_labels + run: | + labels="${{ join(github.event.pull_request.labels.*.name, ',') }}" + echo "labels=${labels}" >> $GITHUB_OUTPUT gcc-openmp: + needs: [pr_relevant, get_labels] + if: | + (github.event_name == 'pull_request' && + needs.pr_relevant.outputs.value=='true' && + !contains(needs.get_labels.outputs.labels,'CI: skip gcc') && + !contains(needs.get_labels.outputs.labels,'CI: skip openmp') && + !contains(needs.get_labels.outputs.labels,'CI: skip eamxx-sa') && + !contains(needs.get_labels.outputs.labels,'CI: skip eamxx-all')) || + (github.event_name == 'workflow_dispatch' && + github.event.inputs.job_to_run == 'gcc-openmp' || + github.event.inputs.job_to_run == 'all') || + github.event_name == 'schedule' runs-on: [self-hosted, ghci-snl-cpu, gcc] strategy: fail-fast: false matrix: build_type: [sp, dbg, fpe, opt] - if: ${{ github.event_name != 'workflow_dispatch' || - github.event.inputs.job_to_run == 'gcc-openmp' || - github.event.inputs.job_to_run == 'all' }} name: gcc-openmp / ${{ matrix.build_type }} steps: - name: Check out the repository @@ -67,13 +111,6 @@ jobs: submodules: recursive - name: Show action trigger uses: ./.github/actions/show-workflow-trigger - - name: Check for skip labels - if: ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_review' }} - uses: ./.github/actions/check-skip-labels - with: - skip_labels: 'AT: skip gcc,AT: skip openmp,AT: skip eamxx-sa,AT: skip eamxx-all' - token: ${{ secrets.GITHUB_TOKEN }} - pr_number: ${{ github.event.pull_request.number }} - name: Set test-all inputs based on event specs run: | echo "generate=false" >> $GITHUB_ENV @@ -91,14 +128,23 @@ jobs: submit: ${{ env.submit }} cmake-configs: Kokkos_ENABLE_OPENMP=ON gcc-cuda: + needs: [pr_relevant, get_labels] + if: | + (github.event_name == 'pull_request' && + needs.pr_relevant.outputs.value=='true' && + !contains(needs.get_labels.outputs.labels,'CI: skip gcc') && + !contains(needs.get_labels.outputs.labels,'CI: skip cuda') && + !contains(needs.get_labels.outputs.labels,'CI: skip eamxx-sa') && + !contains(needs.get_labels.outputs.labels,'CI: skip eamxx-all')) || + (github.event_name == 'workflow_dispatch' && + github.event.inputs.job_to_run == 'gcc-cuda' || + github.event.inputs.job_to_run == 'all') || + github.event_name == 'schedule' runs-on: [self-hosted, ghci-snl-cuda, cuda, gcc] strategy: fail-fast: false matrix: build_type: [sp, dbg, opt] - if: ${{ github.event_name != 'workflow_dispatch' || - github.event.inputs.job_to_run == 'gcc-cuda' || - github.event.inputs.job_to_run == 'all' }} name: gcc-cuda / ${{ matrix.build_type }} steps: - name: Check out the repository @@ -109,13 +155,6 @@ jobs: submodules: recursive - name: Show action trigger uses: ./.github/actions/show-workflow-trigger - - name: Check for skip labels - if: ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_review' }} - uses: ./.github/actions/check-skip-labels - with: - skip_labels: 'AT: skip gcc,AT: skip cuda,AT: skip eamxx-sa,AT: skip eamxx-all' - token: ${{ secrets.GITHUB_TOKEN }} - pr_number: ${{ github.event.pull_request.number }} - name: Set test-all inputs based on event specs run: | echo "generate=false" >> $GITHUB_ENV diff --git a/.github/workflows/eamxx-scripts-tests.yml b/.github/workflows/eamxx-scripts-tests.yml index bd719539bab..87bf5218f50 100644 --- a/.github/workflows/eamxx-scripts-tests.yml +++ b/.github/workflows/eamxx-scripts-tests.yml @@ -5,15 +5,6 @@ on: pull_request: branches: [ master ] types: [opened, synchronize, ready_for_review, reopened] - paths: - - components/eamxx/scripts/** - - components/eamxx/cime_config/*.py - - .github/workflows/eamxx-scripts-tests.yml - - externals/ekat/** - - externals/scorpio/** - - externals/haero/** - - externals/YAKL/** - - components/eam/src/physics/rrtmgp/external/** # Manual run for debug purposes only workflow_dispatch: @@ -30,7 +21,57 @@ concurrency: cancel-in-progress: true jobs: + pr_relevant: + if: ${{ github.event_name == 'pull_request' }} + runs-on: ubuntu-latest # This job can run anywhere + outputs: + value: ${{ steps.check_paths.outputs.touched }} + steps: + - name: check_paths + id: check_paths + run: | + paths=( + components/eamxx/scripts + components/eamxx/cime_config/eamxx + components/eamxx/cime_config/build + components/eamxx/cime_config/yaml_utils.py + .github/workflows/eamxx-scripts-tests.yml + ) + pattern=$(IFS=\|; echo "${paths[*]}") + + # Use the GitHub API to get the list of changed files + response=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.number }}/files") + changed_files=$(echo "$response" | grep -o '"filename": *"[^"]*"' | sed 's/"filename": *//; s/"//g') + + # Check for matches and echo the matching files (or "" if none) + matching_files=$(echo "$changed_files" | grep -E "^($pattern)" || echo "") + if [[ -n "$matching_files" ]]; then + echo "Found relevant files: $matching_files" + echo "touched=true" >> $GITHUB_OUTPUT + else + echo "No relevant files touched by this PR." + echo "touched=false" >> $GITHUB_OUTPUT + fi + get_labels: + if: ${{ github.event_name == 'pull_request' }} + runs-on: ubuntu-latest + outputs: + labels: ${{ steps.get_labels.outputs.labels }} + steps: + - name: get_labels + id: get_labels + run: | + labels="${{ join(github.event.pull_request.labels.*.name, ',') }}" + echo "labels=${labels}" >> $GITHUB_OUTPUT cpu-gcc: + needs: [pr_relevant, get_labels] + if: | + github.event_name != 'pull_request' || + ( + needs.pr_relevant.outputs.value == 'true' && + !contains(needs.get_labels.outputs.labels, 'CI: skip eamxx-all') + ) runs-on: [self-hosted, gcc, ghci-snl-cpu] steps: - name: Check out the repository @@ -41,13 +82,6 @@ jobs: submodules: recursive - name: Show action trigger uses: ./.github/actions/show-workflow-trigger - - name: Check for skip labels - if: ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_review' }} - uses: ./.github/actions/check-skip-labels - with: - skip_labels: 'AT: skip eamxx-all' - token: ${{ secrets.GITHUB_TOKEN }} - pr_number: ${{ github.event.pull_request.number }} - name: Run test run: | cd components/eamxx diff --git a/.github/workflows/eamxx-v1-testing.yml b/.github/workflows/eamxx-v1-testing.yml index 47129159f82..77c270678ad 100644 --- a/.github/workflows/eamxx-v1-testing.yml +++ b/.github/workflows/eamxx-v1-testing.yml @@ -5,17 +5,6 @@ on: pull_request: branches: [ master ] types: [opened, synchronize, ready_for_review, reopened] - paths: - - components/eamxx/** - - components/eam/src/physics/rrtmgp/** - - components/eam/src/physics/p3/scream/** - - components/eam/src/physics/cam/** - - .github/workflows/eamxx-v1-testing.yml - - externals/ekat/** - - externals/scorpio/** - - externals/haero/** - - externals/YAKL/** - - components/eam/src/physics/rrtmgp/external/** # Manual run is used to bless workflow_dispatch: @@ -40,7 +29,56 @@ concurrency: cancel-in-progress: true jobs: + pr_relevant: + if: ${{ github.event_name == 'pull_request' }} + runs-on: ubuntu-latest # This job can run anywhere + outputs: + value: ${{ steps.check_paths.outputs.touched }} + steps: + - name: check_paths + run: | + paths=( + components/eamxx + components/eam/src/physics/rrtmgp + components/eam/src/physics/p3/scream + components/eam/src/physics/cam + components/eam/src/physics/rrtmgp/external + externals/ekat + externals/scorpio + externals/haero + externals/YAKL + .github/workflows/eamxx-v1-testing.yml + ) + pattern=$(IFS=\|; echo "${paths[*]}") + + # Use the GitHub API to get the list of changed files + response=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.number }}/files") + changed_files=$(echo "$response" | grep -o '"filename": *"[^"]*"' | sed 's/"filename": *//; s/"//g') + + # Check for matches and echo the matching files (or "" if none) + matching_files=$(echo "$changed_files" | grep -E "^($pattern)" || echo "") + if [[ -n "$matching_files" ]]; then + echo "Found relevant files: $matching_files" + echo "touched=true" >> $GITHUB_OUTPUT + else + echo "No relevant files touched by this PR." + echo "touched=false" >> $GITHUB_OUTPUT + fi + get_labels: + if: ${{ github.event_name == 'pull_request' }} + runs-on: ubuntu-latest + outputs: + labels: ${{ steps.get_labels.outputs.labels }} + steps: + - name: get_labels + run: | + labels="${{ join(github.event.pull_request.labels.*.name, ',') }}" + echo "labels=${labels}" >> $GITHUB_OUTPUT cpu-gcc: + needs: [pr_relevant, get_labels] + if: | + needs.pr_relevant.outputs.value=='true' runs-on: [self-hosted, gcc, ghci-snl-cpu] strategy: matrix: @@ -55,9 +93,6 @@ jobs: short_name: SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-all_mam4xx_procs fail-fast: false name: cpu-gcc / ${{ matrix.test.short_name }} - if: ${{ github.event_name != 'workflow_dispatch' || - github.event.inputs.job_to_run == 'cpu-gcc' || - github.event.inputs.job_to_run == 'all' }} steps: - name: Check out the repository uses: actions/checkout@v4 @@ -67,13 +102,6 @@ jobs: submodules: recursive - name: Show action trigger uses: ./.github/actions/show-workflow-trigger - - name: Check for skip labels - if: ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_review' }} - uses: ./.github/actions/check-skip-labels - with: - skip_labels: 'AT: skip gcc,AT: skip openmp,AT: skip eamxx-sa,AT: skip eamxx-all' - token: ${{ secrets.GITHUB_TOKEN }} - pr_number: ${{ github.event.pull_request.number }} - name: Set CA certificates env var run: | # Ensure the operating system is Linux