From f033bafe4e116a484b9b61711f65f17418477c6b Mon Sep 17 00:00:00 2001 From: Tee8z Date: Mon, 19 Oct 2026 17:34:55 -0400 Subject: [PATCH] ci: open a sync PR for each upstream desktop release A daily workflow finds the latest block/buzz desktop release that main does not contain, points a sync/ branch at it, and opens a PR to merge it with a merge commit. CodeRabbit skips these PRs because upstream already reviewed the code. Signed-off-by: Tee8z --- .coderabbit.yaml | 4 + .github/workflows/voltage-upstream-sync.yml | 91 +++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 .github/workflows/voltage-upstream-sync.yml diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 4aeb7e55df0..df59608120e 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -2,9 +2,13 @@ # Remote-agent work lands as stacked pull requests, so most bases are other # feature branches. CodeRabbit reviews only default-branch PRs unless # base_branches lists more. Drafts stay unreviewed until marked ready. +# Upstream sync PRs ("chore(sync): merge upstream ") carry block/buzz +# code that upstream already reviewed, so CodeRabbit skips them. reviews: auto_review: enabled: true drafts: false base_branches: - ".*" + ignore_title_keywords: + - "merge upstream" diff --git a/.github/workflows/voltage-upstream-sync.yml b/.github/workflows/voltage-upstream-sync.yml new file mode 100644 index 00000000000..74df3b571d8 --- /dev/null +++ b/.github/workflows/voltage-upstream-sync.yml @@ -0,0 +1,91 @@ +# Voltage fork only: opens a sync PR when block/buzz publishes a desktop +# release that main does not contain yet. Merge sync PRs with "Create a merge +# commit" so upstream commits keep their SHAs; see the upstream-fork-sync skill. +name: Upstream release sync + +on: + schedule: + - cron: "17 13 * * *" + workflow_dispatch: + inputs: + tag: + description: "Upstream release tag, for example desktop-v0.5.28 (default: latest desktop release)" + required: false + type: string + +permissions: + contents: write + pull-requests: write + +concurrency: + group: voltage-upstream-sync + cancel-in-progress: false + +jobs: + open-sync-pr: + name: Open sync PR + if: github.repository == 'voltagecloud/buzz' + runs-on: ubuntu-latest + timeout-minutes: 10 + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + UPSTREAM: block/buzz + INPUT_TAG: ${{ inputs.tag }} + steps: + - name: Open a sync PR for a new upstream release + run: | + set -euo pipefail + + tag="${INPUT_TAG:-}" + if [ -z "$tag" ]; then + tag=$(gh release list -R "$UPSTREAM" --exclude-drafts --exclude-pre-releases --limit 50 \ + --json tagName,publishedAt \ + --jq '[.[] | select(.tagName | startswith("desktop-v"))] | sort_by(.publishedAt) | last | .tagName // empty') + fi + if [ -z "$tag" ]; then + echo "No upstream desktop release found." + exit 0 + fi + if ! [[ "$tag" =~ ^desktop-v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Unexpected tag format: $tag" + exit 1 + fi + + sha=$(gh api "repos/$UPSTREAM/commits/$tag" --jq .sha) + status=$(gh api "repos/$REPO/compare/main...${UPSTREAM/\//:}:$tag" --jq .status) + if [ "$status" = "behind" ] || [ "$status" = "identical" ]; then + echo "main already contains $tag." + exit 0 + fi + + branch="sync/$tag" + existing=$(gh pr list -R "$REPO" --head "$branch" --state all --json number --jq '.[0].number // empty') + if [ -n "$existing" ]; then + echo "Sync PR #$existing already exists for $tag." + exit 0 + fi + + # The refs API points the branch at the upstream commit, which the + # fork network already stores. A git push of upstream workflow + # changes would need the workflows permission, which GITHUB_TOKEN + # cannot have. + if ! gh api "repos/$REPO/git/ref/heads/$branch" >/dev/null 2>&1; then + gh api -X POST "repos/$REPO/git/refs" -f ref="refs/heads/$branch" -f sha="$sha" >/dev/null + fi + + body=$(cat <