Skip to content

colophon announce

Description

Tell people a release happened

Read the release a tag carries and hand it to each adapter .colophon.yaml configures. Two today — discord posts to a chat channel, and file appends the release to a YAML or JSON file in another repository and commits it. A newsletter is the reason the adapters are a seam rather than a webhook call.

A release announces itself from the verb that created it — publish or release — so this verb is for announcing again: a delivery that failed, a channel added after the fact, a release somebody made by hand. It reads the release rather than the changelog, so the words it quotes and the words a reader finds on arrival are the same.

Usage

colophon announce --tag <tag> [flags]

Run colophon announce --help for the authoritative, always-current flag set.

What an announcement is made from

The release notes are the foundation and not the text. Every adapter is built from them and none of them delivers them as they are: a Discord embed wants a title, a colour, a footer and about twelve hundred characters; a newsletter wants a subject line and probably the whole thing; a blog post wants front matter and a permalink.

So an adapter is handed the notes and the facts they were rendered from — project, tag, version, release size, URL — and decides what to make of them.

It announces at least once

This is the only thing colophon does that is not idempotent, and it says so.

Everything else has an answer for being run twice. A release that exists is reported rather than created again. A tag that exists is left alone. A comment apply posts carries an idempotency key the forge honours, so the provider returns the existing one.

Whether it can is the adapter's answer, not this verb's, and it turns on whether the medium can be READ back.

The file adapter can: the entry it appends carries a key and the file is the record, so a retried pipeline re-reads it, finds its own previous write and reports unchanged. No marker, no database, no state kept anywhere else.

The same read is what lets several releases announce into one feed at once. A push that loses the race to another release's push is retried on top of it, up to five attempts with a short random pause between them, so a burst of releases needs no re-announce pass afterwards.

A webhook execution has no such key and nothing to look up, so the discord adapter cannot tell, announces again on a retry, and never claims otherwise. Colophon will not manufacture a guarantee out of state it would have to keep correct forever.

What it reports

  announced  discord
  skipped    newsletter — a patch release, and this announces minor or larger

And when something did not go out:

  failed     discord — 502 Bad Gateway

1 of 2 did not go out.
The release stands; nothing here failed the pipeline.

The exit code is zero either way, unless you ask for one. By the time this runs the release is public, and a red pipeline over a chat message is worse signal than a yellow one. One adapter failing does not stop the others: an announcement that did not reach Discord is no reason to withhold one from a mailing list.

--announce-failure-exit <n> makes a run with a failed line exit n, so a CI job that declares n an allowed failure goes yellow. The last line then says so:

The release stands; exiting 3 so the job shows it.

0, the default, is unset. 1 and 2 are refused, because they already mean "something failed" and "called wrong", and so is anything above 125, which the shell uses. publish and release take the same flag.

When announce cannot start at all (the announce block does not resolve, an adapter cannot be built, the release cannot be read) it is an error and exits 1, flag or no flag. publish and release report the same faults as failed lines, because their release already exists.

Re-sending to one channel

--only limits a run to the adapters or channels it names: an adapter as discord, one of its channels as discord.majors. Give it more than once, or comma-separated, for several. when still applies to what it keeps.

colophon announce --tag v1.4.0 --only discord.majors

It is for the case at-least-once leaves behind: one channel failed and the others did not, and re-running all of them would post twice where it worked. Every name is checked against the resolved manifest before anything is posted, and one it does not configure is refused, listing the names it does. publish and release do not take it, because the run that creates a release announces everywhere.

Configuration

See announce in the release manifest for the block, the when filter and why a webhook is named rather than written.

In the pipeline

It belongs on the tag pipeline after the job that creates the release. It is deliberately not part of release: an announcement that fails should not fail a release that succeeded, and retrying one should not re-run the other.