Przejdź do treści

GitHub Actions

Wysyłaj powiadomienia, pokazuj zadanie jako wydarzenie na żywo i czekaj na odpowiedź prosto z przepływu pracy dzięki akcji PushWard albo śledź każde uruchomienie za pomocą mostu odpytującego.

Demonstracja wydarzenia na żywo

There are two ways in. The PushWard action is a step in your workflow: you decide what it sends and when, and it can stop a job until you answer on your phone. The polling bridge is a container that watches your repositories from outside and shows every run as a Live Activity without touching any workflow file.

⚠ Ostrzeżenie

If the bridge also watches a repository whose jobs show a Live Activity through the action, each run gets two cards, the bridge's and the action's. Use one or the other per repository.

PushWard action

mac-lucky/pushward-action@v1 sends notifications, shows a job as a Live Activity on your Lock Screen, updates Home Screen widgets, sends email, and stops a job until someone taps a button. It runs the pushward CLI, so anything the CLI can do works here through the command input. Source: mac-lucky/pushward-action.

Setup

Copy an integration key from the app and save it as a repository secret, say PUSHWARD_TOKEN. A key just for CI is better than your default one: give it only what the workflow uses, and restrict its activity slugs to gha-* (see Creating scoped keys).

  • Notifications, and waiting for their answers, need notifications at send.
  • Starting a Live Activity needs activities at manage, since activity start creates it.
  • Widget updates need widgets at write, email needs emails at send.

Notify when a job fails

- uses: mac-lucky/pushward-action@v1
  if: failure()
  with:
    token: ${{ secrets.PUSHWARD_TOKEN }}
    title: ${{ github.workflow }} failed
    body: ${{ github.repository }} on ${{ github.ref_name }}
    level: time-sensitive

Tapping it opens the run. Notifications from one repository are grouped into a thread.

A job as a Live Activity

steps:
  - uses: mac-lucky/pushward-action@v1
    with:
      token: ${{ secrets.PUSHWARD_TOKEN }}
      command: activity start --template steps --step 1/3 --step-labels Build,Test,Deploy
      text: Building

  - run: make build

  - uses: mac-lucky/pushward-action@v1
    with:
      token: ${{ secrets.PUSHWARD_TOKEN }}
      command: activity update --step 2/3
      text: Testing

  - run: make test

  - uses: mac-lucky/pushward-action@v1
    with:
      token: ${{ secrets.PUSHWARD_TOKEN }}
      command: activity update --step 3/3
      text: Deploying

  - run: make deploy

  - uses: mac-lucky/pushward-action@v1
    if: always()
    with:
      token: ${{ secrets.PUSHWARD_TOKEN }}
      command: activity end
      status: ${{ job.status }}

The card is named after the workflow, shows repo / job underneath and links to the run. if: always() runs the last step even when an earlier step failed or the run was cancelled, and status: ${{ job.status }} makes activity end show a green check, red cross or grey stop for a few seconds before it ends the card. If the job failed before the start step ran, the end step only logs a warning.

The slug defaults to gha-<owner>-<repo>-<run_id>-<job>. Matrix legs share the job id, so give each leg its own slug and set it on every PushWard step of the job:

    with:
      slug: gha-${{ github.run_id }}-${{ strategy.job-index }}

Wait for an answer

- id: ask
  uses: mac-lucky/pushward-action@v1
  with:
    token: ${{ secrets.PUSHWARD_TOKEN }}
    title: Deploy ${{ github.ref_name }} to production?
    body: ${{ github.event.head_commit.message }}
    actions: |
      deploy=Deploy
      skip=Skip
    wait: 30m

- if: steps.ask.outputs.answer == 'deploy'
  run: ./deploy.sh

If nobody answers in time the step fails. With fail-on-error: false it passes instead, answer is empty and status is pending. The runner is billed the whole time it waits, so for anything longer than a few minutes a protected environment with required reviewers is the cheaper gate.

The same works with an approval card on the Lock Screen: command: activity start --template approval with actions as its options, then command: activity wait with wait: 30m.

Update a widget

- uses: mac-lucky/pushward-action@v1
  with:
    token: ${{ secrets.PUSHWARD_TOKEN }}
    command: widget update
    slug: coverage
    fields: content.value=${{ steps.coverage.outputs.percent }}

Create the widget once, from the app or with command: widget create --template gauge --min 0 --max 100 --unit %.

Send an email

- uses: mac-lucky/pushward-action@v1
  with:
    token: ${{ secrets.PUSHWARD_TOKEN }}
    command: email send --to [email protected] --subject "Nightly report"
    text: ${{ steps.report.outputs.summary }}

Email only goes to addresses you have verified in the app.

Pojawi się w wersji aplikacji 1.17.0

Ta sekcja opisuje funkcję z aktualizacji aplikacji oczekującej na weryfikację w App Store. Odblokuje się tutaj automatycznie, gdy tylko aktualizacja będzie dostępna.

