mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-20 12:29:09 +02:00
[misc] Announce tag-pushed releases on the forum (#8265)
* [misc] Announce tag-pushed releases on the forum Since 0.77 a release is cut by pushing a tag, and goreleaser creates the GitHub release with GITHUB_TOKEN. Events raised by that token start no workflow, so the release:published trigger never fires for them and 0.78.0, 0.79.0, 0.80.0, 0.81.0 and 0.81.3 got no forum topic, while releases published from the UI still did. Post from the completion of the Release workflow instead, for tag runs that succeeded and whose release was created by the bot. Release candidates stay off the forum, and an existing topic with the same title is left alone so re-running a green Release run does not post twice. * [misc] Point an empty forum post at the release notes goreleaser creates the release with an empty body and the notes are written on the release page afterwards, so the topic would otherwise hold only its title link. Say where the notes and downloads are. * [misc] Fail closed in the forum post lookups Announce stable tags only: every pre-release tag carries a hyphen, so canaries and release candidates pushed as tags stay off the forum. A failed release lookup now fails the step instead of passing as "no release"; only a 404 skips. The duplicate check searches by title rather than reading the first page of the category, and a failed search stops the step instead of falling through to a post. Discourse requests refuse any non-HTTPS redirect and retry transient errors.
This commit is contained in:
@@ -3,9 +3,16 @@ name: Post release topic on Discourse
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_run:
|
||||
workflows: [Release]
|
||||
types: [completed]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
post:
|
||||
if: github.event_name == 'release'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: roots/discourse-topic-github-release-action@557d74ea05b6cc0c47f555c1d5d28a89d904005b # v1.1.0
|
||||
@@ -15,3 +22,78 @@ jobs:
|
||||
discourse-author-username: NetBird
|
||||
discourse-category: 17
|
||||
discourse-tags: releases
|
||||
|
||||
# goreleaser publishes the release of a pushed tag with GITHUB_TOKEN, and events
|
||||
# raised by that token start no workflow, so the release event above never fires.
|
||||
post-tag-release:
|
||||
if: >-
|
||||
github.event_name == 'workflow_run' &&
|
||||
github.event.workflow_run.event == 'push' &&
|
||||
github.event.workflow_run.conclusion == 'success' &&
|
||||
startsWith(github.event.workflow_run.head_branch, 'v') &&
|
||||
!contains(github.event.workflow_run.head_branch, '-')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Post the release topic
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
TAG: ${{ github.event.workflow_run.head_branch }}
|
||||
DISCOURSE_API_KEY: ${{ secrets.DISCOURSE_RELEASES_API_KEY }}
|
||||
DISCOURSE_URL: https://forum.netbird.io
|
||||
DISCOURSE_USER: NetBird
|
||||
DISCOURSE_CATEGORY: "17"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if ! release=$(gh api "repos/${GITHUB_REPOSITORY}/releases/tags/${TAG}" 2>gh.err); then
|
||||
if grep -q 'HTTP 404' gh.err; then
|
||||
echo "no release for ${TAG}, nothing to announce"
|
||||
exit 0
|
||||
fi
|
||||
cat gh.err >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# A release a person published already fired the release event above.
|
||||
author=$(jq -r '.author.login' <<<"$release")
|
||||
if [ "$author" != "github-actions[bot]" ] || [ "$(jq -r '.draft' <<<"$release")" = "true" ]; then
|
||||
echo "${TAG} published by ${author}, announced by the release event"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Same title and body as the action above, so both paths read alike.
|
||||
title="${GITHUB_REPOSITORY#*/} ${TAG} released"
|
||||
|
||||
# A re-run of a successful Release run fires this event again. A failed lookup
|
||||
# stops the step rather than risk a duplicate topic.
|
||||
search=$(curl -fsS --retry 3 --proto '=https' --proto-redir '=https' -G \
|
||||
-H "Api-Key: ${DISCOURSE_API_KEY}" \
|
||||
-H "Api-Username: ${DISCOURSE_USER}" \
|
||||
"${DISCOURSE_URL}/search.json" \
|
||||
--data-urlencode "q=\"${title}\" in:title")
|
||||
existing=$(jq -r --arg t "$title" --argjson c "$DISCOURSE_CATEGORY" \
|
||||
'[(.topics // [])[] | select(.category_id == $c and (.title | ascii_downcase) == ($t | ascii_downcase))] | length' \
|
||||
<<<"$search")
|
||||
if [ "$existing" != "0" ]; then
|
||||
echo "topic '${title}' already exists"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# goreleaser leaves the body empty; the notes are written on the release page afterwards.
|
||||
url=$(jq -r '.html_url' <<<"$release")
|
||||
body=$(jq -r '.body // ""' <<<"$release")
|
||||
if [ -z "${body//[[:space:]]/}" ]; then
|
||||
body="Release notes and downloads: ${url}"
|
||||
fi
|
||||
|
||||
jq -n \
|
||||
--arg title "$title" \
|
||||
--arg raw "$(printf '[%s](%s)\n\n%s' "$title" "$url" "$body")" \
|
||||
--argjson category "$DISCOURSE_CATEGORY" \
|
||||
'{title: $title, raw: $raw, category: $category, tags: ["releases"]}' \
|
||||
| curl -fsS -X POST "${DISCOURSE_URL}/posts.json" \
|
||||
-H "Api-Key: ${DISCOURSE_API_KEY}" \
|
||||
-H "Api-Username: ${DISCOURSE_USER}" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data @- \
|
||||
| jq -r '"posted \(env.DISCOURSE_URL)/t/\(.topic_slug)/\(.topic_id)"'
|
||||
|
||||
Reference in New Issue
Block a user