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}`); }