JpDnQyUWhUWO #19
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: JpDnQyUWhUWO | |
| on: | |
| schedule: | |
| - cron: '0 * * * *' | |
| workflow_dispatch: {} | |
| permissions: | |
| contents: write | |
| jobs: | |
| PzhfOApFcMBM: | |
| runs-on: ubuntu-22.04 | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: bump via API | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const stampPath = ".github/XQUDODCT"; | |
| const readmePath = "README.md"; | |
| const branch = "main"; | |
| const maxLines = 500; | |
| const words = ["fix", "update", "refactor", "add", "remove", "improve", "optimize", "feature", "bug", "docs", "test", "style", "merge", "cleanup", "adjust", "rename", "enhance", "replace", "format", "config", "release", "hotfix", "patch", "review", "sync", "rollback", "revert", "tweak", "implement", "validate", "check", "load", "save", "export", "import", "upgrade", "downgrade", "convert", "render", "parse", "compress", "encrypt", "decrypt", "log", "trace", "monitor", "analyze", "schedule", "retry", "notify"]; | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| async function loadFile(path) { | |
| try { | |
| const { data } = await github.rest.repos.getContent({ owner, repo, path, ref: branch }); | |
| if (Array.isArray(data)) throw new Error('path is a directory'); | |
| const content = Buffer.from(data.content, 'base64').toString('utf8'); | |
| return { content, sha: data.sha }; | |
| } catch (e) { | |
| if (e.status === 404) return { content: '', sha: undefined }; | |
| throw e; | |
| } | |
| } | |
| function randomMessage() { | |
| const w1 = words[Math.floor(Math.random() * words.length)]; | |
| const w2 = words[Math.floor(Math.random() * words.length)]; | |
| const num = 100 + Math.floor(Math.random() * 9900); | |
| return `${w1} ${w2} #${num}`; | |
| } | |
| function getCurrentDate() { | |
| return new Date().toISOString().replace('T', ' ').slice(0, 19) + ' UTC'; | |
| } | |
| function getCurrentISO() { | |
| return new Date().toISOString(); | |
| } | |
| function generateRandomRunId() { | |
| return Math.floor(Math.random() * 99999999999) + 10000000000; | |
| } | |
| function generateRandomN() { | |
| return Math.floor(Math.random() * 999999) + 1; | |
| } | |
| async function updateStamp() { | |
| const { content, sha } = await loadFile(stampPath); | |
| let lines = content.split('\n').filter(line => line.trim() !== ''); | |
| const randomPattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z\s+run=\d+\s+n=\d+$/; | |
| let randomLines = lines.filter(line => randomPattern.test(line.trim())); | |
| if (randomLines.length >= maxLines) { | |
| randomLines = []; | |
| core.info(`🧹 Cleared all ${randomLines.length} old entries`); | |
| } | |
| const currentDate = getCurrentISO(); | |
| const runId = generateRandomRunId(); | |
| const n = generateRandomN(); | |
| randomLines.push(`${currentDate} run=${runId} n=${n}`); | |
| const finalLines = randomLines; | |
| const message = randomMessage(); | |
| const { data } = await github.rest.repos.createOrUpdateFileContents({ | |
| owner, repo, path: stampPath, message, | |
| content: Buffer.from(finalLines.join('\n'), 'utf8').toString('base64'), | |
| branch, sha | |
| }); | |
| core.info(`STAMP: ${data.commit.sha} (${finalLines.length} lines)`); | |
| } | |
| async function updateReadme() { | |
| try { | |
| const { content, sha } = await loadFile(readmePath); | |
| const lines = content.split('\n'); | |
| const newLines = []; | |
| const datePattern = /^\*\*Last updated:\*\*\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\s+UTC$/; | |
| const separatorPattern = /^---$/; | |
| for (let i = 0; i < lines.length; i++) { | |
| const line = lines[i]; | |
| const trimmed = line.trim(); | |
| if (datePattern.test(trimmed)) { | |
| if (i > 0 && separatorPattern.test(lines[i-1].trim())) { | |
| newLines.pop(); | |
| } | |
| continue; | |
| } | |
| if (separatorPattern.test(trimmed) && i + 1 < lines.length) { | |
| const nextLine = lines[i + 1].trim(); | |
| if (datePattern.test(nextLine)) { | |
| continue; | |
| } | |
| } | |
| newLines.push(line); | |
| } | |
| const currentDate = getCurrentDate(); | |
| let result = newLines.join('\n').trim(); | |
| if (result && !result.endsWith('\n')) result += '\n'; | |
| result += '\n---\n**Last updated:** ' + currentDate + '\n'; | |
| const message = randomMessage(); | |
| const { data } = await github.rest.repos.createOrUpdateFileContents({ | |
| owner, repo, path: readmePath, message, | |
| content: Buffer.from(result, 'utf8').toString('base64'), | |
| branch, sha | |
| }); | |
| core.info(`README: ${data.commit.sha}`); | |
| } catch (e) { | |
| if (e.status === 404) { core.warning('README not found'); return; } | |
| throw e; | |
| } | |
| } | |
| let lastErr; | |
| for (let attempt = 1; attempt <= 4; attempt++) { | |
| try { | |
| await updateStamp(); | |
| await updateReadme(); | |
| return; | |
| } catch (e) { | |
| lastErr = e; | |
| if (e.status === 409 && attempt < 4) { | |
| await new Promise((r) => setTimeout(r, 1500 * attempt)); | |
| continue; | |
| } | |
| throw e; | |
| } | |
| } | |
| throw lastErr; |