From 997fbeb1643642bba350a6b897f27ebaba85d133 Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Sat, 21 Feb 2026 15:49:03 -0500 Subject: [PATCH] ci: add daily upstream PR mirror workflow Problem: new upstream PRs required manual monitoring of stevearc/oil.nvim to discover. Solution: add a GitHub Actions workflow that runs daily at 08:00 UTC and creates issues in the fork for any upstream PRs opened in the last 24 hours. Skips dependabot PRs and deduplicates by title prefix. Issues are labeled upstream/pr for easy filtering. --- .github/workflows/mirror_upstream_prs.yml | 85 +++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 .github/workflows/mirror_upstream_prs.yml diff --git a/.github/workflows/mirror_upstream_prs.yml b/.github/workflows/mirror_upstream_prs.yml new file mode 100644 index 0000000..af9cdb0 --- /dev/null +++ b/.github/workflows/mirror_upstream_prs.yml @@ -0,0 +1,85 @@ +name: Mirror Upstream PRs +on: + schedule: + - cron: "0 8 * * *" + workflow_dispatch: + +permissions: + issues: write + +jobs: + mirror: + runs-on: ubuntu-latest + steps: + - name: Mirror new upstream PRs + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const upstream = { owner: 'stevearc', repo: 'oil.nvim' }; + const fork = { owner: 'barrettruth', repo: 'oil.nvim' }; + + const since = new Date(); + since.setDate(since.getDate() - 1); + const sinceISO = since.toISOString(); + + const { data: prs } = await github.rest.pulls.list({ + ...upstream, + state: 'open', + sort: 'created', + direction: 'desc', + per_page: 30, + }); + + const recentPRs = prs.filter(pr => { + if (new Date(pr.created_at) < since) return false; + if (pr.user.login === 'dependabot[bot]') return false; + if (pr.user.login === 'dependabot-preview[bot]') return false; + return true; + }); + + if (recentPRs.length === 0) { + console.log('No new upstream PRs in the last 24 hours.'); + return; + } + + const { data: existingIssues } = await github.rest.issues.listForRepo({ + ...fork, + state: 'all', + labels: 'upstream/pr', + per_page: 100, + }); + + const mirroredNumbers = new Set(); + for (const issue of existingIssues) { + const match = issue.title.match(/^upstream#(\d+)/); + if (match) mirroredNumbers.add(parseInt(match[1])); + } + + for (const pr of recentPRs) { + if (mirroredNumbers.has(pr.number)) { + console.log(`Skipping PR #${pr.number} — already mirrored.`); + continue; + } + + const labels = pr.labels.map(l => l.name).join(', ') || 'none'; + + await github.rest.issues.create({ + ...fork, + title: `upstream#${pr.number}: ${pr.title}`, + body: [ + `Mirrored from [stevearc/oil.nvim#${pr.number}](${pr.html_url}).`, + '', + `**Author:** @${pr.user.login}`, + `**Labels:** ${labels}`, + `**Created:** ${pr.created_at}`, + '', + '---', + '', + pr.body || '*No description provided.*', + ].join('\n'), + labels: ['upstream/pr'], + }); + + console.log(`Created issue for upstream PR #${pr.number}: ${pr.title}`); + }