Skip to content

feat(NO-TASK): Add the release post action - #1

Merged
aaronware merged 1 commit into
mainfrom
feat/release-post-action
Aug 10, 2026
Merged

aaronware merged 1 commit into
mainfrom
feat/release-post-action

Conversation

@aaronware

Copy link
Copy Markdown
Contributor

The initial contents of this repo. Paired with
linchpin/linchpin.com#1023, which adds
the endpoint this calls.

main is an empty root commit — the repo had no commits, so there was no base to open a PR
against. Everything real is in this one.

What it does

Reports a published GitHub release to linchpin/v1/release-post on builditbelieveit.com,
which writes the draft post. Nothing is generated here; this only rings the bell and reports
where the draft landed.

A caller usually passes product and the credentials — the rest defaults off the release
event.

Choices worth reviewing

  • Everything reaches the script through env:. Release notes are built from commit
    messages, including bot ones, so a ${{ }} inside a run: block would be a shell
    injection. The payload is assembled with jq for the same reason string quoting cannot
    survive multi-line markdown intact.
  • The response is read as text before anything parses it as JSON. This request crosses
    Cloudflare Access and a WAF before reaching WordPress and all three answer with HTML when
    unhappy, so a non-JSON body reports status, content-type, cf-ray and the first 300
    bytes rather than a parse error.
  • Failures annotate and exit 0 by default. A release must not be held up because the
    blog was unreachable. fail-on-error: true flips it.
  • Retries only what a retry can fix — 000, 429, 5xx. A 4xx is our own bad request
    and would fail identically three times.
  • CI lints action.yml, which the shared linchpin/actions CI does not do for its own
    composite actions, and runs this action against itself in dry-run mode so the wiring is
    covered without credentials.

Verification

Exercised against a stub endpoint across nine cases: created, ungenerated-overview warning,
human_edited, already_published, two 503s then success, a Cloudflare HTML challenge page
with and without fail-on-error, a 401, and dry-run. Payload and headers were confirmed
byte-for-byte on the wire, including that the credential is masked before it can reach a log
line. YAML parses and is within the 125-column limit; bash -n clean.

Before the first caller can use this

  • This repo is private, so it is invisible to other repos by default. Set
    Settings → Actions → General → Access → Accessible from repositories in the linchpin
    organization
    , or every caller fails with "repository not found".
  • The bot user, application password, Cloudflare Access service token and org secrets — see
    Setup in the README.
  • release-as: "1.0.0" is pinned in release-please-config.json so the first tag matches
    the @v1 contract callers use. Remove it once v1.0.0 has shipped, or every subsequent
    release will try to be 1.0.0 again.

Scope

Committed as NO-TASK. Happy to amend with a ClickUp key.

Composite action that reports a published GitHub release to the
linchpin/v1/release-post endpoint on builditbelieveit.com, which writes
the draft post. Nothing is generated here.

Everything reaches the script through the environment — release notes are
built from commit messages, including bot ones, so interpolating them into
a run block would be a shell injection. The payload is assembled with jq
for the same reason string quoting cannot survive multi-line markdown.

The response is read as text before anything parses it as JSON. This
request crosses Cloudflare Access and a WAF before it reaches WordPress and
all three answer with HTML when unhappy, so a non-JSON body reports status,
content-type, cf-ray and a snippet rather than a parse error.

Failures annotate and exit 0 by default. A release must not be held up
because the blog was unreachable.

CI lints action.yml as well as the workflows, which the shared actions repo
does not do for its own composite actions, and runs the action against
itself in dry-run mode so the wiring is covered without credentials.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@aaronware
aaronware merged commit 9b48ae4 into main Aug 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant