A failed version job is reported as no release warranted #86

Closed
opened 2026-09-10 06:31:42 +00:00 by ahmad · 1 comment
Owner

Context

The release notification's details line describes the outcome, beside the
status word. When the version job fails, needs.version.outputs.released
is empty rather than 'true', so the expression falls through every earlier
branch to its last one and the notification reads:

❌ Release — no release warranted by the commits

The status is correct. The sentence beside it describes a different outcome
entirely — a clean run over commits that warranted nothing, which is a
non-event, rather than a job that fell over and wants somebody looking.

Found while reviewing #85, which added a checks-first branch to the same
line. It is pre-existing and was deliberately left out of that change.

Scope

  • In: the details expression in templates/release.yml, and the same line in
    the consumers that already carry it.
  • Out: the status expression — it is correct in this case and was verified
    over all its combinations in #85.

Acceptance criteria

  • Given the version job fails, when the notification is sent, then its
    details line says the version step failed and does not claim the commits
    warranted no release.
  • Given a run over commits that warrant no release, when the notification is
    sent, then its details line still reads as it does today.
  • Given every other combination of job results, when the notification is
    sent, then its details line is unchanged from today's.
### Context The release notification's `details` line describes the outcome, beside the status word. When the `version` job **fails**, `needs.version.outputs.released` is empty rather than `'true'`, so the expression falls through every earlier branch to its last one and the notification reads: > ❌ Release — no release warranted by the commits The status is correct. The sentence beside it describes a different outcome entirely — a clean run over commits that warranted nothing, which is a non-event, rather than a job that fell over and wants somebody looking. Found while reviewing `#85`, which added a `checks`-first branch to the same line. It is pre-existing and was deliberately left out of that change. ### Scope - In: the `details` expression in `templates/release.yml`, and the same line in the consumers that already carry it. - Out: the `status` expression — it is correct in this case and was verified over all its combinations in `#85`. ### Acceptance criteria - [ ] Given the `version` job fails, when the notification is sent, then its details line says the version step failed and does not claim the commits warranted no release. - [ ] Given a run over commits that warrant no release, when the notification is sent, then its details line still reads as it does today. - [ ] Given every other combination of job results, when the notification is sent, then its details line is unchanged from today's.
ahmad self-assigned this 2026-09-11 00:16:27 +00:00
Author
Owner

Done — the template and all thirteen consumers carry the branch.

# repository pull request merge
— amtronics/platform-actions (template) #87 42de7012
1 ahmad/larda #110 1a15efb1
2 ahmad/imamah #167 9ad44d89
3 ahmad/trip #150 26533416
4 ahmad/portfolio #97 05c891da
5 ahmad/launchpad #93 c56b14ef
6 ahmad/namey #90 b8c049d6
7 ahmad/expiro #95 a914b001
8 Bayan/bayan-web #39 5e513e82
9 Bayan/kidpoints #219 8a835e35
10 suhba/suhba-web #49 60ab4d13
11 suhba/suhba-docs #22 78419ebe
12 suhba/khitta #62 d86003b3
13 amtronics/forgejo-mcp #4 10f50624

Every one released green on merge. Bayan/stem is deliberately absent: it carries a different defect in the same line — no released branch at all, so a failed version prints version: v with a hole where the number should be — and it is recorded separately rather than filed as a fourteenth copy of this.

What the three criteria cost, and what it turned up

Criterion 3 — every other combination is unchanged — was the expensive one, and it was worth the price twice.

Enumeration found a second defect the report did not mention. Evaluating the expression over every combination of job results showed that half the changed cases were not the reported symptom: they had printed the full success line while version had failed, reachable because a job can set its outputs and then fall over in a later step, leaving released == 'true' on a failed job. Announcing a release that did not happen is worse than announcing a non-event, and no amount of reading the expression surfaced it.

