ci: add test governing workflow #32
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This workflow checks if integration tests are required, based on whether | |
# source code have been made. The workflow is triggered by the completion of | |
# the other workflows. | |
# | |
# If tests are required, the workflow will check | |
# the status of the integration tests job. If the integration tests job is | |
# successful, the workflow will report success. If the integration tests job | |
# has failed, the workflow will report failure. | |
# Governing Workflow: Evaluates the results of integration tests and file changes | |
# Determines if integration tests are required and reports success or failure. | |
name: Test Check Governing Workflow | |
on: | |
workflow_run: | |
types: | |
- completed | |
# List all of the conditional workflows here and at | |
# least one non-conditional workflow that will always run. | |
workflows: | |
- Pytest (Fast) | |
pull_request: | |
types: | |
- synchronize | |
push: | |
# This push.branches trigger can be used for testing. | |
# Otherwise the workflow only runs against the default branch. | |
branches: | |
- aj/ci/add-check-governing-workflow-check | |
jobs: | |
check_job_status: | |
runs-on: ubuntu-latest | |
env: | |
SHA: ${{ github.event_name == 'push' && github.sha || github.event.workflow_run.head_sha }} | |
IFS: ';' | |
# These are only required when code file paths are modified | |
CONDITIONAL_CHECK_NAMES: > | |
Pytest (Fast) | |
Pytest (Ubuntu, Python 3.10) | |
steps: | |
# Step 1: Checkout the codebase | |
- name: Checkout code | |
uses: actions/checkout@v3 | |
# Step 2: Check which relevant files have changed | |
- name: Check for Relevant File Changes | |
id: check_files_changed | |
uses: dorny/paths-filter@v2 | |
with: | |
filters: | | |
src: | |
- src/** | |
- tests/** | |
- unit_tests/** | |
- poetry.lock | |
- pyproject.toml | |
# Step 3: Fetch the statuses of specific checks using the REST API | |
- name: Fetch Check Statuses | |
id: check_job_status | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
# Declare array outputs we'll append to later | |
successes=() | |
failures=() | |
not_reported=() | |
read -r -a required_checks <<< "${CONDITIONAL_CHECK_NAMES//\n/;}" | |
# Debug: Print CONDITIONAL_CHECK_NAMES for verification | |
echo "Conditional Check Names: ${CONDITIONAL_CHECK_NAMES}" | |
# Debug: Print head SHA for verification | |
echo "Workflow Run Head SHA: ${SHA}" | |
# Query GitHub API for check statuses | |
response=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ | |
-H "Accept: application/vnd.github+json" \ | |
https://api.github.com/repos/${{ github.repository }}/commits/${SHA}/check-runs) | |
# Loop through each check result | |
for check in $(echo "$response" | jq -c '.check_runs[]'); do | |
# Debug: Print each check's raw JSON data for verification | |
name=$(echo "$check" | jq -r '.name') | |
if [[ " ${required_checks[@]} " =~ " $name " ]]; then | |
echo "Processing check: $check" | |
conclusion=$(echo "$check" | jq -r '.conclusion') | |
status=$(echo "$check" | jq -r '.status') | |
echo "$name status: $conclusion ($status)" | |
if [[ "$conclusion" == "failure" ]]; then | |
echo "Adding $name to failures." | |
failures+=("$name") | |
elif [[ "$conclusion" == "success" ]]; then | |
echo "Adding $name to successes." | |
successes+=("$name") | |
else | |
echo "Adding $name to not_reported." | |
not_reported+=("$name") | |
echo not_reported="${not_reported}" | |
echo not_reported="${not_reported[*]}" | |
fi | |
else | |
echo "Skipping check: $name" | |
fi | |
echo not_reported="${not_reported}" | |
done | |
echo not_reported="${not_reported}" | |
echo "Completed parsing check statuses." | |
# Output statuses for debugging (delimited by commas to avoid issues with spaces in names) | |
echo "successes=${successes[*]}" >> $GITHUB_ENV | |
echo "failures=${failures[*]}" >> $GITHUB_ENV | |
echo not_reported="${not_reported[*]}" | |
echo not_reported="${not_reported[*]}" >> $GITHUB_ENV | |
echo "Evaluating step results." | |
# Determine overall result | |
if [[ ${#failures[@]} -gt 0 ]]; then | |
echo "result=failure" >> $GITHUB_OUTPUT | |
elif [[ ${#not_reported[@]} -gt 0 ]]; then | |
echo "result=neutral" >> $GITHUB_OUTPUT | |
else | |
echo "result=success" >> $GITHUB_OUTPUT | |
fi | |
# Step 4: Fail the job if any check has failed | |
- name: Abort if failed | |
if: steps.check_job_status.outputs.result == 'failure' | |
run: | | |
echo "One or more checks failed." | |
exit 1 | |
# Step 5: Determine if integration tests are required | |
- name: Set Integration Tests Requirement | |
run: | | |
# Debug: Print output from paths-filter to verify file changes | |
echo "Files changed in src: ${{ steps.check_files_changed.outputs.src }}" | |
if [[ "${{ steps.check_files_changed.outputs.src }}" == 'true' ]]; then | |
echo "requires_integration_tests=true" >> $GITHUB_ENV | |
else | |
echo "requires_integration_tests=false" >> $GITHUB_ENV | |
fi | |
# Step 6: Report neutral if integration tests are still waiting. | |
- name: Report Neutral if Checks Still Waiting | |
if: ${{ env.requires_integration_tests == 'true' && env.not_reported != '' }} | |
run: | | |
echo "One or more tests have not completed yet." | |
exit 78 # Neutral exit code | |
# Step 7: Report success if all checks passed | |
- name: Report Success if All Checks Passed | |
if: steps.check_job_status.outputs.result == 'success' | |
run: | | |
echo "All required checks passed. Reporting success." |