concurrency: cancel-in-progress, and the deploy you must not cancel

Cancelling superseded runs is right for tests and wrong for a deploy, and the same key applied to both produces a half-finished release.

# tests: cancel the old run, per branch
concurrency:
  group: test-${{ github.ref }}
  cancel-in-progress: true

# deploy: queue, never cancel
concurrency:
  group: deploy-production
  cancel-in-progress: false

A deploy cancelled between the file upload and the symlink swap leaves a release directory that is complete and not live, which is recoverable, and one cancelled during a migration is not. The un-cancelled group also serialises deploys across branches, which is what you want and is not obvious from the syntax — the group name has no github.ref in it deliberately. Only one run can queue behind a running one; a third supersedes the queued one, which is usually correct and is worth knowing.