Releasing · page 4 of 4
Releases that wait on someone, Ready to promote, and foreman release watch.
Some releases cannot finish inside foreman ship: a promotion someone clicks later, or a deployment that runs for hours. Foreman parks them. This page is for anyone whose release path has such a step, and for anyone who sees “Ready to promote” on the dashboard and wants to know what Foreman is waiting for. It also covers parking a slot, which is a different thing with the same word.
Why a release parks
A park is a release that has passed every check and is waiting, outside the run, for something that finishes later. A ship step that cannot finish now returns a park instead of a result: a reason in words, and a check, plain data the step can run later to see whether the release finished. foreman ship then exits 9 (see How a story ships): no later step runs, nothing halts, and the slot is freed for the next story. In Foreman 0.10.0 the core steps never park. The Salesforce pack’s Gearset promote step does, when salesforce.gearset.promote is owner: the owner clicks Promote in Gearset, and Foreman waits for the promotion pull request, its merge and the deploy into the stage’s org (Stages and release paths). The Salesforce pack is a preview: its release paths pass their own tests, but no story has yet shipped through them on a live org, and the Gearset path has not run against a live Gearset pipeline. A park with no reason, or with a check that cannot be stored, is a failure of that step with exit 1.
Before it exits, foreman ship records the park in three places:
- The park file,
parks/<id>.jsonin the state folder:{ id, step, reason, check, pr, slot, parkedAt }. It survives a restart, and with the run state on a branch it goes to the branch. - The story, through its source: status
ready-to-promote, with the note “ready to promote: <reason>” and the eventparked, which no story source moves an issue for. - The event feed: “<id> is ready to promote: <reason>”.
The printed result says how that went, parkSaved and storyUpdated. The story session then runs foreman story end ready-to-promote, which only frees the slot; the run trusts that claim only when the park foreman ship saved is there (or the story is already done, the watch having finished it meanwhile). A session that says ready-to-promote with no park is counted as failed, with a warning. After a restart, a parked story’s stale claim is let go and its release is left to finish on its own.
Ready to promote
On the dashboard, the run details card’s Finished tab has a Ready to promote list while any release is parked: each story with its reason, when it parked, when it was last checked, and a link to its pull request, under the note “Every check passed. Foreman moves each one to Done when its release finishes.” The same story appears under Waiting on you as “<id> <title> is ready to promote”, with the reason and the last check’s outcome, and a Check now button that runs foreman release watch at once instead of waiting for the next check. A check’s detail can carry what its tool printed, so the snapshot shows the outcome only.
foreman release watch
foreman release watch finishes the parked releases. The run does it for you every 5 minutes while any park exists, in a process of its own; you can run it by hand at any time. It reads every park, oldest first, and asks the step that parked it, through that step’s check, whether the release finished. A step taken out of ship.steps still answers for its parks. Each park ends one of four ways:
| Outcome | What happened | What Foreman does |
|---|---|---|
done |
The release finished. | Moves the story to Done through its source, with today’s date and the note “Released: <what the check said, or the park’s reason>”, removes the park, and writes “<id> shipped: the release finished” to the feed. |
failed |
The release failed for good, with a reason. | Blocks the story with the reason and the note “Release failed: <reason>”, removes the park, and writes a warning to the feed. Nothing halts: the failure is that story’s alone. |
waiting |
Still waiting. | Keeps the park, with lastCheck (when, outcome, detail), and tries again at the next watch. |
error |
The check threw, gave an answer Foreman cannot read, or the story source did not take the change. | Keeps the park with lastCheck, and writes the detail to the feed once, not again while it stays the same. The next watch tries again. |
The story leaves its park only once the story source took the change; a Done or a block the source refused is an error, and the park stays. The command prints one JSON line, { ok: true, checked, results: [{ id, step, outcome, detail }] }, and exits 0 whatever the parks said; a config that cannot be read exits 1. One watch runs at a time, through the lock locks/release-watch.json in the state folder; a second prints { ok: true, busy: true } and checks nothing. The command loads Foreman’s own keys from .env.foreman (the names every step in the table declares, since a park can belong to a step no longer in the list) and the project’s environment file, and prints neither. A check’s reason and detail go into the feed and the output, so a step never puts tokens, keys or addresses with credentials in them. With the run state on a branch, the command pulls before and pushes after.
A markdown story in state mode whose own commit marks it done cannot truly park; Foreman does not handle that case.
Parking a slot
A slot can be parked too: a parked slot picks up no stories until you unpark it. The slot actions on the dashboard (Dashboard) and foreman slot <wN> <action> do it:
| Action | What it does | When it applies |
|---|---|---|
Park (park) |
An idle or down slot parks at once, with the reason “Parked by you.”, and picks up nothing until you unpark it. On a building slot it parks the slot once its current story is done: the story in progress carries on to the end, then the slot parks. | idle, down, building |
Unpark (unpark) |
The slot goes back to idle and takes the next story that can be built. It lets go of the story it was parked on, which the picker takes again by priority. | parked by you |
Foreman parks a slot on its own in two cases, and says why on the slot’s row. Crash: the session stopped and could not carry on; Resume carries on from where it stopped, Restart begins the story again from the base branch, and Skip and Take over are there too. Dirty: the slot’s folder has changes that do not belong to a story. Changes a story left behind when it ended are not that: Foreman saves them on a local branch named leftover/<slot>-<story>-<date>, cleans the folder, writes an event naming the branch, and carries on. Any other dirty folder, or one whose save fails, parks the slot with “Its folder has changes that do not belong to a story.”, writes a warning to the feed naming the slot, the reason and the branch the folder is on, and sends the “parked” notification. Resume as is keeps the changes; Discard throws them away and resets the folder. A parked slot waits for you; the run never unparks it by itself.
Was this page useful? Something missing or wrong?Email us and say which section.