Skip to content

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/bash
PULSE_URL="YOUR_WEBHOOK_URL"
JOB="my-deploy"
notify() {
curl -s -X POST "$PULSE_URL" \
-H "Content-Type: application/json" \
-d "$1" > /dev/null
}
# Start
notify "{\"job_id\":\"$JOB\",\"layout\":\"progress\",\"message\":\"Deploy started\",\"metric\":\"Step 1/3\",\"progress\":0.1,\"status\":\"running\"}"
# … your deploy steps …
./build.sh
notify "{\"job_id\":\"$JOB\",\"layout\":\"progress\",\"message\":\"Build complete\",\"metric\":\"Step 2/3\",\"progress\":0.6,\"status\":\"running\"}"
./deploy.sh
notify "{\"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 progress incrementally (e.g. 0.1 on start, 0.6 after build, 1.0 on done) so the bar moves visibly.
  • Always use if: always() (GitHub) or after_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.