Sync Fork With Upstream #2
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 Fork With Upstream | |
| on: | |
| schedule: | |
| - cron: '0 7 * * *' # Every day at 07:00 UTC | |
| workflow_dispatch: | |
| inputs: | |
| upstream_branch: | |
| description: 'Upstream branch to sync from (default: main)' | |
| required: false | |
| default: 'main' | |
| type: string | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| concurrency: | |
| group: sync-upstream-${{ github.repository }} | |
| cancel-in-progress: true | |
| jobs: | |
| sync: | |
| runs-on: ubuntu-latest | |
| env: | |
| UPSTREAM_REPO: https://github.com/garrytan/gstack.git | |
| UPSTREAM_BRANCH: ${{ inputs.upstream_branch || 'main' }} | |
| SYNC_BRANCH: sync/upstream-main | |
| BASE_BRANCH: ${{ github.event.repository.default_branch }} | |
| steps: | |
| - name: Checkout fork repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Configure Git identity | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| - name: Fetch upstream and push sync branch | |
| run: | | |
| git remote add upstream "$UPSTREAM_REPO" || git remote set-url upstream "$UPSTREAM_REPO" | |
| git fetch upstream "$UPSTREAM_BRANCH" | |
| git checkout -B "$SYNC_BRANCH" "upstream/$UPSTREAM_BRANCH" | |
| git push origin "$SYNC_BRANCH" --force | |
| - name: Create or update sync PR | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| const head = `${owner}:${process.env.SYNC_BRANCH}`; | |
| const base = process.env.BASE_BRANCH || 'main'; | |
| const labels = ['upstream-sync', 'dependencies']; | |
| const compare = await github.rest.repos.compareCommitsWithBasehead({ | |
| owner, | |
| repo, | |
| basehead: `${base}...${process.env.SYNC_BRANCH}` | |
| }); | |
| if (compare.data.total_commits === 0) { | |
| core.info(`No new commits to sync from upstream into ${base}.`); | |
| return; | |
| } | |
| const open = await github.rest.pulls.list({ | |
| owner, | |
| repo, | |
| state: 'open', | |
| head, | |
| base | |
| }); | |
| if (open.data.length > 0) { | |
| const pr = open.data[0]; | |
| await github.rest.issues.addLabels({ | |
| owner, | |
| repo, | |
| issue_number: pr.number, | |
| labels | |
| }); | |
| await github.rest.pulls.update({ | |
| owner, | |
| repo, | |
| pull_number: pr.number, | |
| title: `chore: sync upstream (${process.env.UPSTREAM_BRANCH} -> ${base})` | |
| }); | |
| core.info(`Sync PR already exists: #${pr.number}`); | |
| return; | |
| } | |
| const created = await github.rest.pulls.create({ | |
| owner, | |
| repo, | |
| title: `chore: sync upstream (${process.env.UPSTREAM_BRANCH} -> ${base})`, | |
| head: process.env.SYNC_BRANCH, | |
| base, | |
| body: [ | |
| 'Automated upstream sync PR.', | |
| '', | |
| `- Upstream: ${process.env.UPSTREAM_REPO}`, | |
| `- Upstream branch: ${process.env.UPSTREAM_BRANCH}`, | |
| `- Base branch: ${base}`, | |
| '', | |
| 'Please review and merge when checks pass.' | |
| ].join('\n') | |
| }); | |
| await github.rest.issues.addLabels({ | |
| owner, | |
| repo, | |
| issue_number: created.data.number, | |
| labels | |
| }); | |
| core.info(`Created PR #${created.data.number}: ${created.data.html_url}`); |