fix(github): create the release over the REST API; drop GitHub-only annotations #51

Merged
ryangr0 merged 2 commits from chore/forgejo-native-diagnostics into main 2026-08-25 09:45:32 +00:00
Owner

Two changes to the Forgejo tree, both from chasing the ploeg GitHub track to green.

1. fix(github): create the release over the REST API, not the gh CLI

The Forgejo ci-runner image does not ship gh. ploeg run 181 mirrored every branch and tag to github.com successfully and then died on the next line:

line 18: gh: command not found

leaving the repo mirrored but with no GitHub Release — the one part of the GitHub track that had never actually run.

Installing gh would have been the wrong fix: another github.com download on the release path, which is exactly the dependency that keeps flaking here (the syft installer took the signing job down in runs 172 and 175, then recovered on its own in 177). curl and jq are already present, and this step already used both for the Forgejo API.

gh release view → GET /releases/tags/{tag}. gh release create → POST /releases with a jq-built payload. --verify-tag is preserved explicitly, because POST /releases will otherwise create the tag as a side effect, and a release pointing at a tag the mirror never pushed would be a silent lie. GH_HOST is dropped — it only ever configured the CLI.

Verified against a stubbed curl across all five branches: release already exists, tag not mirrored, create with Forgejo notes, create with generated notes, and a 422.

2. chore(forgejo): drop GitHub-only annotation commands from .forgejo/

::error:: / ::warning:: / ::notice:: create annotations on GitHub. On Forgejo they create nothing — act_runner re-emits the line with a ❗ marker but keeps the raw ::error:: text, and the job API has no field to put an annotation in. $GITHUB_STEP_SUMMARY is not an alternative either; Forgejo dumps it into the log as one line with literal \n.

All 34 cosmetic sites in .forgejo/ become plain ERROR: / WARN: / NOTE:, with operator-actionable remediation on the last lines before exit 1.

  • ::add-mask:: untouched at all 5 sites — that one IS functional on act_runner and is what produces AUTHORIZATION: basic *** in checkout logs.
  • .github/ untouched, per ADR 002 — the commands do real work there.
  • README gains the convention, including the point that matters most: Forgejo's one structured surface is the step list, so a short well-named precondition step beats any log formatting.
Two changes to the Forgejo tree, both from chasing the ploeg GitHub track to green. ## 1. `fix(github)`: create the release over the REST API, not the `gh` CLI The Forgejo ci-runner image does not ship `gh`. ploeg run 181 mirrored every branch and tag to github.com successfully and then died on the next line: ``` line 18: gh: command not found ``` leaving the repo mirrored but with **no GitHub Release** — the one part of the GitHub track that had never actually run. Installing `gh` would have been the wrong fix: another github.com download on the release path, which is exactly the dependency that keeps flaking here (the syft installer took the signing job down in runs 172 and 175, then recovered on its own in 177). `curl` and `jq` are already present, and this step already used both for the Forgejo API. `gh release view` → `GET /releases/tags/{tag}`. `gh release create` → `POST /releases` with a jq-built payload. `--verify-tag` is preserved explicitly, because `POST /releases` will otherwise **create the tag as a side effect**, and a release pointing at a tag the mirror never pushed would be a silent lie. `GH_HOST` is dropped — it only ever configured the CLI. Verified against a stubbed curl across all five branches: release already exists, tag not mirrored, create with Forgejo notes, create with generated notes, and a 422. ## 2. `chore(forgejo)`: drop GitHub-only annotation commands from `.forgejo/` `::error::` / `::warning::` / `::notice::` create annotations on GitHub. On Forgejo they create nothing — `act_runner` re-emits the line with a `❗` marker but keeps the raw `::error::` text, and the job API has no field to put an annotation in. `$GITHUB_STEP_SUMMARY` is not an alternative either; Forgejo dumps it into the log as one line with literal `\n`. All 34 cosmetic sites in `.forgejo/` become plain `ERROR:` / `WARN:` / `NOTE:`, with operator-actionable remediation on the last lines before `exit 1`. - **`::add-mask::` untouched** at all 5 sites — that one IS functional on act_runner and is what produces `AUTHORIZATION: basic ***` in checkout logs. - **`.github/` untouched**, per ADR 002 — the commands do real work there. - README gains the convention, including the point that matters most: Forgejo's one structured surface is the **step list**, so a short well-named precondition step beats any log formatting.
chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree
Some checks failed
docker-build-and-push-registry.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
docker-build-and-push.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
forgejo-distribute.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
github-distribute.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
github-issue-create-by-prompt.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
github-issues-create-by-prompt.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
helm-chart-deploy.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
helm-chart-push.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
helm-charts-deploy.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
helm-charts-push.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
laravel-quality.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
php-application-static-analysis.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
rust-semantic-release.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
semantic-release-monorepo.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
semantic-release.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
setup-repository-bootstrap.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
setup-repository-copilot-files.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
setup-repository-create-from-template.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
spa-preview.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
static-analysis.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
sync-template-files.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
techdocs-deploy-backstage-s3.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
techdocs-deploy-codeberg.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
techdocs-deploy-docs-site.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
techdocs-deploy-gh-pages.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
tests.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
update_mkdocs.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
update_techdocs.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
wordpress-plugin-release-distribute.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
wordpress-plugin-release.yml / chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree (pull_request) Failing after 0s
a5c5b5f7ad
`::error::` / `:⚠️:` / `::notice::` buy nothing on Forgejo. act_runner
re-emits the line with a `❗` marker but keeps the raw `::error::` text, and the
job view has no annotations surface to put it on — so the only effect is an
uglier log line. Verified against the ploeg run 172 job API: `currentJob` is
just title/details/steps/allAttempts, with nowhere for an annotation to land.
`$GITHUB_STEP_SUMMARY` is no better; Forgejo dumps it into the log as one line
with literal `\n` sequences.

