CI recipes
Complete workflows to copy — GitHub Actions on a preview and on production, GitLab CI with JUnit, Vercel then wait, the Monday-morning script.
Updated on 17 September 2026
On this page
Four situations, four ready-made files. Everywhere, the key comes from a secret (POSTSHIP_TOKEN) and the project id from a committed ./.postship.json (postship init) or a POSTSHIP_PROJECT variable. Never a key in clear text, never as an argument.
GitHub Actions: a pull request's preview
Check the preview URL before merging, with a threshold, and see the failures annotated on the pull request. check counts one check per URL toward the quota.
name: PostShip
on: [pull_request]
jobs:
preview:
runs-on: ubuntu-latest
steps:
- uses: titilyonnais/postship-check@v1
with:
url: ${{ steps.preview.outputs.url }}
token: ${{ secrets.POSTSHIP_TOKEN }}
min-score: 80steps.preview.outputs.url is the address your preview deployment step produced (Vercel, Netlify…). Without the action, the same thing in two lines:
- run: npm i -g postship
- run: postship check --url "${{ steps.preview.outputs.url }}" --min-score 80
env:
POSTSHIP_TOKEN: ${{ secrets.POSTSHIP_TOKEN }}GitHub Actions: production, after a deployment
Wait until PostShip has checked this commit in production, then decide. Nothing is consumed: wait and gate are reads.
production:
runs-on: ubuntu-latest
needs: deploy
steps:
- uses: actions/checkout@v4
- run: npm i -g postship
- run: postship wait --sha "$GITHUB_SHA" --timeout 600
env:
POSTSHIP_TOKEN: ${{ secrets.POSTSHIP_TOKEN }}
- run: postship gate --min-score 80
env:
POSTSHIP_TOKEN: ${{ secrets.POSTSHIP_TOKEN }}The project comes from the committed ./.postship.json. wait exits 2 if ten minutes pass without a concluded ship — the job fails, but not because the site is broken: steps.<id>.outcome tells the two apart if you want to let a 2 through.
GitLab CI: the JUnit report
--junit writes a report that GitLab's Tests tab displays, one line per check.
postship:
image: node:20
script:
- npm i -g postship
- postship check --url "$CI_ENVIRONMENT_URL" --min-score 80 --junit postship.xml
artifacts:
when: always
reports:
junit: postship.xmlPOSTSHIP_TOKEN is a masked and protected CI/CD variable (Settings → CI/CD → Variables).
Vercel from the command line, then wait
A deployment started by hand, and the certainty it was checked before you close the terminal.
vercel deploy --prod
postship wait --sha "$(git rev-parse HEAD)" --timeout 600 && postship openpostship open opens the project's Overview in the browser.
The Monday-morning script
A glance at every site without opening the app — and an exit code 1 that can ring something else.
#!/usr/bin/env bash
set -euo pipefail
postship projects --fail-if-red
for id in $(postship projects --json | jq -r '.projects[].id'); do
postship incidents -p "$id" --fail-if-open
doneSee also
The postship command — every command · postship check · postship wait · postship gate · Checking from your CI — the same thing with curl, nothing to install.