From c20c6560fd58d9d9aae2ac3dc752de2b2fc57c94 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Fri, 17 Jul 2026 06:23:44 -0700 Subject: [PATCH] fix(ci): job timeouts everywhere + retries on all network installs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reliability pass over every workflow: - timeout-minutes on all 21 jobs that lacked one (a hung job previously burned the 6-hour default runner budget) - ./.github/actions/retry wrapped around every network-fetching install that lacked it: pip installs (deploy-site, skills-index), npm ci (deploy-site website, upload_to_pypi web + ui-tui), uv sync (docker test deps). Deterministic build steps (npm run build) deliberately NOT retried — split into separate steps so a real build failure fails fast instead of retrying 3x. --- .github/workflows/ci.yml | 3 +++ .github/workflows/contributor-check.yml | 1 + .github/workflows/deploy-site.yml | 12 ++++++++--- .github/workflows/docker.yml | 13 ++++++------ .github/workflows/docs-site-checks.yml | 1 + .github/workflows/history-check.yml | 1 + .github/workflows/js-tests.yml | 2 ++ .github/workflows/skills-index-freshness.yml | 1 + .github/workflows/skills-index.yml | 6 +++++- .github/workflows/supply-chain-audit.yml | 3 +++ .github/workflows/tests.yml | 2 ++ .github/workflows/upload_to_pypi.yml | 21 ++++++++++++++++++-- 12 files changed, 54 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f80b2230a62..cc0219f57d8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,6 +35,7 @@ jobs: detect: name: Detect affected areas runs-on: ubuntu-latest + timeout-minutes: 10 outputs: python: ${{ steps.classify.outputs.python }} frontend: ${{ steps.classify.outputs.frontend }} @@ -161,6 +162,7 @@ jobs: # - docker if: always() runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Evaluate job results env: @@ -191,6 +193,7 @@ jobs: needs: [all-checks-pass, docker] if: always() runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/contributor-check.yml b/.github/workflows/contributor-check.yml index fd9e76752af..2c5db6f311d 100644 --- a/.github/workflows/contributor-check.yml +++ b/.github/workflows/contributor-check.yml @@ -9,6 +9,7 @@ permissions: jobs: check-attribution: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/deploy-site.yml b/.github/workflows/deploy-site.yml index 6e7dc84415d..f98db238697 100644 --- a/.github/workflows/deploy-site.yml +++ b/.github/workflows/deploy-site.yml @@ -41,6 +41,7 @@ jobs: # doesn't auto-deploy via the deploy-docs path. if: github.event_name == 'release' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest + timeout-minutes: 30 steps: - name: Trigger Vercel Deploy run: curl -X POST "${{ secrets.VERCEL_DEPLOY_HOOK }}" @@ -48,6 +49,7 @@ jobs: deploy-docs: if: github.repository == 'NousResearch/hermes-agent' runs-on: ubuntu-latest + timeout-minutes: 30 environment: name: github-pages url: ${{ steps.deploy.outputs.page_url }} @@ -65,7 +67,9 @@ jobs: python-version: '3.11' - name: Install PyYAML for skill extraction - run: pip install pyyaml==6.0.2 httpx==0.28.1 + uses: ./.github/actions/retry + with: + command: pip install pyyaml==6.0.2 httpx==0.28.1 - name: Prepare skills index (unified multi-source catalog) env: @@ -150,8 +154,10 @@ jobs: run: python3 website/scripts/generate-skill-docs.py - name: Install dependencies - run: npm ci - working-directory: website + uses: ./.github/actions/retry + with: + command: npm ci + working-directory: website - name: Build Docusaurus run: npm run build diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index e19894c96fd..e92a085f781 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -127,12 +127,13 @@ jobs: run: uv python install 3.11 - name: Install Python dependencies (for docker tests) - run: | - # ``dev`` extra pulls in pytest, pytest-asyncio — - # everything tests/docker/ needs. We deliberately avoid ``all`` - # here because the docker tests only drive the container via - # subprocess and don't import hermes_agent's optional deps. - uv sync --locked --python 3.11 --extra dev + # ``dev`` extra pulls in pytest, pytest-asyncio — + # everything tests/docker/ needs. We deliberately avoid ``all`` + # here because the docker tests only drive the container via + # subprocess and don't import hermes_agent's optional deps. + uses: ./.github/actions/retry + with: + command: uv sync --locked --python 3.11 --extra dev - name: Run docker integration tests env: diff --git a/.github/workflows/docs-site-checks.yml b/.github/workflows/docs-site-checks.yml index 705f2171e5c..41acf1790f4 100644 --- a/.github/workflows/docs-site-checks.yml +++ b/.github/workflows/docs-site-checks.yml @@ -9,6 +9,7 @@ permissions: jobs: docs-site-checks: runs-on: ubuntu-latest + timeout-minutes: 20 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/history-check.yml b/.github/workflows/history-check.yml index 07e4fa348e4..a48dba8cb8a 100644 --- a/.github/workflows/history-check.yml +++ b/.github/workflows/history-check.yml @@ -22,6 +22,7 @@ permissions: jobs: check-common-ancestor: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/js-tests.yml b/.github/workflows/js-tests.yml index f0a384bafe6..4e4622f72d0 100644 --- a/.github/workflows/js-tests.yml +++ b/.github/workflows/js-tests.yml @@ -8,6 +8,7 @@ jobs: workspaces: name: List npm workspaces runs-on: ubuntu-latest + timeout-minutes: 20 outputs: packages: ${{ steps.set-matrix.outputs.packages }} steps: @@ -32,6 +33,7 @@ jobs: name: Typecheck & Test needs: workspaces runs-on: ubuntu-latest + timeout-minutes: 20 strategy: matrix: package: ${{ fromJson(needs.workspaces.outputs.packages) }} diff --git a/.github/workflows/skills-index-freshness.yml b/.github/workflows/skills-index-freshness.yml index 856878def5f..badbd989a0c 100644 --- a/.github/workflows/skills-index-freshness.yml +++ b/.github/workflows/skills-index-freshness.yml @@ -20,6 +20,7 @@ jobs: check-freshness: if: github.repository == 'NousResearch/hermes-agent' runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Probe live index id: probe diff --git a/.github/workflows/skills-index.yml b/.github/workflows/skills-index.yml index 1997dedf5c7..8d5032cfd81 100644 --- a/.github/workflows/skills-index.yml +++ b/.github/workflows/skills-index.yml @@ -20,6 +20,7 @@ jobs: # Only run on the upstream repository, not on forks if: github.repository == 'NousResearch/hermes-agent' runs-on: ubuntu-latest + timeout-minutes: 15 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -28,7 +29,9 @@ jobs: python-version: "3.11" - name: Install dependencies - run: pip install httpx==0.28.1 pyyaml==6.0.2 + uses: ./.github/actions/retry + with: + command: pip install httpx==0.28.1 pyyaml==6.0.2 - name: Build skills index env: @@ -49,6 +52,7 @@ jobs: needs: build-index if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Trigger Deploy Site workflow env: diff --git a/.github/workflows/supply-chain-audit.yml b/.github/workflows/supply-chain-audit.yml index 201e92d174c..ff2df8e077f 100644 --- a/.github/workflows/supply-chain-audit.yml +++ b/.github/workflows/supply-chain-audit.yml @@ -43,6 +43,7 @@ jobs: name: Scan PR for critical supply chain risks if: inputs.scan runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -164,6 +165,7 @@ jobs: name: Check PyPI dependency upper bounds if: inputs.deps runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -229,6 +231,7 @@ jobs: name: MCP catalog security review if: inputs.mcp_catalog runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f74d574fa27..faa4b072504 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,6 +20,7 @@ jobs: generate: name: "Generate slices" runs-on: ubuntu-latest + timeout-minutes: 10 outputs: matrix: ${{ steps.matrix.outputs.matrix }} steps: @@ -126,6 +127,7 @@ jobs: needs: test if: needs.test.result == 'success' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Download all slice durations uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 diff --git a/.github/workflows/upload_to_pypi.yml b/.github/workflows/upload_to_pypi.yml index 03fad4eba0c..edd17e15525 100644 --- a/.github/workflows/upload_to_pypi.yml +++ b/.github/workflows/upload_to_pypi.yml @@ -26,6 +26,7 @@ jobs: build: name: Build distribution 📦 runs-on: ubuntu-latest + timeout-minutes: 30 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -56,10 +57,24 @@ jobs: node-version: "22" - name: Build web dashboard - run: cd web && npm ci && npm run build + uses: ./.github/actions/retry + with: + command: npm ci + working-directory: web + + - name: Compile web dashboard + run: npm run build + working-directory: web - name: Build TUI bundle - run: cd ui-tui && npm ci && npm run build + uses: ./.github/actions/retry + with: + command: npm ci + working-directory: ui-tui + + - name: Compile TUI bundle + run: npm run build + working-directory: ui-tui - name: Bundle TUI into hermes_cli run: | @@ -90,6 +105,7 @@ jobs: name: Publish to PyPI needs: build runs-on: ubuntu-latest + timeout-minutes: 30 environment: name: pypi url: https://pypi.org/p/hermes-agent @@ -115,6 +131,7 @@ jobs: if: startsWith(github.ref, 'refs/tags/') needs: publish runs-on: ubuntu-latest + timeout-minutes: 30 permissions: contents: write # attach assets to the existing release id-token: write # sigstore signing