← Back to blog
Feb 9, 2026

How I Use ActivitySmith While Deploying ActivitySmith

Adam Bardon
Adam BardonFounder
Deployment progress shown across three iPhone Live Activity stages

I am a huge fan of dogfooding. If I build developer tooling, I want to use it in my own day-to-day workflows.

Deployments are one of the biggest ways I use ActivitySmith: push to main, GitHub Actions runs in the background, and I get step-by-step progress updates on my iPhone lock screen using iOS Live Activities.

The Problem I Kept Running Into

My deployments are automated with GitHub Actions and are fairly simple, but they still have multiple steps and usually take at least a minute. In larger projects and teams, deployment runs often take much longer.

Before ActivitySmith, that meant opening GitHub, finding the repo, going to Actions, opening the current run, and watching it progress until it finished so I knew when I could try it out.

That workflow was annoying. With ActivitySmith, the progress streams directly to my iPhone lock screen in real time, and I know exactly when a release is finished and ready to try.

ActivitySmith deployment live activity completion

What ActivitySmith Does in My Deployments

For every production deployment, ActivitySmith:

  • Starts a Live Activity at the beginning of the workflow.
  • Updates each phase of deployment progress in real time.
  • Ends the activity when production is fully switched.

This is not limited to one backend service. I use the same pattern across various backend services, frontend apps, landing pages, and other projects.

My GitHub Actions Workflow

Here is the workflow I use in production:

name: Deploy API to Production

on:
push:
branches: [main]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v4
with:
node-version:node-version:node-version: 24
cache: npm

- name: Start live activity
id: start_activity
uses: ActivitySmithHQ/[email protected]
with:
action: start_live_activity
api-key: ${{ secrets.ACTIVITYSMITH_API_KEY }}
payload: |
content_state:
title: "API Deployment"
subtitle: "ci: install & build"
number_of_steps: 4
current_step: 1
type: "segmented_progress"
color: "yellow"

- name: Build
run: |
npm ci
npm run build

- name: Update live activity
uses: ActivitySmithHQ/[email protected]
with:
action: update_live_activity
api-key: ${{ secrets.ACTIVITYSMITH_API_KEY }}
live-activity-id: ${{ steps.start_activity.outputs.live_activity_id }}
payload: |
content_state:
title: "ActivitySmith API Deployment"
subtitle: "prepare release & upload"
current_step: 2

- name: Set release id
run: |
echo "RELEASE_ID=$(date +%Y%m%d%H%M%S)" >> $GITHUB_ENV

- name: Prepare release dir on remote server
run: |
ssh -o StrictHostKeyChecking=no [email protected] "RELEASE_ID=${RELEASE_ID} bash -s" << 'EOF'
set -euo pipefail
BASE="/srv/apps/activitysmith-api"
NEW="$BASE/releases/$RELEASE_ID"
mkdir -p "$BASE/releases"
rm -rf "$NEW"
mkdir -p "$NEW"
EOF

- name: Upload built artifacts to remote server
run: |
# rsync release artifacts to the new server release directory

- name: Update live activity
uses: ActivitySmithHQ/[email protected]
with:
action: update_live_activity
api-key: ${{ secrets.ACTIVITYSMITH_API_KEY }}
live-activity-id: ${{ steps.start_activity.outputs.live_activity_id }}
payload: |
content_state:
title: "ActivitySmith API Deployment"
subtitle: "prod install & reload"
current_step: 3

- name: Install prod deps, switch release, and reload
run: |
# Remote deployment script:
# - Install production dependencies in the new release directory
# - Atomically switch current symlink to the new release
# - Gracefully reload PM2 cluster behind nginx
# - Prune old releases while keeping rollback-safe history

- name: End live activity
uses: ActivitySmithHQ/[email protected]
with:
action: end_live_activity
api-key: ${{ secrets.ACTIVITYSMITH_API_KEY }}
live-activity-id: ${{ steps.start_activity.outputs.live_activity_id }}
payload: |
content_state:
title: "ActivitySmith API Deployment"
subtitle: "done"
current_step: 4

Push Notification

ActivitySmith push notification

You can also use ActivitySmith to send push notifications to your iOS devices.

- name: Send deployment complete push notification
uses: ActivitySmithHQ/[email protected]
with:
action: send_push_notification
api-key: ${{ secrets.ACTIVITYSMITH_API_KEY }}
payload: |
title: "Build Failed 🚨"
message: "CI pipeline failed on main branch"

Why Zero Downtime Is Non-Negotiable

ActivitySmith is API infrastructure. Users expect near-constant availability.

Before I implemented zero-downtime deployments, the Live Activity lifecycle would break during release restarts because the API went down mid-deploy, so updates could not be delivered.

Deployments now run behind nginx with PM2 in cluster mode using zero-downtime reloads (worker A, then worker B), so traffic stays up and Live Activity updates continue reliably.

More Than One Project

This pattern now powers every deployment workflow I care about, not just ActivitySmith core services. Once wired in, every release gives real-time confidence without babysitting logs.

And outside GitHub Actions, the same approach works from scripts, cron jobs, workers, agents and more. Basically any backend. Zapier and n8n integrations are complete and currently pending marketplace approval.

Try It on Your Next Deployment