Two consumers were not copies, and copying the template into them would have been wrong. ahmad/trip has four check jobs rather than one, so needs.checks.result has no referent there; ahmad/trip and ahmad/portfolio both lack notes_fallback, so the template's four-argument success line would have cited an output that does not exist. That failure is silent — a missing output evaluates to empty — so the message would have looked right forever while carrying a warning that could never fire. Both were adapted and enumerated on their own terms (32768 and 512 combinations).

Two more were the same text indented four spaces shallower, where byte-identity fails while telling you nothing. Those were verified on the parsed value instead: strip all whitespace from the folded scalar and assert old == template old, new == template new, and new minus the inserted branch == old. Both were realigned in the same change, so the cheap check works on them from now on.

The other nine were straight copies, and there the check that earned its keep was byte-identity on both sides — identical to the template at 42de7012^ and at 42de7012. The before-check is what makes #87's own verification transferable rather than merely suggestive.

Closing this as done.

**Done — the template and all thirteen consumers carry the branch.** | # | repository | pull request | merge | |---|---|---|---| | — | `amtronics/platform-actions` (template) | `#87` | `42de7012` | | 1 | `ahmad/larda` | `#110` | `1a15efb1` | | 2 | `ahmad/imamah` | `#167` | `9ad44d89` | | 3 | `ahmad/trip` | `#150` | `26533416` | | 4 | `ahmad/portfolio` | `#97` | `05c891da` | | 5 | `ahmad/launchpad` | `#93` | `c56b14ef` | | 6 | `ahmad/namey` | `#90` | `b8c049d6` | | 7 | `ahmad/expiro` | `#95` | `a914b001` | | 8 | `Bayan/bayan-web` | `#39` | `5e513e82` | | 9 | `Bayan/kidpoints` | `#219` | `8a835e35` | | 10 | `suhba/suhba-web` | `#49` | `60ab4d13` | | 11 | `suhba/suhba-docs` | `#22` | `78419ebe` | | 12 | `suhba/khitta` | `#62` | `d86003b3` | | 13 | `amtronics/forgejo-mcp` | `#4` | `10f50624` | Every one released green on merge. `Bayan/stem` is deliberately absent: it carries a **different** defect in the same line — no `released` branch at all, so a failed `version` prints `version: v` with a hole where the number should be — and it is recorded separately rather than filed as a fourteenth copy of this. ### What the three criteria cost, and what it turned up Criterion 3 — *every other combination is unchanged* — was the expensive one, and it was worth the price twice. **Enumeration found a second defect the report did not mention.** Evaluating the expression over every combination of job results showed that half the changed cases were not the reported symptom: they had printed the **full success line while `version` had failed**, reachable because a job can set its outputs and then fall over in a later step, leaving `released == 'true'` on a failed job. Announcing a release that did not happen is worse than announcing a non-event, and no amount of reading the expression surfaced it. **Two consumers were not copies, and copying the template into them would have been wrong.** `ahmad/trip` has four check jobs rather than one, so `needs.checks.result` has no referent there; `ahmad/trip` and `ahmad/portfolio` both lack `notes_fallback`, so the template's four-argument success line would have cited an output that does not exist. That failure is **silent** — a missing output evaluates to empty — so the message would have looked right forever while carrying a warning that could never fire. Both were adapted and enumerated on their own terms (32768 and 512 combinations). **Two more were the same text indented four spaces shallower**, where byte-identity fails while telling you nothing. Those were verified on the parsed value instead: strip all whitespace from the folded scalar and assert *old == template old*, *new == template new*, and *new minus the inserted branch == old*. Both were realigned in the same change, so the cheap check works on them from now on. The other nine were straight copies, and there the check that earned its keep was byte-identity **on both sides** — identical to the template at `42de7012^` *and* at `42de7012`. The before-check is what makes `#87`'s own verification transferable rather than merely suggestive. Closing this as done.
ahmad 2026-09-11 07:43:47 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
amtronics/platform-actions#86
No description provided.