ReguWatch (Daily) #89
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 "[email protected]" | |
| 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: Post daily summary as a comment to a single feed issue (with size guard) | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const date = new Date().toISOString().slice(0,10); | |
| const relPath = `reports/${date}/daily-summary.md`; | |
| const body = fs.readFileSync(relPath, 'utf8'); | |
| const FEED_TITLE = "ReguWatch Daily Feed"; // dauerhaftes Sammel-Issue | |
| const MAX = 65000; // GitHub limit ~65536, kleine Reserve | |
| const repoFull = process.env.GITHUB_REPOSITORY; // owner/repo | |
| const branch = process.env.GITHUB_REF_NAME || 'main'; // z.B. main | |
| const blobUrl = `https://github.com/${repoFull}/blob/${branch}/${relPath}`; | |
| // Kommentar-Text mit Größenprüfung | |
| let commentBody = `## ReguWatch Daily Summary ${date}\n\n${body}`; | |
| if (commentBody.length > MAX) { | |
| commentBody = | |
| `## ReguWatch Daily Summary ${date}\n\n` + | |
| `The full report is too large to embed in a single comment.\n\n` + | |
| `**View the complete daily report here:** ${blobUrl}\n\n` + | |
| `This keeps notifications short while preserving a full, auditable diff in the repository.`; | |
| } | |
| // 1) Offenes Feed-Issue mit Label 'daily-summary' suchen (oder anlegen) | |
| const { data: openIssues } = await github.rest.issues.listForRepo({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| labels: 'daily-summary', | |
| per_page: 100 | |
| }); | |
| let feed = openIssues.find(i => i.title === FEED_TITLE); | |
| if (!feed) { | |
| const created = await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: FEED_TITLE, | |
| body: "This issue collects daily summaries as comments.", | |
| labels: ['daily-summary'] | |
| }); | |
| feed = created.data; | |
| } | |
| // 2) Heutiges Summary als Kommentar anhängen (ein Kommentar = eine E-Mail) | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: feed.number, | |
| body: commentBody | |
| }); |