From 1c2386c5333f9caf20aea3ede2ef6621c880e8fb Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 12 Aug 2026 23:15:21 +0000 Subject: [PATCH 1/3] ci: stop pretending the workflow can switch Pages on enablement: true cannot work with a workflow token: creating a Pages site needs administration:write, which GITHUB_TOKEN cannot be granted, so the step failed with "Resource not accessible by integration" rather than enabling anything. The action's own maintainers changed the default away from attempting it for the same reason. Removed, and the one-time human step it was trying to avoid is written down where the next person will look for it. Co-authored-by: BruceMoseti --- .github/workflows/pages.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 605e976..320fde5 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -56,11 +56,13 @@ jobs: steps: - uses: actions/checkout@v4 - # enablement turns Pages on for the repository if it is off, so the - # published link works without anyone visiting the settings page first. + # Publishing needs Pages switched on once, by hand, with Source set to + # "GitHub Actions" in Settings -> Pages. It cannot be automated from here: + # creating a Pages site needs administration:write, which a workflow token + # cannot be granted, so configure-pages fails with "Resource not + # accessible by integration" until the site exists. After that this step + # just reads the existing configuration on every run. - uses: actions/configure-pages@v5 - with: - enablement: true - uses: actions/upload-pages-artifact@v3 with: From 44c8e03995827463a53b2ac1e975d59c2c1e83ce Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 12 Aug 2026 23:26:11 +0000 Subject: [PATCH 2/3] test(web): give the random-play game room to finish The harness aims at a random legal ball, so it plays badly and its games run long in the tail: one reached 66 shots and was still making progress when the 40-turn cap stopped it, failing a test that had nothing wrong with it. Games observed since: 5, 6, 23, 29, 31, 33, 37 shots, all concluding. The cap is there to catch a table that has stopped progressing, not to express how long a game should take, so it moves to 120 and the failure now says how many shots were played and what phase the game was stuck in. selfplay.mjs already allows 250 for the same reason. Co-authored-by: BruceMoseti --- web/test/browser.mjs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/web/test/browser.mjs b/web/test/browser.mjs index b8e7730..2c6565f 100644 --- a/web/test/browser.mjs +++ b/web/test/browser.mjs @@ -32,7 +32,13 @@ function parseArgs() { }; return { url: get("--url", "http://localhost:8123/index.html"), - shots: Number(get("--shots", 40)), + // One action of the harness: a placement, or a shot of its own. The bot's + // replies happen inside a single wait and do not count. The harness aims at + // a random legal ball on purpose, so it plays badly and its games run long + // in the tail — one here needed 40 and was still going. The cap is only + // here to catch a table that has genuinely stopped making progress, so it + // sits well above that rather than close to the average. + shots: Number(get("--shots", 120)), games: Number(get("--games", 1)), screenshot: get("--screenshot", null), verbose: args.includes("--verbose"), @@ -128,7 +134,12 @@ async function main() { `${result.fouls} fouls, ` + (result.finished ? `winner ${result.winner}` : "shot limit reached") ); - if (!result.finished) throw new Error("game did not reach a conclusion"); + if (!result.finished) { + throw new Error( + `game did not reach a conclusion: ${result.shots} shots played in ` + + `${shotLimit} turns of the harness, phase "${result.phase}"` + ); + } if (result.botShots === 0) throw new Error("the bot never took a shot"); } if (screenshot) await page.screenshot({ path: screenshot, fullPage: true }); @@ -223,6 +234,7 @@ async function playGame(page, shotLimit, verbose = false) { potted: history.reduce((a, h) => a + h.potted.filter((n) => n !== 0).length, 0), fouls: history.filter((h) => h.foul).length, finished: final.phase === "over", + phase: final.phase, winner: final.winner, }; } From 017c5d60fcf9ea9308fb365543f207e18a78d41e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 12 Aug 2026 23:53:13 +0000 Subject: [PATCH 3/3] ci: say what is missing instead of failing on a missing setting The deploy job has gone red on every push to main, with "Resource not accessible by integration" from configure-pages. That reads like a broken workflow. It is not: Pages has never been switched on for the repository, and no workflow token can switch it on. The precondition is now checked and named. If the site does not exist the job ends with a warning saying which setting to set, and publishes nothing rather than failing at it. Once the setting is set, every step runs as before. Co-authored-by: BruceMoseti --- .github/workflows/pages.yml | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 320fde5..521b519 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -59,14 +59,30 @@ jobs: # Publishing needs Pages switched on once, by hand, with Source set to # "GitHub Actions" in Settings -> Pages. It cannot be automated from here: # creating a Pages site needs administration:write, which a workflow token - # cannot be granted, so configure-pages fails with "Resource not - # accessible by integration" until the site exists. After that this step - # just reads the existing configuration on every run. - - uses: actions/configure-pages@v5 + # cannot be granted, and the REST call is refused. Left to itself + # configure-pages reports that as "Resource not accessible by + # integration", which reads like a broken workflow rather than a setting + # nobody has set, so the precondition is checked and named instead. + - id: site + name: Check that Pages is switched on + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + if gh api "repos/$GITHUB_REPOSITORY/pages" >/dev/null 2>&1; then + echo "exists=true" >> "$GITHUB_OUTPUT" + else + echo "exists=false" >> "$GITHUB_OUTPUT" + echo "::warning title=Nothing was published::GitHub Pages is not enabled for this repository. Set Settings -> Pages -> Source to \"GitHub Actions\", then re-run this workflow. Creating the site needs administration:write, which no workflow token can hold." + fi + + - if: steps.site.outputs.exists == 'true' + uses: actions/configure-pages@v5 - - uses: actions/upload-pages-artifact@v3 + - if: steps.site.outputs.exists == 'true' + uses: actions/upload-pages-artifact@v3 with: path: web - id: deployment + if: steps.site.outputs.exists == 'true' uses: actions/deploy-pages@v4