CI / CD Pipeline
The CI/CD pattern is the most natural fit for Island Pulse. A build starts, progresses through stages, and ends with a pass or fail. You get that status on your Lock Screen without opening any dashboard.
The three-push pattern
Every CI job follows the same shape: a start push when the job kicks off, optional progress updates mid-run, and a final status push when it finishes.
POST /notify → status: running (job starts)POST /notify → status: running (mid-run update, optional)POST /notify → status: success (or "failed")GitHub Actions
Add a step at the start and end of your job. Use if: always() on the final step so it fires even when the build fails.
name: Deploy
on: push: branches: [main]
jobs: deploy: runs-on: ubuntu-latest
steps: - name: "Notify: build started" run: | curl -s -X POST "${{ secrets.ISLAND_PULSE_URL }}" \ -H "Content-Type: application/json" \ -d '{ "job_id": "github-deploy", "layout": "progress", "message": "Running on ${{ github.ref_name }}", "metric": "Starting", "progress": 0.05, "status": "running" }'
- uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20
- name: Install & build run: npm ci && npm run build
- name: "Notify: tests running" run: | curl -s -X POST "${{ secrets.ISLAND_PULSE_URL }}" \ -H "Content-Type: application/json" \ -d '{ "job_id": "github-deploy", "layout": "progress", "message": "Build done, running tests", "metric": "Testing", "progress": 0.6, "status": "running" }'
- name: Test run: npm test
- name: Deploy run: npm run deploy
- name: "Notify: result" if: always() run: | STATUS="${{ job.status }}" if [ "$STATUS" = "success" ]; then MSG="Deployed to production" PULSE_STATUS="success" else MSG="Build failed on ${{ github.ref_name }}" PULSE_STATUS="failed" fi
curl -s -X POST "${{ secrets.ISLAND_PULSE_URL }}" \ -H "Content-Type: application/json" \ -d "{ \"job_id\": \"github-deploy\", \"layout\": \"progress\", \"message\": \"$MSG\", \"metric\": \"$PULSE_STATUS\", \"progress\": 1.0, \"status\": \"$PULSE_STATUS\" }"Store your webhook URL as a repository secret named ISLAND_PULSE_URL.
Bearer instead of query (recommended for log hygiene): Many CI systems log the full curl command. To avoid putting your uniqueID in the URL line, store the base URL without query params (for example https://api.islandpulse.dev/notify) in one secret and your uniqueID in another, then:
- run: | curl -s -X POST "${{ secrets.ISLAND_PULSE_NOTIFY_URL }}" \ -H "Authorization: Bearer ${{ secrets.ISLAND_PULSE_TOKEN }}" \ -H "Content-Type: application/json" \ -d '{"job_id":"github-deploy","layout":"progress","message":"…","status":"running"}'The token value is the same ID embedded in the webhook URL from the app.
GitLab CI
Use before_script for the start push and a custom after_script for the result:
deploy: stage: deploy variables: PULSE_URL: $ISLAND_PULSE_WEBHOOK_URL before_script: - | curl -s -X POST "$PULSE_URL" \ -H "Content-Type: application/json" \ -d "{\"job_id\":\"gitlab-deploy\",\"layout\":\"progress\",\"message\":\"Pipeline $CI_PIPELINE_ID started\",\"metric\":\"Running\",\"progress\":0.1,\"status\":\"running\"}" script: - ./deploy.sh after_script: - | if [ "$CI_JOB_STATUS" = "success" ]; then STATUS="success"; MSG="Deploy complete" else STATUS="failed"; MSG="Pipeline failed" fi curl -s -X POST "$PULSE_URL" \ -H "Content-Type: application/json" \ -d "{\"job_id\":\"gitlab-deploy\",\"layout\":\"progress\",\"message\":\"$MSG\",\"metric\":\"Done\",\"progress\":1.0,\"status\":\"$STATUS\"}"Generic shell example
For any CI tool that runs shell scripts:
#!/bin/bashPULSE_URL="YOUR_WEBHOOK_URL"JOB="my-deploy"
notify() { curl -s -X POST "$PULSE_URL" \ -H "Content-Type: application/json" \ -d "$1" > /dev/null}
# Startnotify "{\"job_id\":\"$JOB\",\"layout\":\"progress\",\"message\":\"Deploy started\",\"metric\":\"Step 1/3\",\"progress\":0.1,\"status\":\"running\"}"
# … your deploy steps …./build.shnotify "{\"job_id\":\"$JOB\",\"layout\":\"progress\",\"message\":\"Build complete\",\"metric\":\"Step 2/3\",\"progress\":0.6,\"status\":\"running\"}"
./deploy.shnotify "{\"job_id\":\"$JOB\",\"layout\":\"progress\",\"message\":\"Deploy finished\",\"metric\":\"Step 3/3\",\"progress\":1.0,\"status\":\"success\"}"Tips
- Use
layout: "progress"for CI jobs, the progress bar gives a much stronger at-a-glance reading than plain text. - Set
progressincrementally (e.g.0.1on start,0.6after build,1.0on done) so the bar moves visibly. - Always use
if: always()(GitHub) orafter_script(GitLab) for the final push, so failure notifications actually arrive. - Store the webhook URL (or base URL + Bearer token) as secrets, treat them like passwords and never commit them to the repo.