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#
mainis production. It only moves when a release ships (plus emergency hotfixes, which the next ship merges back).nextis the open release. Task PRs targetnext; adding a task to the release merges its PR intonextwith a merge commit (never squash: stacked PRs keep their parents' commits).- Your hosting builds
mainandnext.nextis served on preview URLs (release.previewUrls, fromRELEASE_PREVIEW_WEB_URLandRELEASE_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 inrepo.apiPathsis flagged se verifica en producción: it cannot be tried onnext. - CI runs on PRs to
next; the deploy workflow runs on pushes tomain.
Task states around a release#
| Estado | Meaning |
|---|---|
| En revisión | PR open (or merged into next), reporter can try it on next. |
| En producción | The release shipped; the requester must verify on prod. Set only by the ship, never by hand. |
| Hecha | Verified 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#
- Crear (
POST <basePath>/releases,create_release): one open release at a time; creates branchnextfrommainif it is missing. - Agregar tareas (
POST releases/:id/tasks,add_to_release): the task needs an open PR with green checks. The board retargets the PR tonextif it still points atmain, merges it, deletes the branch, links it as merged and recordsneedsApi. Agent keys may add only their own tasks. - Probar en next: the release card and the task page link to the
nexthosts. Every addition rebuilds them once. - Lanzar (
POST releases/:id/ship,ship_release, admin keys only): mergesmainintonextifmainmoved, mergesnextintomain, tagsrelease/<slug>, moves every task to En producción, drafts the changelog grouped by epic and rings each requester. The push tomaintriggers the deploy. Shipped by hand instead (anext→mainPR merged outside the board):POST releases/:id/record-shipwith{ "sha": "<7-40 hex>", "prNumber": 1100 }(record_ship, admin/automation keys only) records it. The release must be open (or closed without ashippedSha). The board checks, through the SCM provider, thatshais inmain(compare(main, sha)isidenticalorbehind; elsesha_not_in_main) and that the PR's merge commit is inside it (elsepr_not_in_sha). It then setsSHIPPED+shippedSha+shippedAtand moves every not-yet-done task whose linked PR number isprNumberand 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 movesnext(those areship's GitHub side effects, already done by hand). Link the release PR to each card first (link_pr). - Verificar (
POST tasks/:id/verify): unlocked when/versionon 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).