From 3ed483127d0aee9d63c91efd5d068a8b0cd434bf Mon Sep 17 00:00:00 2001 From: chaodu-agent <274062505+chaodu-agent@users.noreply.github.com> Date: Fri, 23 Oct 2026 01:53:49 +0000 Subject: [PATCH] ci(pre-beta): gate scheduled builds on main HEAD SHA, not a 70-min window GitHub delivers the hourly schedule every ~4-5h, so the 'commit in the last ~70min' gate skipped most merges. The last full pre-beta build was 99c11ec (2026-10-03); #1562, #1564, #1568 and #1569 never reached pre-beta-*, which also kept downstream openab-pty images on Node 22.23.3. Build when main HEAD differs from the head SHA of the last successful run that tagged every agent. --- .github/workflows/pre-beta-build.yml | 49 +++++++++++++++++++++------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/.github/workflows/pre-beta-build.yml b/.github/workflows/pre-beta-build.yml index 529b06a7d..02d1f7e99 100644 --- a/.github/workflows/pre-beta-build.yml +++ b/.github/workflows/pre-beta-build.yml @@ -21,10 +21,11 @@ jobs: runs-on: ubuntu-latest permissions: contents: read + actions: read outputs: should_run: ${{ steps.check.outputs.should_run }} steps: - - name: Skip scheduled run when no recent commits + - name: Skip scheduled run when main is already built uses: actions/github-script@v7 id: check with: @@ -34,17 +35,43 @@ jobs: core.setOutput('should_run', 'true'); return; } - // Scheduled run: build only if main got a commit in the last ~70min. - const since = new Date(Date.now() - 70 * 60 * 1000).toISOString(); - const { data: commits } = await github.rest.repos.listCommits({ - owner: context.repo.owner, - repo: context.repo.repo, - sha: context.payload.repository?.default_branch || 'main', - since, - per_page: 1, + // Scheduled run: build unless the current main HEAD was already + // published by a full pre-beta build. Compare SHAs, not a time + // window. GitHub delivers the hourly schedule hours late, so a + // "commit in the last ~70min" window skipped most merges and left + // pre-beta-* stale (openab#1567). + const { owner, repo } = context.repo; + const branch = context.payload.repository?.default_branch || 'main'; + const { data: head } = await github.rest.repos.getBranch({ owner, repo, branch }); + const headSha = head.commit.sha; + const agentCount = process.env.ALL_AGENTS.split(',').length; + + const { data: runs } = await github.rest.actions.listWorkflowRuns({ + owner, repo, + workflow_id: 'pre-beta-build.yml', + branch, + status: 'success', + per_page: 100, }); - const run = commits.length > 0; - core.info(`commits since ${since}: ${commits.length} -> should_run=${run}`); + let lastBuilt = null; + for (const run of runs.workflow_runs) { + if (run.id === context.runId) continue; + const jobs = await github.paginate( + github.rest.actions.listJobsForWorkflowRun, + { owner, repo, run_id: run.id, per_page: 100 }, + ); + // A full build tags every agent. Skipped-gate runs and partial + // manual builds (agents subset) do not count. + const tagged = jobs.filter( + (j) => j.name.startsWith('tag') && j.conclusion === 'success', + ).length; + if (tagged >= agentCount) { + lastBuilt = run.head_sha; + break; + } + } + const run = lastBuilt !== headSha; + core.info(`main HEAD ${headSha}, last full pre-beta build ${lastBuilt ?? 'none found'} -> should_run=${run}`); core.setOutput('should_run', run ? 'true' : 'false'); matrix: