From e0e4edea9d751d36e9f41230ba1abdc43b6bf3f7 Mon Sep 17 00:00:00 2001 From: Doglightning <170844007+Doglightning@users.noreply.github.com> Date: Thu, 16 Oct 2025 15:41:31 +0000 Subject: [PATCH] refactor(monorepo): move workflow to correct location (#253) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Enhance Auto-Deploy Workflow with Better Logging and Status Tracking ## Overview This PR enhances the auto-deploy GitHub workflow by improving status tracking and adding detailed logging for deployment processes. It provides better visibility into deployment progress and failures. ## Brief Changelog - Added explicit GitHub token to workflow actions - Improved JSON handling for input parameters using `toJson` - Enhanced status tracking with per-project state monitoring - Added detailed logging for deployment progress and completion status - Implemented tracking of last reported terminal state per project to avoid duplicate logs - Added visual indicators (✅/❌) for successful and failed deployments - Removed duplicate workflow file from incorrect location ## Testing and Verifying This change can be verified by running the auto-deploy workflow and observing the improved logs in the GitHub Actions console, which now show clear progress indicators, success/failure counts, and detailed per-project status updates. --- .github/workflows/auto_deploy.yml | 67 +++++++++++++++++++++++++++---- workflows/auto_deploy.yml | 67 ------------------------------- 2 files changed, 59 insertions(+), 75 deletions(-) delete mode 100644 workflows/auto_deploy.yml diff --git a/.github/workflows/auto_deploy.yml b/.github/workflows/auto_deploy.yml index a8dafe05..71ea7981 100644 --- a/.github/workflows/auto_deploy.yml +++ b/.github/workflows/auto_deploy.yml @@ -21,26 +21,39 @@ jobs: - name: Emit repository_dispatch to App uses: actions/github-script@v7 with: + github-token: ${{ secrets.GITHUB_TOKEN }} script: | await github.rest.repos.createDispatchEvent({ owner: context.repo.owner, repo: context.repo.repo, event_type: "auto-deploy", - client_payload: { base: inputs.base, head: inputs.head } + client_payload: { + base: ${{ toJson(inputs.base) }}, + head: ${{ toJson(inputs.head) }} + } }) + - name: Wait for World Forge status uses: actions/github-script@v7 with: + github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const owner = context.repo.owner, repo = context.repo.repo, ref = inputs.head; + const owner = context.repo.owner; + const repo = context.repo.repo; + const ref = ${{ toJson(inputs.head) }}; const prefix = "world-forge/auto-deploy"; const initDeadline = Date.now() + 2*60*1000; const hardDeadline = Date.now() + 45*60*1000; const sleep = (ms) => new Promise(r => setTimeout(r, ms)); + async function allStatuses() { const { data } = await github.rest.repos.getCombinedStatusForRef({ owner, repo, ref }); return data.statuses || []; } + + // Track last reported terminal state per project to avoid duplicate logs + const lastReportedBySlug = {}; + let expected = null; while (Date.now() < initDeadline) { const statuses = await allStatuses(); @@ -51,17 +64,55 @@ jobs: const n = parseInt(a.description || "0", 10); if (!Number.isNaN(n) && n > 0) { expected = n; break; } } - if (expected) break; + if (expected) { core.info(`${expected} deploy${expected===1?'':'s'} are in progress`); break; } await sleep(5000); } if (!expected) { core.setFailed("Auto-deploy did not publish expected deployment count."); return; } + + let prevCompleted = -1, prevSuccess = -1, prevFailed = -1; while (Date.now() < hardDeadline) { const statuses = await allStatuses(); - const perProject = statuses.filter(s => s.context.startsWith(prefix + "/")); - const success = perProject.filter(s => s.state === "success").length; - const failed = perProject.filter(s => s.state === "failure" || s.state === "error").length; - if (success + failed >= expected) { if (failed > 0) core.setFailed(`Deploy failures: ${failed}/${expected}`); return; } + const perProject = statuses.filter(s => s.context && s.context.startsWith(prefix + "/")); + + // Build latest status per project slug (use updated_at/created_at to pick most recent) + const latestBySlug = {}; + for (const s of perProject) { + const slug = s.context.slice(prefix.length + 1); + const time = new Date(s.updated_at || s.created_at || 0).getTime(); + const prev = latestBySlug[slug]; + if (!prev || time > prev._time) { + latestBySlug[slug] = { ...s, _time: time, _slug: slug }; + } + } + + const latestList = Object.values(latestBySlug); + const success = latestList.filter(s => s.state === "success").length; + const failed = latestList.filter(s => s.state === "failure" || s.state === "error").length; + const completed = success + failed; + + if (completed !== prevCompleted || success !== prevSuccess || failed !== prevFailed) { + core.info(`completed=${completed}/${expected} success=${success} failed=${failed}`); + prevCompleted = completed; prevSuccess = success; prevFailed = failed; + } + + // Emit per-project updates when terminal state changes + for (const s of latestList) { + const slug = s._slug; + const state = s.state; + const prev = lastReportedBySlug[slug]; + if ((state === "failure" || state === "error") && prev !== state) { + const reason = s.description || "No details provided."; + core.info(`❌Project ${slug} failed: ${reason}`); + core.info(" "); + lastReportedBySlug[slug] = state; + } else if (state === "success" && prev !== state) { + core.info(`✅Project ${slug} passed!`); + core.info(" "); + lastReportedBySlug[slug] = state; + } + } + + if (completed >= expected) { if (failed > 0) core.setFailed(`Deploy failures: ${failed}/${expected}`); return; } await sleep(10000); } core.setFailed("Timed out waiting for auto-deploy results."); - \ No newline at end of file diff --git a/workflows/auto_deploy.yml b/workflows/auto_deploy.yml deleted file mode 100644 index a8dafe05..00000000 --- a/workflows/auto_deploy.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: Auto Deploy Preview - -on: - workflow_call: - inputs: - base: - type: string - required: true - head: - type: string - required: true - -permissions: - contents: write - statuses: read - -jobs: - signal: - runs-on: ubuntu-latest - steps: - - name: Emit repository_dispatch to App - uses: actions/github-script@v7 - with: - script: | - await github.rest.repos.createDispatchEvent({ - owner: context.repo.owner, - repo: context.repo.repo, - event_type: "auto-deploy", - client_payload: { base: inputs.base, head: inputs.head } - }) - - name: Wait for World Forge status - uses: actions/github-script@v7 - with: - script: | - const owner = context.repo.owner, repo = context.repo.repo, ref = inputs.head; - const prefix = "world-forge/auto-deploy"; - const initDeadline = Date.now() + 2*60*1000; - const hardDeadline = Date.now() + 45*60*1000; - const sleep = (ms) => new Promise(r => setTimeout(r, ms)); - async function allStatuses() { - const { data } = await github.rest.repos.getCombinedStatusForRef({ owner, repo, ref }); - return data.statuses || []; - } - let expected = null; - while (Date.now() < initDeadline) { - const statuses = await allStatuses(); - const aggFail = statuses.find(s => s.context === prefix && (s.state === "failure" || s.state === "error")); - if (aggFail) { core.setFailed(aggFail.description || "Auto-deploy aggregate failed"); return; } - const aggs = statuses.filter(s => s.context === prefix && s.state === "pending"); - for (const a of aggs) { - const n = parseInt(a.description || "0", 10); - if (!Number.isNaN(n) && n > 0) { expected = n; break; } - } - if (expected) break; - await sleep(5000); - } - if (!expected) { core.setFailed("Auto-deploy did not publish expected deployment count."); return; } - while (Date.now() < hardDeadline) { - const statuses = await allStatuses(); - const perProject = statuses.filter(s => s.context.startsWith(prefix + "/")); - const success = perProject.filter(s => s.state === "success").length; - const failed = perProject.filter(s => s.state === "failure" || s.state === "error").length; - if (success + failed >= expected) { if (failed > 0) core.setFailed(`Deploy failures: ${failed}/${expected}`); return; } - await sleep(10000); - } - core.setFailed("Timed out waiting for auto-deploy results."); - \ No newline at end of file