Shipped

Setup guide

Most teams are done in about 10 minutes. You need Jira admin rights for steps 1-2.

1. Create a component

A component is one deployable thing whose releases you tag: a service, app or library. In Jira open Apps → Shipped → Settings → Setup and give it a name and a tag pattern, a git glob where * is the version:

Your tags look likeTag pattern
v1.2.3v*
1.2.3[0-9]*
api@1.2.3 (monorepo)api@*
api/v1.2.3 (monorepo)api/v*
build-123, calvercustom regex, e.g. ^build-(?<v>\d+)$

Components are also created automatically the first time CI pushes a tag for a new name.

2. Generate the ingest secret

The wizard shows your site's ingest URL and generates a secret (shown once). Store them as CI secrets named SHIPPED_URL and SHIPPED_SECRET. Rotating keeps the old secret valid for 24 hours.

3. Add one CI step

The wizard generates a snippet for GitHub Actions, GitLab CI, Bitbucket Pipelines, Jenkins, Azure Pipelines or any shell. GitHub Actions example:

on:
  push:
    tags: ['v*']
jobs:
  shipped:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }   # full history: Shipped needs the previous tag
      - uses: shippedapp/shipped-push@v1
        with:
          component: api
          url: ${{ secrets.SHIPPED_URL }}
          secret: ${{ secrets.SHIPPED_SECRET }}

Snippets pin the script by version and SHA-256. The script needs bash, git, curl, openssl and jq.

4. Import history (optional)

From a local clone: bash shipped-push.sh --component api --tag-glob 'v*' --backfill 20 sends your last 20 tags.

Writing ticket keys

Shipped finds keys like ABC-123 in commit subjects and bodies, merge commit messages (which usually carry the PR title and branch name) and squash-merge subjects. Keys are checked against real projects and issues on your site, so strings like UTF-8 never count. Commits brought in by a merge whose message has a key count as tracked.

Monorepos

Use one component per deployable with its own tag prefix (api@*) and add --paths "services/api" so only commits touching that path count.

Drift and Fix Versions

Shipped never uses Fix Version to decide what shipped; it only compares. Set a Fix Version mapping per release or as a default: {release} if your Fix Version is named like the release, or {component}-{version} for one Fix Version per component version (e.g. api-1.5.0).

Troubleshooting

CI log saysFix
Signature rejected (401)Wrong SHIPPED_SECRET, revoked, or rotated over 24 h ago. Generate a new one.
Payload rejected (400)See Settings → Ingest log; every rejection has a reason. Usually an outdated script.
Timestamp rejected (409)The CI runner's clock is more than 5 minutes off.
No previous tagShallow clone: use fetch-depth: 0 (GitHub) or GIT_DEPTH: 0 (GitLab). The script also tries to unshallow.
Tag ignoredThe tag doesn't match the component's tag pattern. Fix the pattern in Components.

The script never fails your release on a Shipped problem unless you pass --strict.