ReguWatch (Daily) #21
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: ReguWatch (Daily) | |
| on: | |
| schedule: | |
| # 05:00 UTC ≈ 07:00 Berlin (Sommerzeit); im Winter ≈ 06:00 Berlin | |
| - cron: "0 5 * * *" | |
| workflow_dispatch: {} | |
| jobs: | |
| run: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| issues: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Build watchlist from Issues | |
| id: build | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const cfg = JSON.parse(fs.readFileSync('reguwatch.config.json','utf8')); | |
| const profile = cfg.profiles[cfg.profile] || {}; | |
| const maxMonitors = profile.max_monitors ?? 999999; | |
| const { owner, repo } = context.repo; | |
| const issues = await github.paginate(github.rest.issues.listForRepo, { | |
| owner, repo, state: 'open', labels: 'reguwatch', per_page: 100 | |
| }); | |
| const seen = new Set(); | |
| const items = []; | |
| for (const is of issues) { | |
| // ⬇️ NEW: never include daily-summary issues in the watchlist | |
| const labels = (is.labels || []).map(l => (l.name || l).toLowerCase()); | |
| const isDaily = labels.includes('daily-summary') || (is.title || '').startsWith('ReguWatch Daily Summary '); | |
| if (isDaily) continue; | |
| const body = is.body || ""; | |
| const nameMatch = body.match(/\*\*Short name\*\*[\s\S]*?\n\n([\s\S]*?)(?:\n\n|$)/i); | |
| const name = (nameMatch ? nameMatch[1].trim() : `Issue #${is.number}`) || `Issue #${is.number}`; | |
| const urlMatch = body.match(/https?:\/\/\S+/); | |
| const url = urlMatch ? urlMatch[0] : ''; | |
| if (!url) continue; | |
| if (seen.has(url)) continue; | |
| seen.add(url); | |
| items.push({ name, url, issue: is.number }); | |
| } | |
| items.sort((a,b)=>a.issue-b.issue); | |
| const limited = items.slice(0, maxMonitors); | |
| for (const d of ['snapshots','state','reports']) { | |
| if (!fs.existsSync(d)) fs.mkdirSync(d); | |
| } | |
| fs.writeFileSync('sites.json', JSON.stringify(limited, null, 2)); | |
| fs.writeFileSync('urls.txt', limited.map(i=>i.url).join('\n') + (limited.length?'\n':'')); | |
| core.setOutput('count', String(limited.length)); | |
| - name: Show watchlist summary | |
| run: | | |
| echo "Entries: ${{ steps.build.outputs.count }}" | |
| cat sites.json || true | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - run: pip install requests selectolax | |
| - name: Run daily check | |
| id: check | |
| run: python .github/scripts/check.py --daily | |
| - name: Commit snapshots, state & report | |
| run: | | |
| git config user.name "reguwatch-bot" | |
| git config user.email "actions@users.noreply.github.com" | |
| git add snapshots state reports last_diff.txt || true | |
| git commit -m "Daily: snapshots/state/report [skip ci]" || echo "No changes to commit" | |
| git push | |
| - name: Open/Update daily summary issue (then close) | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const date = new Date().toISOString().slice(0,10); | |
| const path = `reports/${date}/daily-summary.md`; | |
| const body = fs.readFileSync(path, 'utf8'); | |
| // 1) Offene Daily-Issues für heute suchen | |
| const { data: existingOpen } = await github.rest.issues.listForRepo({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| labels: 'daily-summary' | |
| }); | |
| for (const is of existingOpen) { | |
| if (is.title.includes(date)) { | |
| // aktualisieren + schließen | |
| await github.rest.issues.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: is.number, | |
| body, | |
| }); | |
| await github.rest.issues.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: is.number, | |
| state: 'closed' | |
| }); | |
| return; | |
| } | |
| } | |
| // 2) Falls es schon ein geschlossenes Daily von heute gibt: aktualisieren + geschlossen lassen | |
| const { data: existingClosed } = await github.rest.issues.listForRepo({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'closed', | |
| labels: 'daily-summary' | |
| }); | |
| for (const is of existingClosed) { | |
| if (is.title.includes(date)) { | |
| await github.rest.issues.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: is.number, | |
| body | |
| }); | |
| // geschlossen lassen | |
| return; | |
| } | |
| } | |
| // 3) Neues Daily-Issue erstellen (Mail wird verschickt) … und direkt schließen | |
| const created = await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: `ReguWatch Daily Summary ${date}`, | |
| body, | |
| labels: ['daily-summary'] | |
| }); | |
| await github.rest.issues.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: created.data.number, | |
| state: 'closed' | |
| }); |