GitHub Actions notifications on your phone
Your workflow finished. You find out by refreshing the Actions tab.
Here’s how to get notified on your phone instead.
The simplest version: one curl step
Add this to the end of any job:
- name: Notify
if: always()
run: |
curl -s -X POST "https://trigger.fyi/$TRIGGER_FYI_SECRET_KEY" \
-H "Content-Type: text/plain" \
-d "${{ job.status == 'success' && 'Deploy succeeded' || 'Deploy failed' }}"
env:
TRIGGER_FYI_SECRET_KEY: ${{ secrets.TRIGGER_FYI_SECRET_KEY }}if: always() ensures it runs even when the job fails. The ternary picks the message based on status.
With context
Include the branch, commit, and duration:
- name: Notify
if: always()
run: |
STATUS="${{ job.status }}"
BRANCH="${{ github.ref_name }}"
SHA="${{ github.sha }}"
SHORT_SHA="${SHA:0:7}"
ACTOR="${{ github.actor }}"
if [ "$STATUS" = "success" ]; then
TITLE="Deploy succeeded"
else
TITLE="Deploy failed"
fi
BODY="${BRANCH} · ${SHORT_SHA} · ${ACTOR}"
curl -s -X POST "https://trigger.fyi/$TRIGGER_FYI_SECRET_KEY" \
-H "Content-Type: application/json" \
-d "{\"title\":\"$TITLE\",\"body\":\"$BODY\",\"meta\":{\"branch\":\"$BRANCH\",\"status\":\"$STATUS\"}}"
env:
TRIGGER_FYI_SECRET_KEY: ${{ secrets.TRIGGER_FYI_SECRET_KEY }}The meta fields are filterable in the trigger.fyi feed — you can filter by branch: main to see only production deploys.
Using levels
Succeed silently, fail loudly:
- name: Notify
if: always()
run: |
STATUS="${{ job.status }}"
if [ "$STATUS" = "success" ]; then
PAYLOAD='{"title":"Deploy complete","level":"log","body":"${{ github.ref_name }}"}'
else
PAYLOAD='{"title":"Deploy failed","level":"critical","body":"${{ github.ref_name }} · ${{ github.actor }}"}'
fi
curl -s -X POST "https://trigger.fyi/$TRIGGER_FYI_SECRET_KEY" \
-H "Content-Type: application/json" \
-d "$PAYLOAD"
env:
TRIGGER_FYI_SECRET_KEY: ${{ secrets.TRIGGER_FYI_SECRET_KEY }}log records in the feed without pushing. critical uses Web Push urgency high. On iOS, critical degrades to normal priority — iOS web push can’t override silent mode.
Per-job vs per-workflow
Notify at the job level if each job is independent:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
- name: Notify
if: always()
run: |
curl -s -X POST "https://trigger.fyi/$TRIGGER_FYI_SECRET_KEY" \
-d "Tests ${{ job.status }}"
env:
TRIGGER_FYI_SECRET_KEY: ${{ secrets.TRIGGER_FYI_SECRET_KEY }}
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh
- name: Notify
if: always()
run: |
curl -s -X POST "https://trigger.fyi/$TRIGGER_FYI_SECRET_KEY" \
-d "Deploy ${{ job.status }}"
env:
TRIGGER_FYI_SECRET_KEY: ${{ secrets.TRIGGER_FYI_SECRET_KEY }}Or notify only once at the workflow level using a final job that needs all others:
notify:
needs: [test, build, deploy]
runs-on: ubuntu-latest
if: always()
steps:
- name: Notify
run: |
curl -s -X POST "https://trigger.fyi/$TRIGGER_FYI_SECRET_KEY" \
-d "Pipeline ${{ needs.deploy.result }}"
env:
TRIGGER_FYI_SECRET_KEY: ${{ secrets.TRIGGER_FYI_SECRET_KEY }}Adding the secret
In your repository: Settings → Secrets and variables → Actions → New repository secret
Name: TRIGGER_FYI_SECRET_KEY
Value: your trigger.fyi key
Or set it at the organization level for all repositories.
Getting your key
npx trigger.fyiGenerates a key and subscribes your device. Copy the key into the GitHub secret. Done.
Related: Deploy notifications on your phone · Cron job notifications · The curl guide to trigger.fyi · What is trigger.fyi?