Sync #13924
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Sync | |
| on: | |
| workflow_dispatch: {} | |
| schedule: | |
| - cron: "*/30 * * * *" # Runs every 30 minutes | |
| jobs: | |
| sync: | |
| name: Sync With Upstream | |
| runs-on: warp-ubuntu-latest-x64-4x | |
| steps: | |
| - uses: actions/create-github-app-token@v1 | |
| id: app-token | |
| with: | |
| app-id: ${{ secrets.APP_ID }} | |
| private-key: ${{ secrets.APP_PRIVATE_KEY }} | |
| - name: Checkout with GitHub App Token | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ steps.app-token.outputs.token }} | |
| - name: Get GitHub App User ID | |
| id: get-user-id | |
| run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT" | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| - run: | | |
| git config --global user.name '${{ steps.app-token.outputs.app-slug }}[bot]' | |
| git config --global user.email '${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com' | |
| - name: Sync with upstream repository | |
| run: | | |
| # Get the upstream repository URL from GitHub API | |
| REPO_NAME="${GITHUB_REPOSITORY}" | |
| UPSTREAM_INFO=$(gh api repos/$REPO_NAME | jq -r '.parent.clone_url // empty') | |
| if [ -z "$UPSTREAM_INFO" ]; then | |
| echo "This doesn't appear to be a fork or the API couldn't retrieve the parent repository" | |
| exit 1 | |
| fi | |
| echo "Upstream repository: $UPSTREAM_INFO" | |
| # Check if upstream remote exists, add it if it doesn't | |
| if ! git remote | grep -q "^upstream$"; then | |
| git remote add upstream $UPSTREAM_INFO | |
| else | |
| git remote set-url upstream $UPSTREAM_INFO | |
| fi | |
| # Fetch from upstream and origin | |
| git fetch upstream | |
| git fetch origin | |
| # Store current branch (typically main) | |
| CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) | |
| echo "Current branch: $CURRENT_BRANCH" | |
| # Function to sync a branch with conflict resolution | |
| sync_branch() { | |
| local branch_name=$1 | |
| echo "Syncing branch: $branch_name" | |
| # Save any workflow files we might have modified | |
| mkdir -p /tmp/workflow-backup | |
| if [ -d ".github/workflows" ]; then | |
| cp -r .github/workflows/* /tmp/workflow-backup/ || true | |
| fi | |
| # Get just the commit message from upstream | |
| UPSTREAM_COMMIT_MSG=$(git log -1 --pretty=format:"%s" upstream/$branch_name) | |
| # Check if we need to merge (are we behind upstream?) | |
| if git merge-base --is-ancestor HEAD upstream/$branch_name; then | |
| echo "Already up to date with upstream/$branch_name" | |
| else | |
| # We're behind upstream, proceed with merge | |
| # Try standard merge first with the upstream commit message | |
| if git merge upstream/$branch_name -m "$UPSTREAM_COMMIT_MSG"; then | |
| echo "Standard merge successful" | |
| else | |
| # If standard merge fails, abort it | |
| git merge --abort | |
| # Try again with strategy to prefer upstream changes | |
| echo "Standard merge failed. Using 'theirs' strategy to resolve conflicts automatically." | |
| git merge -X theirs upstream/$branch_name -m "$UPSTREAM_COMMIT_MSG" | |
| fi | |
| fi | |
| # Restore our workflow files regardless of merge strategy | |
| if [ -d "/tmp/workflow-backup" ] && [ -n "$(ls -A /tmp/workflow-backup)" ]; then | |
| mkdir -p .github/workflows | |
| cp -r /tmp/workflow-backup/* .github/workflows/ | |
| git add .github/workflows/ | |
| if git diff --staged --quiet; then | |
| echo "No changes to workflow files" | |
| else | |
| git commit -m "Preserve custom workflow files after sync" | |
| fi | |
| fi | |
| # Push changes to origin | |
| git push origin $branch_name | |
| } | |
| # ----- Sync current branch ----- | |
| sync_branch "$CURRENT_BRANCH" | |
| echo "Sync complete" | |
| env: | |
| GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| on-failure: | |
| runs-on: warp-ubuntu-latest-x64-4x | |
| needs: sync | |
| if: ${{ always() && needs.sync.result != 'success' }} | |
| steps: | |
| - uses: ravsamhq/notify-slack-action@v2 | |
| with: | |
| status: "failure" | |
| env: | |
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} |