better CI workflow for reviewing games#4007
Conversation
Updated title and description for the Casino game.
Automated pr 1779221690075
Updated README to reflect new casino gambling game features and mechanics.
Add a note about gambling and a formatting todo.
Added a new Shop feature to buy items with earned credits and clarified AI usage in backend.
Updated game description and controls information, added share link, and improved formatting.
Added game location and share link for GamblingCasino.
Add files via upload
…ch-3 Revert "Add files via upload"
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
this pr introduces a fully automated node.js backend to triage, track, and manage game submissions, replacing the old manual google sheets tracking and fragile one-off yaml scripts. everything described here runs automatically on github actions, nobody needs to press anything to trigger any of it.
the main focus is the massive overhaul to the ci workflow. here is exactly how the new pipeline works from start to finish:
1. the core workflow (
auto-triage.mjs)the workflow triggers on:
opened,synchronize,assigned,unassigned,edited,reopened,ready_for_review,pull_request_review: submitted,issue_comment: created.when a game submission pr is opened or updated, the
auto-triagebot immediately kicks in:@title,@author,@tags,@addedOn, etc.), ensures files are placed correctly ingames/, checks file size, and runs the python plagiarism checker against the existing game library.<details>sections for each check category that passed or failed: "Files & Directories", "PR Description", "Game Metadata Header", and "Code & Assets".ready_for_reviewevent to kick off triage when the author marks it ready.auto-triage.ymlhas aconcurrencyblock that cancels older in-progress triage runs if a new event fires for the same pr, so rapid-fire commits don't produce duplicate bot comments.see it in action: SSoggyTacoMan#15 (comment)
(to see the "play in sprig editor" in action, replace the sprig link before the / with https://sprig-teal.vercel.app/ )
2. all submission labels & their meanings (
review-utils.mjs)the entire system is state-driven by github labels. all label definitions, colors, and descriptions are centralized in
review-utils.mjsand automatically created on the repo if they don't exist yet (viaensureReviewLabels). here is what each label means and when it gets applied:Submission: added to any pr that modifies a file insidegames/. this is the core gate — the sync script and stale tracker only look at prs with this label.Verified: automated checks passed. the pr is structurally valid.Failed: one or more automated checks failed (wrong directory, missing metadata, file too large, etc.). the bot's comment will list exactly what failed.Ready for Playtest: checks passed and the game is waiting for a human reviewer to actually download and play it.Claimed: a reviewer assigned themselves to the pr (via the github assignees ui). they are actively testing it. if there is 0 activity for 3 days, the bot fully unassigns them and removes this label so someone else can pick it up.Needs Author: automated checks failed, OR a human reviewer requested changes. the pr author needs to push fixes. has a 14-day auto-close timer.Ready for Maintainer: a reviewer approved the pr. a maintainer now needs to do a final check and merge it. if it sits untouched for 7 days, the bot drops a @-mention reminder to the maintainers listed in.github/review-roles.json.Stale: no meaningful activity for a set number of days (7 days inNeeds Author, 30 days for any open pr with no activity at all).Plagiarism Risk: the similarity checker found high overlap (above threshold) with an existing game in the library.AI Concern: a reviewer flagged the game for potential undisclosed ai usage.Potential Duplicate: the pr author already has another open submission. the bot also drops a comment explaining they can edit their existing pr instead of opening a new one.Keep Open: a manual override label. if any pr has this label, the stale tracker completely skips it and will never auto-close it, useful for known-good PRs that are just waiting on something external.3. full state lifecycle
here is the exact path a submission takes through the pipeline from open to close:
Verified+Ready for Playtest. if fail:Failed+Needs Author.Claimed.Needs Author. 14-day clock starts.Ready for Playtestagain. state is reset, 14-day clock restarts.Ready for Maintainer. bot skips this transition if the reviewer is the same person as the pr author (self-review bypass).Ready for Maintainer. the bot previously stomped this back toReady for Playtest, now fixed.Merged.4. edge cases & automated tracking (
stale-review-queue.mjs,duplicate-submission-labeler.yml)cron jobs and secondary workflows handle all the edge cases that the main bot can't cover inline:
the 14-day clock: if a pr is in
Needs Author(failed checks or changes requested) with no activity:Keep Openescape hatch: any maintainer can add theKeep Openlabel to permanently exempt a pr from this timer.auto-reopen on author comment: if the pr is closed (by the 14-day timer or manually) and the original author leaves any comment on it, the bot instantly reopens the pr and bumps it back to
Ready for Playtest. no maintainer action needed.forgotten maintainer approvals: if a pr sits in
Ready for Maintainerfor 7 days with no activity, the bot posts a reminder comment that @-mentions the maintainers by name (pulled from.github/review-roles.json).abandoned claims: if a reviewer assigns themselves (
Claimed) but there is 0 activity on the pr for 3 days, the bot fully unassigns them from the github ui (removing them from the assignees list, not just the label) and removesClaimedso someone else can pick it up. the 3-day timer is based on the pr'supdated_atfield so any activity (comments, commits, reviews) resets it.completely untouched submissions: if any open pr with
Submissionlabel has had 0 activity for 30 days, the bot flags it withStaleto get a reviewer's attention.persistent duplicates (
duplicate-submission-labeler.yml): if a user has more than one open submission at once, the newer pr gets flagged withPotential Duplicateand the bot drops a helpful comment explaining how to update their existing pr instead of opening a new one. if the user closes the extra pr, the workflow automatically removes the label from their surviving pr.ghost prs on project board: the sync script fetches the 100 most recently updated prs (including closed/merged) so prs that get merged don't get stuck in their old state on the project board forever.
synchronize stomps approval: when an author pushes a fix commit after a reviewer has approved, the bot previously reset the state back to
Ready for Playtest. now fixed,synchronizeevents check for an existing valid approval and preserveReady for Maintainerif one is found.self-review bypass: the review handler checks that the reviewer is not the same person as the pr author before accepting a
CHANGES_REQUESTEDorAPPROVEDreview as a state transition.stale marker collision: both the 7-day stale warning and the auto-close comment now use unique date-stamped html markers (e.g.
<!-- sprig-stale-reminder-2026-06-01 -->) so a pr that recovers and re-enters the stale state will always get a fresh comment instead of silently doing nothing because the old marker is still in the thread.plagiarism risk auto-close:
Plagiarism Riskprs now follow the same 14-day auto-close as all other stale submissions. the previous exception that kept them open forever has been removed.fix commits penalized: the "only new files" check now only flags files added outside of
games/. modifications to an existing file insidegames/are allowed, so authors pushing fixes to address requested changes aren't penalized.deleted/unreadable file crash: fixed a null-pointer crash in
validateSingleGameFilewhere trying to checkcontent.lengthon a null file (e.g. a deleted game file) would crash the entire action. now it safely logs a failed check and continues.sync script rate limit: removed a redundant
GET /issues/{number}api call per pr in the board sync script by using the labels already present on the pr object from the pulls list. this roughly halves the api call count per sync run.5. reviewer roles (
review-roles.json)added
.github/review-roles.jsonto define which github usernames are maintainers and which are triagers:{ "maintainers": ["lachlanjc", "maxwofford", "sampoder"], "triagers": [] }this file is read by
stale-review-queue.mjsto @-mention the right people in the "7-day waiting on maintainer" reminder comment. update this file to add or remove team members, no code changes needed.6. github projects integration (
sync-github-project.mjs)as a replacement for the manual google sheets tracking, the state logic is hooked up to a native github project board. (this is optional and can be skipped if the team prefers a different setup.)
PROJECT_PAT(a personal access token withprojectscope) andGITHUB_PROJECT_URL(the url of the project board to sync to).setup-project.mjsis included to automatically create all the required custom fields on any new github project board from scratch.7. bug fixes
src/integrations/generate-metadata.ts): one malformed game file used to crash the entire site build. it now catches errors per-game, logs them, and skips the bad file instead of failing the whole build. also made the space after the colon in metadata headers optional (@description:textand@description: textboth parse correctly now).plagiarism_check.py): fixed regex patterns that were incorrectly matching or failing on certain game files.node:fsinstead of the barefsimport.editor.tsx,editor.astro,editor.module.css, andnavbar-editor.tsx.8. what maintainers need to do after merging
ensureReviewLabelswill automatically create all required labels onhackclub/sprigthe first time a workflow runs.PROJECT_PAT(project-scoped personal access token) andGITHUB_PROJECT_URLas repository secrets, then runnode setup-project.mjsonce to scaffold the board columns.4. review roles: update
.github/review-roles.jsonto reflect the actual maintainer and triager github usernames.(I just put active ones on there if it's not accurate just edit it)
also trisgers will have to get added to the GitHub repo/team with the triage perms (if possible) so they can close (not merge), add labels, request changes etc.