From c9c90dcf288ceb4d3dcea45b210170954d1a21a5 Mon Sep 17 00:00:00 2001 From: collissimo <148455189+collissimo@users.noreply.github.com> Date: Fri, 23 Oct 2026 19:02:23 +0200 Subject: [PATCH 1/2] Fork release: real release notes from upstream and fork pull requests The notes said only which commits were built. They now list upstream's notes for every nightly since the previous fork build, then the fork's pull requests, so the update popup and the release page show what changed. The commits move into a hidden comment that the skip check, the watcher and the watchdog read. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/fork-release.yml | 19 ++++++---- FORK.md | 6 ++-- fork/release-notes.sh | 48 +++++++++++++++++++++++++ fork/upstream-nightly-watcher/worker.js | 4 +-- 4 files changed, 66 insertions(+), 11 deletions(-) create mode 100755 fork/release-notes.sh diff --git a/.github/workflows/fork-release.yml b/.github/workflows/fork-release.yml index bb8be20795e7b..5c8b72e7c0a53 100644 --- a/.github/workflows/fork-release.yml +++ b/.github/workflows/fork-release.yml @@ -90,7 +90,7 @@ jobs: if [[ -n "$last" ]]; then body=$(gh release view "$last" --repo "$GITHUB_REPOSITORY" --json body --jq .body) fi - if [[ "$FORCE" != "true" && "$body" == *"Fork: $FORK_SHA"* && "$body" == *"Upstream: $UPSTREAM_SHA"* ]]; then + if [[ "$FORCE" != "true" && "$body" == *"fork=$FORK_SHA upstream=$UPSTREAM_SHA "* ]]; then echo "$last already has fork $FORK_SHA and upstream $UPSTREAM_SHA." echo "due=false" >> "$GITHUB_OUTPUT" else @@ -253,7 +253,7 @@ jobs: if [[ -n "$last" ]]; then body=$(gh release view "$last" --repo "$GITHUB_REPOSITORY" --json body --jq .body) fi - if [[ "$body" == *"upstream $UPSTREAM_TAG "* ]]; then + if [[ "$body" == *"upstream-tag=$UPSTREAM_TAG "* ]]; then echo "$UPSTREAM_TAG is already released." exit 0 fi @@ -459,11 +459,16 @@ jobs: run: | set -euo pipefail ls -la publish - notes=$(printf '%s\n' \ - "Windows x64 and Linux x64 builds of upstream $UPSTREAM_TAG with the fork's features (see FORK.md). Unsigned." \ - "" \ - "Fork: $FORK_SHA" \ - "Upstream: $UPSTREAM_SHA") + # Missing notes must not hold back a build; the marker alone still records it. + marker="" + previous=$(gh release list --repo "$GITHUB_REPOSITORY" --limit 1 --json tagName --jq '.[0].tagName // ""') + gh api "repos/$GITHUB_REPOSITORY/contents/fork/release-notes.sh?ref=$GITHUB_SHA" \ + -H "Accept: application/vnd.github.raw" > "$RUNNER_TEMP/release-notes.sh" + if ! notes=$(REPO="$GITHUB_REPOSITORY" TARGET="$FORK_SHA" PREVIOUS_TAG="$previous" \ + bash "$RUNNER_TEMP/release-notes.sh"); then + echo "::warning::release notes failed; publishing without them" + notes="$marker" + fi gh release create "$TAG" publish/* \ --repo "$GITHUB_REPOSITORY" \ --target "$FORK_BRANCH" \ diff --git a/FORK.md b/FORK.md index 8b9792b0252eb..0447a3df6832d 100644 --- a/FORK.md +++ b/FORK.md @@ -82,8 +82,10 @@ check. - T3 Connect needs the public relay and Clerk values that upstream bakes in. They are repository variables here: `T3CODE_RELAY_URL`, `T3CODE_CLERK_PUBLISHABLE_KEY`, `T3CODE_CLERK_JWT_TEMPLATE`, `T3CODE_CLERK_CLI_OAUTH_CLIENT_ID`. Upstream's telemetry tokens are deliberately not copied. -- The tag sits on the `collin/main` commit; the release notes name the fork and upstream commits - the build merged. +- The tag sits on the `collin/main` commit. The release notes (`fork/release-notes.sh`) are + upstream's notes for every nightly since the previous fork build, then the fork's pull + requests since then; the update popup shows them. A hidden comment at the end records the fork + and upstream commits, which the skip check, the watcher and the watchdog read. ## Keeping changes mergeable diff --git a/fork/release-notes.sh b/fork/release-notes.sh new file mode 100755 index 0000000000000..f4b1a61778d62 --- /dev/null +++ b/fork/release-notes.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Release notes of a fork build: the notes of every upstream nightly since the previous fork +# release, then the fork's own pull requests since then. The app's update popup and the GitHub +# release page both show this body. A trailing HTML comment, invisible in both, records what was +# built for fork-release.yml and the watcher. +# +# Env: REPO (owner/name), TAG (new release tag), TARGET (fork commit), UPSTREAM_TAG, +# UPSTREAM_SHA, PREVIOUS_TAG (the fork's latest release before this one, may be empty). +set -euo pipefail + +# Only the bullet list of a GitHub "What's Changed" body; the app stops reading at +# "New Contributors" and "Full Changelog", so neither may appear before the fork's list. +changes() { + sed -e '/^## New Contributors/,$d' -e '/^\*\*Full Changelog\*\*/,$d' | grep -E '^[*-] ' || true +} + +previous_upstream="" +if [[ -n "$PREVIOUS_TAG" ]]; then + previous_body=$(gh release view "$PREVIOUS_TAG" --repo "$REPO" --json body --jq .body) + previous_upstream=$(grep -oE 'upstream-tag=[^ ]+|builds of upstream [^ ]+' <<<"$previous_body" | head -n 1 | sed -E 's/.*[= ]//' || true) +fi + +# Upstream nightlies after the previous build's, up to this build's, oldest first: the app +# shows the last items of a body first, so the newest nightly sits right above the fork's list. +nightlies=$(gh release list --repo pingdotgg/t3code --limit 50 --exclude-drafts --json tagName,publishedAt \ + --jq "[.[] | select(.tagName | contains(\"-nightly.\"))] | sort_by(.publishedAt) | map(.tagName) + | (index(\"$UPSTREAM_TAG\")) as \$to | (index(\"$previous_upstream\") // ((\$to // 0) - 1)) as \$from + | if \$to == null then [\"$UPSTREAM_TAG\"] else .[(\$from + 1):(\$to + 1)] end | .[]") + +upstream_changes="" +for nightly in $nightlies; do + upstream_changes+=$(gh release view "$nightly" --repo pingdotgg/t3code --json body --jq .body | changes) + upstream_changes+=$'\n' +done + +fork_changes="" +if [[ -n "$PREVIOUS_TAG" ]]; then + fork_changes=$(gh api "repos/$REPO/releases/generate-notes" -f tag_name="$TAG" \ + -f target_commitish="$TARGET" -f previous_tag_name="$PREVIOUS_TAG" --jq .body | changes) +fi + +if [[ -n "${upstream_changes//[[:space:]]/}" ]]; then + printf '## T3 Code\n%s\n' "$upstream_changes" +fi +if [[ -n "$fork_changes" ]]; then + printf '## Fork\n%s\n\n' "$fork_changes" +fi +printf '\n' "$TARGET" "$UPSTREAM_SHA" "$UPSTREAM_TAG" diff --git a/fork/upstream-nightly-watcher/worker.js b/fork/upstream-nightly-watcher/worker.js index b7dd10c44ce73..11f8059f5ec22 100644 --- a/fork/upstream-nightly-watcher/worker.js +++ b/fork/upstream-nightly-watcher/worker.js @@ -64,8 +64,8 @@ async function check(env) { if (!nightly) return "no upstream nightly"; const tag = nightly.tagName; - // fork-release.yml writes "builds of upstream with" into each release. - if (latest?.description?.includes(`upstream ${tag} `)) return `${tag} already released`; + // fork/release-notes.sh ends each release with a hidden "upstream-tag= " marker. + if (latest?.description?.includes(`upstream-tag=${tag} `)) return `${tag} already released`; // A failed build must not be redispatched every minute; the workflow's cron retries it. const workflow = `repos/${env.FORK}/actions/workflows/fork-release.yml`; From cb4a6c80113fea652354abe0ccf259d0923b4df3 Mon Sep 17 00:00:00 2001 From: collissimo <148455189+collissimo@users.noreply.github.com> Date: Fri, 23 Oct 2026 19:04:42 +0200 Subject: [PATCH 2/2] Fork release: a missing notes script no longer blocks publishing Co-Authored-By: Claude Opus 5.5 --- .github/workflows/fork-release.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/fork-release.yml b/.github/workflows/fork-release.yml index 5c8b72e7c0a53..1485635ed18bb 100644 --- a/.github/workflows/fork-release.yml +++ b/.github/workflows/fork-release.yml @@ -462,10 +462,10 @@ jobs: # Missing notes must not hold back a build; the marker alone still records it. marker="" previous=$(gh release list --repo "$GITHUB_REPOSITORY" --limit 1 --json tagName --jq '.[0].tagName // ""') - gh api "repos/$GITHUB_REPOSITORY/contents/fork/release-notes.sh?ref=$GITHUB_SHA" \ - -H "Accept: application/vnd.github.raw" > "$RUNNER_TEMP/release-notes.sh" - if ! notes=$(REPO="$GITHUB_REPOSITORY" TARGET="$FORK_SHA" PREVIOUS_TAG="$previous" \ - bash "$RUNNER_TEMP/release-notes.sh"); then + if ! { gh api "repos/$GITHUB_REPOSITORY/contents/fork/release-notes.sh?ref=$GITHUB_SHA" \ + -H "Accept: application/vnd.github.raw" > "$RUNNER_TEMP/release-notes.sh" && + notes=$(REPO="$GITHUB_REPOSITORY" TARGET="$FORK_SHA" PREVIOUS_TAG="$previous" \ + bash "$RUNNER_TEMP/release-notes.sh"); }; then echo "::warning::release notes failed; publishing without them" notes="$marker" fi