ArgoCD
在 iPhone Lock Screen 上以 Live Activity 的形式觀察 ArgoCD 應用程式同步 — 從 Syncing 到 Rolling out 再到 Deployed 的三步驟管線,同步失敗與健康狀態退化都會即時標記。
ArgoCD delivers through the hosted Relay — point ArgoCD's built-in notifications at relay.pushward.app/argocd with your integration key. No container to deploy and no self-hosting.
Get Your Integration Key
開啟 PushWard App → 設定 → 整合金鑰,即可找到您的預設 hlk_ 金鑰。
若要為此整合建立專屬金鑰:
- 前往 設定 → 管理金鑰
- 點按 +
- 設定名稱(例如「ArgoCD」),選擇 , 完整管理 範圍,並限定於
argocd-* - 複製產生的
hlk_金鑰
How It Works
ArgoCD's notifications controller posts a small JSON body to the relay on each lifecycle event. The relay maps them onto one steps Live Activity per application — a three-step pipeline:
| Event | Step |
|---|---|
sync-running | 1/3 — Syncing |
sync-succeeded | 2/3 — Rolling out |
deployed | 3/3 — Deployed (ends the activity) |
sync-failed | Sync Failed |
health-degraded | Degraded (transient warning during rollout) |
The activity slug is derived from the app name (the pushward-server app becomes argocd-pushward-server), so repeated syncs of the same app reuse one activity instead
of stacking up. Fast syncs that finish within the relay's grace period (10 seconds by default) are
suppressed entirely, so a quick no-op sync never wakes your phone.
Configure ArgoCD Notifications
First store your hlk_ key in argocd-notifications-secret so it never
lands in a committed manifest:
apiVersion: v1
kind: Secret
metadata:
name: argocd-notifications-secret
stringData:
pushward-key: hlk_YOUR_INTEGRATION_KEYThen add the PushWard webhook service, one template per event, and the matching triggers to argocd-notifications-cm. Each template sends the JSON body the relay expects
(app, event, revision, repo_url) with the
event name as a literal string:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
data:
service.webhook.pushward: |
url: https://relay.pushward.app/argocd
headers:
- name: Authorization
value: Bearer $pushward-key
- name: Content-Type
value: application/json
template.pushward-sync-running: |
webhook:
pushward:
method: POST
body: |
{"app":"{{.app.metadata.name}}","event":"sync-running","revision":"{{.app.status.sync.revision}}","repo_url":"{{.app.spec.source.repoURL}}"}
template.pushward-sync-succeeded: |
webhook:
pushward:
method: POST
body: |
{"app":"{{.app.metadata.name}}","event":"sync-succeeded","revision":"{{.app.status.sync.revision}}","repo_url":"{{.app.spec.source.repoURL}}"}
template.pushward-deployed: |
webhook:
pushward:
method: POST
body: |
{"app":"{{.app.metadata.name}}","event":"deployed","revision":"{{.app.status.sync.revision}}","repo_url":"{{.app.spec.source.repoURL}}"}
template.pushward-sync-failed: |
webhook:
pushward:
method: POST
body: |
{"app":"{{.app.metadata.name}}","event":"sync-failed","revision":"{{.app.status.sync.revision}}","repo_url":"{{.app.spec.source.repoURL}}"}
template.pushward-health-degraded: |
webhook:
pushward:
method: POST
body: |
{"app":"{{.app.metadata.name}}","event":"health-degraded","revision":"{{.app.status.sync.revision}}","repo_url":"{{.app.spec.source.repoURL}}"}
trigger.on-pushward-sync-running: |
- when: app.status.operationState != nil and app.status.operationState.phase in ['Running']
oncePer: app.status.operationState.startedAt
send: [pushward-sync-running]
trigger.on-pushward-sync-succeeded: |
- when: app.status.operationState != nil and app.status.operationState.phase in ['Succeeded']
oncePer: app.status.operationState.startedAt
send: [pushward-sync-succeeded]
trigger.on-pushward-deployed: |
- when: app.status.operationState != nil and app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'
oncePer: app.status.operationState.startedAt
send: [pushward-deployed]
trigger.on-pushward-sync-failed: |
- when: app.status.operationState != nil and app.status.operationState.phase in ['Error', 'Failed']
oncePer: app.status.operationState.startedAt
send: [pushward-sync-failed]
trigger.on-pushward-health-degraded: |
- when: app.status.health.status == 'Degraded'
send: [pushward-health-degraded]oncePer: app.status.operationState.startedAt makes every sync fire the full event sequence — without it ArgoCD deduplicates repeat notifications and later syncs never reach your phone.
Finally, subscribe the applications you want to track — either per Application or on
the ArgoCD project to cover everything in it:
metadata:
annotations:
notifications.argoproj.io/subscribe.on-pushward-sync-running.pushward: ""
notifications.argoproj.io/subscribe.on-pushward-sync-succeeded.pushward: ""
notifications.argoproj.io/subscribe.on-pushward-deployed.pushward: ""
notifications.argoproj.io/subscribe.on-pushward-sync-failed.pushward: ""
notifications.argoproj.io/subscribe.on-pushward-health-degraded.pushward: ""Trigger a sync of any subscribed application and watch it move through Syncing, Rolling out, and Deployed on your Lock Screen. If nothing arrives, check the notifications controller logs — a wrong event string is reported by the relay as an unknown event.