Skip to content

Sync upstream stable #52

Sync upstream stable

Sync upstream stable #52

Workflow file for this run

name: Sync upstream stable
on:
workflow_dispatch:
schedule:
- cron: "17 */6 * * *"
permissions:
contents: write
pull-requests: write
env:
UPSTREAM_REPO: pingdotgg/t3code
STABLE_BRANCH: stable
PLUS_BRANCH: plus
BUMP_PREFIX: version-bump/
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Checkout fork
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Configure Git
run: |
git config user.name "T3 Code Plus Bot"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Get latest upstream stable release
id: release
env:
GH_TOKEN: ${{ github.token }}
run: |
TAG=$(gh api "repos/${UPSTREAM_REPO}/releases/latest" --jq '.tag_name')
if [ -z "$TAG" ]; then
echo "Could not determine latest upstream release."
exit 1
fi
echo "Latest upstream stable release: $TAG"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
- name: Fetch latest upstream release
run: |
TAG="${{ steps.release.outputs.tag }}"
git remote add upstream "https://github.com/${UPSTREAM_REPO}.git" || true
# Fetch only the release tag we actually care about.
git fetch upstream \
"refs/tags/$TAG:refs/tags/$TAG" \
--force
- name: Determine release state
id: state
run: |
TAG="${{ steps.release.outputs.tag }}"
RELEASE_SHA=$(git rev-list -n 1 "$TAG")
CURRENT_STABLE=$(git ls-remote origin \
"refs/heads/${STABLE_BRANCH}" | cut -f1)
BUMP_BRANCH="${BUMP_PREFIX}${TAG}"
echo "Release tag: $TAG"
echo "Release SHA: $RELEASE_SHA"
echo "Current stable: ${CURRENT_STABLE:-<missing>}"
echo "Bump branch: $BUMP_BRANCH"
echo "release_sha=$RELEASE_SHA" >> "$GITHUB_OUTPUT"
echo "bump_branch=$BUMP_BRANCH" >> "$GITHUB_OUTPUT"
if [ "$CURRENT_STABLE" = "$RELEASE_SHA" ]; then
echo "new_release=false" >> "$GITHUB_OUTPUT"
echo "Stable is already on $TAG."
else
echo "new_release=true" >> "$GITHUB_OUTPUT"
echo "New stable release detected."
fi
# Always clean up PRs for older upstream releases.
- name: Close stale version bump PRs
env:
GH_TOKEN: ${{ github.token }}
run: |
CURRENT_BRANCH="${{ steps.state.outputs.bump_branch }}"
gh pr list \
--state open \
--base "$PLUS_BRANCH" \
--json number,headRefName \
--jq '.[] | select(.headRefName | startswith("'"$BUMP_PREFIX"'")) | "\(.number) \(.headRefName)"' \
| while read -r PR_NUMBER HEAD_BRANCH; do
if [ "$HEAD_BRANCH" != "$CURRENT_BRANCH" ]; then
echo "Closing stale PR #$PR_NUMBER ($HEAD_BRANCH)"
gh pr comment "$PR_NUMBER" \
--body "Closing automatically because a newer upstream stable release is available."
gh pr close "$PR_NUMBER" \
--delete-branch
fi
done
# If this is genuinely a new release, move stable.
- name: Update stable branch
if: steps.state.outputs.new_release == 'true'
run: |
RELEASE_SHA="${{ steps.state.outputs.release_sha }}"
echo "Moving ${STABLE_BRANCH} to $RELEASE_SHA"
git push origin \
"$RELEASE_SHA:refs/heads/${STABLE_BRANCH}" \
--force
# Check whether a PR for the CURRENT release is already open.
- name: Find existing version bump PR
id: existing_pr
env:
GH_TOKEN: ${{ github.token }}
run: |
BUMP_BRANCH="${{ steps.state.outputs.bump_branch }}"
PR_NUMBER=$(gh pr list \
--state open \
--base "$PLUS_BRANCH" \
--head "$BUMP_BRANCH" \
--json number \
--jq '.[0].number // empty')
echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
if [ -n "$PR_NUMBER" ]; then
echo "Existing PR: #$PR_NUMBER"
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "No existing PR for current release."
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
# Only create a bump branch for an ACTUAL new release.
- name: Create version bump branch
if: steps.state.outputs.new_release == 'true'
run: |
RELEASE_SHA="${{ steps.state.outputs.release_sha }}"
BUMP_BRANCH="${{ steps.state.outputs.bump_branch }}"
echo "Creating $BUMP_BRANCH at $RELEASE_SHA"
git push origin \
"$RELEASE_SHA:refs/heads/$BUMP_BRANCH" \
--force
# Only create a PR when:
# - this is a new release
# - and one doesn't already exist
- name: Create version bump PR
if: >
steps.state.outputs.new_release == 'true' &&
steps.existing_pr.outputs.exists == 'false'
id: create_pr
env:
GH_TOKEN: ${{ github.token }}
run: |
TAG="${{ steps.release.outputs.tag }}"
BUMP_BRANCH="${{ steps.state.outputs.bump_branch }}"
PR_URL=$(gh pr create \
--base "$PLUS_BRANCH" \
--head "$BUMP_BRANCH" \
--title "chore: update upstream to $TAG" \
--body "## Upstream version update
Updates **T3 Code Plus** to upstream stable release **$TAG**.
- Upstream: \`$UPSTREAM_REPO\`
- Stable tag: \`$TAG\`
- Stable branch: \`$STABLE_BRANCH\`
- Target branch: \`$PLUS_BRANCH\`
This PR was created automatically.
If it can be merged cleanly, the workflow will merge it automatically.
If there is a merge conflict or another merge failure, this PR will remain open for manual resolution.")
PR_NUMBER=$(gh pr view "$PR_URL" \
--json number \
--jq '.number')
echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
# Pick either:
# - the already-open PR
# - or the newly-created PR
- name: Resolve current PR
id: current_pr
run: |
EXISTING="${{ steps.existing_pr.outputs.number }}"
CREATED="${{ steps.create_pr.outputs.number }}"
if [ -n "$EXISTING" ]; then
PR_NUMBER="$EXISTING"
elif [ -n "$CREATED" ]; then
PR_NUMBER="$CREATED"
else
PR_NUMBER=""
fi
echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
if [ -n "$PR_NUMBER" ]; then
echo "Current version bump PR: #$PR_NUMBER"
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "There is no version bump PR to process."
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Check PR mergeability
if: steps.current_pr.outputs.exists == 'true'
id: mergeability
env:
GH_TOKEN: ${{ github.token }}
run: |
PR_NUMBER="${{ steps.current_pr.outputs.number }}"
MERGEABLE="UNKNOWN"
for i in {1..10}; do
MERGEABLE=$(gh pr view "$PR_NUMBER" \
--json mergeable \
--jq '.mergeable')
echo "Mergeability: $MERGEABLE"
if [ "$MERGEABLE" != "UNKNOWN" ]; then
break
fi
sleep 3
done
echo "mergeable=$MERGEABLE" >> "$GITHUB_OUTPUT"
- name: Merge clean version bump
if: >
steps.current_pr.outputs.exists == 'true' &&
steps.mergeability.outputs.mergeable == 'MERGEABLE'
env:
GH_TOKEN: ${{ github.token }}
run: |
PR_NUMBER="${{ steps.current_pr.outputs.number }}"
echo "PR #$PR_NUMBER is mergeable."
if gh pr merge "$PR_NUMBER" \
--merge \
--delete-branch; then
echo "Version bump merged successfully."
else
echo "Automatic merge failed."
echo "Leaving PR #$PR_NUMBER open."
fi
- name: Report unresolved version bump
if: >
steps.current_pr.outputs.exists == 'true' &&
steps.mergeability.outputs.mergeable != 'MERGEABLE'
run: |
echo "Version bump PR #${{ steps.current_pr.outputs.number }} could not be merged automatically."
echo "Leaving the PR open for manual resolution."
- name: Nothing to do
if: >
steps.state.outputs.new_release == 'false' &&
steps.current_pr.outputs.exists == 'false'
run: |
echo "Stable already matches the latest upstream release."
echo "There is no pending version bump PR."
echo "Nothing to do."