Inputs

token is the only required input. command takes any pushward command with its flags (the CLI page lists them); the other inputs are shortcuts for the common flags. An input the command has no use for is ignored with a warning.

InputDescriptionDefault
tokenIntegration key (hlk_). Pass it from a secret.required
commandpushward command to run, e.g. activity start, widget update. Split like a shell line.notify
slugActivity or widget slug. Activity commands default to gha-<owner>-<repo>-<run_id>-<job>.--
titleNotification title--
bodyNotification body--
subtitleSecondary line of a notification, activity or widget--
levelNotification interruption level: passive, active, time-sensitive or critical--
urlURL opened on tap. Notifications and started activities default to the run's page.--
nameActivity or widget display name. activity start defaults to the workflow name.--
templateActivity or widget template, e.g. generic, steps, approval, gauge--
textStatus text of an activity, or the plain-text body of an email--
progressActivity progress from 0 to 1--
iconSF Symbol name, or mdi:<name>--
colorAccent color, a name (green, red, ...) or #RRGGBB--
statusFor activity end: success, failure or cancelled. Pass job.status.--
waitHow long to wait for an answer, e.g. 15m. For notify this needs actions; for activity wait it is the timeout.--
actionsAnswer buttons, one id=Title per line: notification actions, or the options of an approval activity--
fieldsExtra typed fields, one key=value per line, with dotted keys (content.total_steps=4, push=false)--
jsonRequest body as JSON. Inputs and fields are applied on top of it.--
api-urlAPI base URL--
fail-on-errorFail the step when the call fails. false turns the error annotation into a warning.true
Pojawi się w wersji aplikacji 1.17.0
⚠ Ostrzeżenie

Keep untrusted text (branch names, commit messages, PR titles) in the shortcut inputs, never in command. command is split like a shell line, so a crafted value there can add flags.

Outputs

OutputValue
responseThe API response as JSON
idNotification or scheduled notification id
slugActivity or widget slug
answerId of the tapped action, or the chosen option of an approval card
answer-textText typed with the answer, if any
statusDelivery of a notification or email (all, partial, none), activity state (ongoing, ended), answer status (pending, answered), or the status of a scheduled notification

Runners and versions

This is a Docker container action, so it runs on Linux runners only. On macOS or Windows runners, install the CLI (brew install mac-lucky/tap/pushward, or a release archive) and call it from a run step.

@v1 follows the newest 1.x release. Every release pins an exact pushward-cli image, so pinning @v1.2.3 or a commit SHA also pins the CLI.

Polling bridge

The pushward-github bridge container polls the GitHub Actions API for in-progress workflow runs and maps workflow progress to Live Activities using the steps template.

  1. Idle polling -- checks all configured repos every 60s for in-progress workflows
  2. Active tracking -- on each poll cycle the bridge fetches the tracked run's jobs and updates progress
  3. Cleanup -- after the workflow completes, the activity is cleaned up after a configurable delay (default 15 min)

1. Get your integration key

Użyj swojego domyślnego klucza integracji z aplikacji PushWard w Ustawienia → Klucz integracji lub utwórz klucz o ograniczonym zakresie dla tej integracji.

2. Create a GitHub personal access token

Create a fine-grained PAT with actions:read permission on the repos you want to track.

3. Deploy the bridge

docker-compose.yml
services:
  pushward-github:
    image: ghcr.io/mac-lucky/pushward-github:latest
    environment:
      PUSHWARD_URL: https://api.pushward.app
      PUSHWARD_API_KEY: hlk_YOUR_INTEGRATION_KEY
      PUSHWARD_GITHUB_TOKEN: github_pat_YOUR_GITHUB_TOKEN
      PUSHWARD_GITHUB_OWNER: your-username  # auto-discovers all repos
      # OR specify repos explicitly:
      # PUSHWARD_GITHUB_REPOS: owner/repo1,owner/repo2
    restart: unless-stopped

Configuration

Zmienna środowiskowaOpisDomyślnie
PUSHWARD_URLPushWard server URL--
PUSHWARD_API_KEYIntegration key (hlk_ prefix)--
PUSHWARD_GITHUB_TOKENGitHub PAT with actions:read--
PUSHWARD_GITHUB_OWNERGitHub username for auto-discovery--
PUSHWARD_GITHUB_REPOSComma-separated owner/repo list--
PUSHWARD_PRIORITYActivity priority (0-10)1
PUSHWARD_POLL_IDLEPoll interval for run detection and active job updates60s
PUSHWARD_CLEANUP_DELAYDelay before cleanup after ended15m
💡 Wskazówka

Use PUSHWARD_GITHUB_OWNER to auto-discover all your repos. The bridge refreshes the repo list every 5 minutes, skipping archived and disabled repos.

Activity slug format

Activities are created with the slug gh-<8 hex chars>, derived from SHA-256(owner/repo) (e.g. gh-1a2b3c4d). One run is tracked per repository at a time.