Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions .github/workflows/fork-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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="<!-- fork-release fork=$FORK_SHA upstream=$UPSTREAM_SHA upstream-tag=$UPSTREAM_TAG -->"
previous=$(gh release list --repo "$GITHUB_REPOSITORY" --limit 1 --json tagName --jq '.[0].tagName // ""')
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
gh release create "$TAG" publish/* \
--repo "$GITHUB_REPOSITORY" \
--target "$FORK_BRANCH" \
Expand Down
6 changes: 4 additions & 2 deletions FORK.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
48 changes: 48 additions & 0 deletions fork/release-notes.sh
Original file line number Diff line number Diff line change
@@ -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 '<!-- fork-release fork=%s upstream=%s upstream-tag=%s -->\n' "$TARGET" "$UPSTREAM_SHA" "$UPSTREAM_TAG"
4 changes: 2 additions & 2 deletions fork/upstream-nightly-watcher/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 <tag> 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=<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`;
Expand Down
Loading