All 34 cosmetic sites in `.forgejo/` become plain `ERROR:` / `WARN:` / `NOTE:`
prefixes, and the operator-actionable ones (the GH_TOKEN preflights) become
short blocks with the remediation on the last lines before `exit 1` — the log
tail is what you land on when you expand a failed step. Kept on stdout: Forgejo
merges both streams into one untagged log, and separate buffers only risk
reordering the block.

`::add-mask::` is left alone at all 5 sites — that one IS functional on
act_runner, and is what produces `AUTHORIZATION: basic ***` in checkout logs.

`.github/` is untouched, per ADR 002: the commands do real work there.

README gains the convention, next to the existing Forgejo-divergence callout,
including the point that matters most — Forgejo's one structured surface is the
step list, so a short well-named precondition step beats any log formatting.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fix(github): create the release over the REST API, not the gh CLI
Some checks failed
docker-build-and-push-registry.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
docker-build-and-push.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
forgejo-distribute.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
github-distribute.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
github-issue-create-by-prompt.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
github-issues-create-by-prompt.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
helm-chart-deploy.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
helm-chart-push.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
helm-charts-deploy.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
helm-charts-push.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
laravel-quality.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
php-application-static-analysis.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
rust-semantic-release.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
semantic-release-monorepo.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
semantic-release.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
setup-repository-bootstrap.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
setup-repository-copilot-files.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
setup-repository-create-from-template.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
spa-preview.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
static-analysis.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
sync-template-files.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
techdocs-deploy-backstage-s3.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
techdocs-deploy-codeberg.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
techdocs-deploy-docs-site.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
techdocs-deploy-gh-pages.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
tests.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
update_mkdocs.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
update_techdocs.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
wordpress-plugin-release-distribute.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
wordpress-plugin-release.yml / Merge pull request 'fix(github): create the release over the REST API; drop GitHub-only annotations' (#51) from chore/forgejo-native-diagnostics into main (pull_request) Failing after 0s
0f2c5a56f8
The Forgejo ci-runner image does not ship `gh`. ploeg run 181 mirrored every
branch and tag to github.com successfully and then died on the next line with

    line 18: gh: command not found

leaving the repo mirrored but with no GitHub Release — the one part of the
GitHub track that had never actually run.

Installing gh was the wrong fix: it would put another github.com download on
the release path, which is precisely the dependency that keeps flaking here
(the syft installer took the signing job down in runs 172 and 175, and
recovered on its own in 177). curl and jq are already present and this step
already used both for the Forgejo API.

`gh release view` becomes GET /releases/tags/{tag}, and `gh release create`
becomes POST /releases with a jq-built payload. `--verify-tag` is preserved
explicitly, because POST /releases will otherwise CREATE the tag as a side
effect and a release pointing at a tag the mirror never pushed would be a
silent lie. GH_HOST is dropped; it only ever configured the gh CLI.

Verified by running the step body against a stubbed curl across all five
branches: release already exists, tag not mirrored, create with Forgejo notes,
create with generated notes, and a 422 from the API.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ryangr0 changed title from chore(forgejo): drop GitHub-only annotation commands from the .forgejo tree to fix(github): create the release over the REST API; drop GitHub-only annotations 2026-08-25 09:41:04 +00:00
webgrip-ci referenced this pull request from a commit 2026-08-25 09:46:30 +00:00
Sign in to join this conversation.
No reviewers
No labels
pull-request
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
webgrip/workflows!51
No description provided.