Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 115 additions & 6 deletions .github/workflows/testsPython.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ name: Python Unit Tests

on:
workflow_dispatch: # Allows the workflow to be manually triggered from the GitHub Actions tab
inputs:
notify_email:
description: 'Recipient email(s) for failure notification (comma-separated)'
required: false
default: ''
pull_request: #
paths: # Trigger workflow on pull requests, but
- "**.py" # only if Python files are changed
Expand Down Expand Up @@ -64,16 +69,120 @@ jobs:

# Job #2: Notifications (Mini-capstone assignment)
# This job will run after the Python unit tests and
# is scaffolded to facilitate sending notifications based
# on the test results.
# sends notifications when tests fail via Slack, email, and GitHub Issues.
# if: always() is required — without it GitHub skips this job when the
# upstream job fails, which defeats the purpose.
notifications:
needs: python-unit-tests
runs-on: ubuntu-latest
if: always()
permissions:
issues: write
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
MAIL_USERNAME: ${{ secrets.MAIL_USERNAME }}
steps:
- name: Notify on test results
- name: Write job summary
if: always()
run: |
if [ "${{ needs.python-unit-tests.result }}" == "success" ]; then
echo "success notifications go here"
if [ "${{ needs.python-unit-tests.result }}" == "failure" ]; then
echo "## ❌ Python Tests Failed" >> $GITHUB_STEP_SUMMARY
else
echo "failure notifications go here"
echo "## ✅ Python Tests Passed" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
echo "|---|---|" >> $GITHUB_STEP_SUMMARY
echo "| Branch | \`${{ github.ref_name }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Commit | \`${{ github.sha }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Actor | ${{ github.actor }} |" >> $GITHUB_STEP_SUMMARY
echo "| Run | [View logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) |" >> $GITHUB_STEP_SUMMARY

- name: Notify Slack on failure
if: needs.python-unit-tests.result == 'failure' && env.SLACK_WEBHOOK_URL != ''
uses: slackapi/slack-github-action@v2
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
{
"text": ":x: *Python tests failed* on `${{ github.ref_name }}`",
"attachments": [{
"color": "danger",
"fields": [
{ "title": "Repo", "value": "${{ github.repository }}", "short": true },
{ "title": "Triggered by", "value": "${{ github.actor }}", "short": true },
{ "title": "Commit", "value": "${{ github.sha }}" },
{ "title": "Run", "value": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" }
]
}]
}

- name: Send failure email
if: needs.python-unit-tests.result == 'failure' && env.MAIL_USERNAME != ''
uses: dawidd6/action-send-mail@v3
with:
server_address: smtp.gmail.com
server_port: 465
username: ${{ secrets.MAIL_USERNAME }}
password: ${{ secrets.MAIL_PASSWORD }}
to: ${{ github.event.inputs.notify_email || secrets.NOTIFY_EMAIL }}
from: GitHub Actions <${{ secrets.MAIL_USERNAME }}>
subject: "❌ Tests failed — ${{ github.repository }} (${{ github.ref_name }})"
body: |
Python unit tests failed.

Repository : ${{ github.repository }}
Branch : ${{ github.ref_name }}
Commit : ${{ github.sha }}
Triggered by: ${{ github.actor }}
Run URL : ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

- name: Create GitHub issue on failure
if: needs.python-unit-tests.result == 'failure'
uses: actions/github-script@v7
with:
script: |
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `❌ Tests failed on ${context.ref} (${context.sha.substring(0, 7)})`,
body: [
`**Python unit tests failed.**`,
``,
`| Field | Value |`,
`|---|---|`,
`| Branch | \`${context.ref}\` |`,
`| Commit | \`${context.sha}\` |`,
`| Triggered by | ${context.actor} |`,
`| Run | [View logs](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}) |`,
].join('\n'),
labels: ['bug']
});

- name: Close GitHub issue on success
if: needs.python-unit-tests.result == 'success'
uses: actions/github-script@v7
with:
script: |
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'bug'
});
const ciIssues = issues.data.filter(i => i.title.startsWith('❌ Tests failed'));
for (const issue of ciIssues) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: `✅ Tests are passing again as of commit \`${context.sha.substring(0, 7)}\` on \`${context.ref}\`. Closing.`
});
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
state: 'closed'
});
}
2 changes: 1 addition & 1 deletion app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

# MySQL database settings
MYSQL_HOST = os.getenv("MYSQL_HOST", SET_ME_PLEASE)
MYSQL_PORT = int(os.getenv("MYSQL_PORT", "3306"))
MYSQL_PORT = int(os.getenv("MYSQL_PORT") or "3306")
MYSQL_USER = os.getenv("MYSQL_USER", SET_ME_PLEASE)
MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD", SET_ME_PLEASE)
MYSQL_DATABASE = os.getenv("MYSQL_DATABASE", SET_ME_PLEASE)
Expand Down
Loading
Loading