Releases

How finished work reaches production in batches, and what each role does about it.

Everything between < and > is yours: <KEY> is your task-key prefix, <owner>/<repo> your repository and <basePath> where the board is mounted.

Work ships in batches. A lanzamiento is a named set of tasks that is testable as one unit on next and reaches production in a single deploy.

Git model#

  • main is production. It only moves when a release ships (plus emergency hotfixes, which the next ship merges back).
  • next is the open release. Task PRs target next; adding a task to the release merges its PR into next with a merge commit (never squash: stacked PRs keep their parents' commits).
  • Your hosting builds main and next. next is served on preview URLs (release.previewUrls, from RELEASE_PREVIEW_WEB_URL and RELEASE_PREVIEW_ADMIN_URL; without them the board draws no "try it" links), which may talk to the production API. A task whose PR touches a path in repo.apiPaths is flagged se verifica en producción: it cannot be tried on next.
  • CI runs on PRs to next; the deploy workflow runs on pushes to main.

Task states around a release#

EstadoMeaning
En revisiónPR open (or merged into next), reporter can try it on next.
En producciónThe release shipped; the requester must verify on prod. Set only by the ship, never by hand.
HechaVerified on prod (verifiedAt, verifiedById).

"Falló" on a released task sends it back to En progreso with the comment; the code stays in production and the fix is a new PR into the next release.

Lifecycle#

  1. Crear (POST <basePath>/releases, create_release): one open release at a time; creates branch next from main if it is missing.
  2. Agregar tareas (POST releases/:id/tasks, add_to_release): the task needs an open PR with green checks. The board retargets the PR to next if it still points at main, merges it, deletes the branch, links it as merged and records needsApi. Agent keys may add only their own tasks.
  3. Probar en next: the release card and the task page link to the next hosts. Every addition rebuilds them once.
  4. Lanzar (POST releases/:id/ship, ship_release, admin keys only): merges main into next if main moved, merges next into main, tags release/<slug>, moves every task to En producción, drafts the changelog grouped by epic and rings each requester. The push to main triggers the deploy. Shipped by hand instead (a next → main PR merged outside the board): POST releases/:id/record-ship with { "sha": "<7-40 hex>", "prNumber": 1100 } (record_ship, admin/automation keys only) records it. The release must be open (or closed without a shippedSha). The board checks, through the SCM provider, that sha is in main (compare(main, sha) is identical or behind; else sha_not_in_main) and that the PR's merge commit is inside it (else pr_not_in_sha). It then sets SHIPPED + shippedSha + shippedAt and moves every not-yet-done task whose linked PR number is prNumber and merged to En producción, with the same audit row (backlog.release.record_ship) and requester notification as a normal ship. It never tags and never moves next (those are ship's GitHub side effects, already done by hand). Link the release PR to each card first (link_pr).
  5. Verificar (POST tasks/:id/verify): unlocked when /version on the API, the store and the admin report the shipped sha (an admin can override). Verified tasks become Hecha; the release closes when none remain.

Error codes#

release_open_exists, release_not_open, release_empty, task_in_release, no_open_pr, ambiguous_pr, pr_closed, pr_draft, pr_merged_to_main, stacked_pr (add the parent task first, then rebase), pr_conflicts (rebase onto origin/next), checks_failing, checks_pending (force skips it), pr_not_mergeable, head_moved, next_conflicts_with_main, nothing_to_ship, tag_exists, not_released, prod_not_deployed, agent_not_assignee, sha_not_in_main, pr_not_in_sha, plus the GitHub codes (github_unconfigured, github_unauthorized, github_rate_limited, github_not_found, github_error).