Skip to content

CI/CD notifications

CI sends emails that nobody reads, or posts to Slack/Telegram where they drown among memes. Notifly provides an isolated “infrastructure-only” channel — messages are immediately visible, don’t get lost, and don’t distract colleagues.

The examples below use two secrets:

  • NOTIFLY_URL — the full URL of your server, e.g. https://notifly.example.com
  • NOTIFLY_TOKEN — app token (prefix A)

In GitHub: Settings → Secrets and variables → Actions → New repository secret. In GitLab: Settings → CI/CD → Variables → Add variable (set “Masked”).

.github/workflows/build.yml:

name: Build & Notify
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm test
- run: npm run build
notify:
needs: build
if: always()
runs-on: ubuntu-latest
steps:
- name: Notifly
env:
NOTIFLY_URL: ${{ secrets.NOTIFLY_URL }}
NOTIFLY_TOKEN: ${{ secrets.NOTIFLY_TOKEN }}
STATUS: ${{ needs.build.result }}
run: |
if [ "$STATUS" = "success" ]; then
TITLE="✅ ${{ github.repository }} build OK"
PRIO=4
else
TITLE="❌ ${{ github.repository }} build FAILED"
PRIO=9
fi
MSG="Branch: ${{ github.ref_name }}
Commit: ${{ github.sha }}
By: ${{ github.actor }}
Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
curl -s --max-time 10 \
"$NOTIFLY_URL/message?token=$NOTIFLY_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg t "$TITLE" --arg m "$MSG" --argjson p "$PRIO" \
'{title:$t, message:$m, priority:$p}')"

Place into .github/actions/notifly/action.yml:

name: 'Notifly send'
inputs:
title: {required: true}
message: {required: true}
priority: {default: '5'}
runs:
using: composite
steps:
- shell: bash
env:
NOTIFLY_URL: ${{ env.NOTIFLY_URL }}
NOTIFLY_TOKEN: ${{ env.NOTIFLY_TOKEN }}
run: |
curl -s --max-time 10 \
"$NOTIFLY_URL/message?token=$NOTIFLY_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg t '${{ inputs.title }}' \
--arg m '${{ inputs.message }}' \
--argjson p ${{ inputs.priority }} \
'{title:$t, message:$m, priority:$p}')"

Usage:

- uses: ./.github/actions/notifly
with:
title: '🚀 deploy started'
message: 'release ${{ github.ref_name }}'
priority: 5

.gitlab-ci.yml:

stages: [build, notify]
build:
stage: build
script:
- npm ci && npm test && npm run build
notify:success:
stage: notify
when: on_success
script:
- |
curl -s --max-time 10 \
"$NOTIFLY_URL/message?token=$NOTIFLY_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--arg t '✅ '"$CI_PROJECT_PATH"' build OK' \
--arg m 'Branch: '"$CI_COMMIT_REF_NAME"$'\nCommit: '"$CI_COMMIT_SHORT_SHA"$'\nURL: '"$CI_PIPELINE_URL" \
'{title:$t, message:$m, priority:4}')"
notify:failure:
stage: notify
when: on_failure
script:
- |
curl -s --max-time 10 \
"$NOTIFLY_URL/message?token=$NOTIFLY_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--arg t '❌ '"$CI_PROJECT_PATH"' build FAILED' \
--arg m 'Branch: '"$CI_COMMIT_REF_NAME"$'\nCommit: '"$CI_COMMIT_SHORT_SHA"$'\nURL: '"$CI_PIPELINE_URL" \
'{title:$t, message:$m, priority:9}')"
  • Long build (> 10 min) — alert ‘something is wrong’.
  • New release — separate event with changelog.
  • Coverage regression below threshold — priority 5 so it isn’t missed.
  • Security issues found in npm audit / pip-audit — priority 8.
  • One channel for the entire infra. Push → build → push → deploy → push.
  • No ‘build #12345 failed’ emails in the inbox where they get lost.
  • Progress visible on the phone. Especially convenient for deployments at night or on the road.