Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: add test governing workflow #86

Closed
wants to merge 18 commits into from
154 changes: 154 additions & 0 deletions .github/workflows/job_status_check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# 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
curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/repos/${{ github.repository }}/commits/${SHA}/check-runs >> RESPONSE.json

# Loop through each check result
for check in $(cat RESPONSE.json | 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."
Loading