Skip to content

ci(workflows): route Linux jobs to self-hosted p330 - #4

Merged
NomenAK merged 5 commits into
mainfrom
capy/self-hosted-runner-optimize
May 9, 2026
Merged

NomenAK merged 5 commits into
mainfrom
capy/self-hosted-runner-optimize

Conversation

@NomenAK

@NomenAK NomenAK commented May 9, 2026 •

Copy link
Copy Markdown
Owner

This PR routes Linux CI/CD jobs to the deterministic p330 self-hosted runner and adds low-risk performance defaults to reduce CI/CD waste.

  • .github/workflows/ci.yml: Migrate all Linux jobs (lint, build, test-unit, test-coverage, test-e2e, test-integration, test-security, sonarqube, ci-summary, i18n-matrix, i18n, pr-test-policy, advanced-security, package-artifact, coverage-pr-comment) from ubuntu-latest to [self-hosted, Linux, X64, nomenak, omniroute, p330]. Add workflow-level NPM_CONFIG_AUDIT, NPM_CONFIG_FUND, and PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD defaults. E2E job retains explicit npx playwright install --with-deps chromium.

  • .github/workflows/docker-publish.yml: Pin runner from [self-hosted, nomenak] to [self-hosted, Linux, X64, nomenak, omniroute, p330] for deterministic multi-arch builds.

  • .github/workflows/deploy-vps.yml: Move deploy job to p330 runner; triggers and SSH commands unchanged.

  • .github/workflows/npm-publish.yml: Move publish job to p330 runner; add npm/Playwright env defaults; preserve Node 22.22.2 and publish logic.

  • .github/workflows/electron-release.yml: Move validate and release jobs to p330 runner. Linux Electron matrix entry uses p330; macOS (intel/ARM64) and Windows entries remain on GitHub-hosted runners. Add workflow-level npm/Playwright env defaults.

Open CAPD-004 CAPD-004

Summary by CodeRabbit

  • Chores

    • CI workflows now set flags to disable npm audit/fund and skip Playwright browser downloads.
    • Runner selection changed to use hosted runners for pull-request events and self-hosted runners for other events across build, test, publish, deploy, and release workflows.
    • No application-facing functionality changed.
  • Tests

    • Unit tests for retry/cooldown behavior updated to improve deterministic timing and validate cooldown recovery.

Review Change Stack

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
@NomenAK NomenAK added the capy Generated by capy.ai label May 9, 2026 — with Capy AI
@coderabbitai

coderabbitai Bot commented May 9, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Multiple GitHub Actions workflows switch jobs to a labeled self-hosted runner; ci.yml and npm-publish.yml add workflow-level env vars to disable npm audit/fund and skip Playwright browser downloads; a unit test was updated to restore retry config and assert provider DB state after retry recovery.

Changes

Self-Hosted Runner Migration

Layer / File(s) Summary
Workflow Environment Configuration
.github/workflows/ci.yml, .github/workflows/npm-publish.yml
Added NPM_CONFIG_AUDIT, NPM_CONFIG_FUND, and PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD workflow-level environment variables.
CI Workflow Runner Migration
.github/workflows/ci.yml
Multiple jobs (lint, i18n-matrix, i18n, pr-test-policy, advanced-security, build, package-artifact, test-unit, test-coverage, sonarqube, coverage-pr-comment, test-e2e, test-integration, test-security, ci-summary) now conditionally run on ubuntu-latest for pull requests or on the labeled self-hosted runner for other events.
Deployment Workflows Runner Migration
.github/workflows/deploy-vps.yml, .github/workflows/docker-publish.yml, .github/workflows/electron-release.yml, .github/workflows/npm-publish.yml
VPS deploy, Docker publish, Electron release (validate/build/release), and npm publish jobs updated to run on the labeled self-hosted runner labels.
Actionlint Runner Labels
.github/actionlint.yaml
Adds self-hosted-runner.labels listing self-hosted, linux, x64, nomenak, omniroute, p330.
Unit Test: Retry & Provider DB Assertion
tests/unit/chat-cooldown-aware-retry.test.ts
Tests now import providers DB, save/restore BaseExecutor.RETRY_CONFIG.maxAttempts, mock fetch to fail once then succeed, and assert fetch call count and provider connection rateLimitedUntil cleared.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I hopped through YAML late at night,

Switched runners to my cozy site.
Audits hushed, browsers kept at bay,
Tests check DB where connections lay.
CI hums softly through the day.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the main changes across all modified workflows and explains the rationale, but is missing several required template sections: Related Issues, Validation, Tests, and Coverage Notes. Add the missing template sections: Related Issues (if applicable), Validation checklist, Tests Added Or Updated, Coverage Notes, and Reviewer Notes to complete the description.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: routing Linux CI/CD jobs to a self-hosted p330 runner, which matches the primary objective of the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch capy/self-hosted-runner-optimize

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Line 26: The CI workflow uses custom self-hosted runner labels (nomenak,
omniroute, p330) in the runs-on array which actionlint flags as unknown; fix
this by adding an actionlint configuration that declares these labels in the
allowlist for runners (include nomenak, omniroute, p330) so actionlint
recognizes them, and ensure the new config is committed to the repo so all
workflows referencing the runs-on labels pass actionlint validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9f286e82-b751-46c5-b0a4-ff64f9aca87f

📥 Commits

Reviewing files that changed from the base of the PR and between c7a0159 and b588777.

📒 Files selected for processing (5)
  • .github/workflows/ci.yml
  • .github/workflows/deploy-vps.yml
  • .github/workflows/docker-publish.yml
  • .github/workflows/electron-release.yml
  • .github/workflows/npm-publish.yml

Comment thread .github/workflows/ci.yml Outdated

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added 1 comment

Comment thread .github/workflows/ci.yml Outdated
lint:
name: Lint
runs-on: ubuntu-latest
runs-on: [self-hosted, Linux, X64, nomenak, omniroute, p330]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🟠 High] [🔵 Bug]

The PR changes pull_request CI jobs from ephemeral GitHub-hosted runners to a persistent self-hosted runner, which lets contributor-controlled PR code execute on internal infrastructure and increases runner compromise/lateral-movement risk even when secrets are restricted. ```yaml

.github/workflows/ci.yml

jobs:
lint:
name: Lint
runs-on: [self-hosted, Linux, X64, nomenak, omniroute, p330]
``` This matters because this workflow is triggered by pull_request and now routes broad job coverage (lint/build/tests/security scans) to the same self-hosted target. Keep untrusted PR workloads on `ubuntu-latest`, or gate self-hosted execution to trusted contexts only (for example, trusted actors/events or `pull_request_target` with strict checkout safeguards).

NomenAK and others added 4 commits May 9, 2026 14:50
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/unit/chat-cooldown-aware-retry.test.ts (1)

31-39: ⚡ Quick win

Restore delayMs in teardown to avoid config leakage between tests.

Line 32 sets BaseExecutor.RETRY_CONFIG.delayMs = 0, but no restore is done in afterEach. Restoring it (like maxAttempts) keeps test isolation robust.

Suggested patch
 const originalRetryMaxAttempts = BaseExecutor.RETRY_CONFIG.maxAttempts;
+const originalRetryDelayMs = BaseExecutor.RETRY_CONFIG.delayMs;
@@
 test.afterEach(async () => {
+  BaseExecutor.RETRY_CONFIG.delayMs = originalRetryDelayMs;
   BaseExecutor.RETRY_CONFIG.maxAttempts = originalRetryMaxAttempts;
   await resetStorage();
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/chat-cooldown-aware-retry.test.ts` around lines 31 - 39, The test
setup modifies BaseExecutor.RETRY_CONFIG.delayMs to 0 in test.beforeEach but
never restores it, causing config leakage; update the teardown (test.afterEach)
to restore delayMs to its original value (similar to how maxAttempts is
restored) by saving the original delayMs before changing it in beforeEach and
assigning it back in afterEach, referring to BaseExecutor.RETRY_CONFIG,
test.beforeEach/test.afterEach and resetStorage to ensure isolation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/unit/chat-cooldown-aware-retry.test.ts`:
- Around line 130-135: The test dereferences updatedConnection without asserting
it exists; change the test around providersDb.getProviderConnections so it first
asserts the returned array has at least one element (or that updatedConnection
is defined) before using updatedConnection.id and
updatedConnection.rateLimitedUntil; update assertions near
providersDb.getProviderConnections / updatedConnection to include a clear
failure message if no connection is returned so the test fails with a
descriptive assertion instead of a TypeError.

---

Nitpick comments:
In `@tests/unit/chat-cooldown-aware-retry.test.ts`:
- Around line 31-39: The test setup modifies BaseExecutor.RETRY_CONFIG.delayMs
to 0 in test.beforeEach but never restores it, causing config leakage; update
the teardown (test.afterEach) to restore delayMs to its original value (similar
to how maxAttempts is restored) by saving the original delayMs before changing
it in beforeEach and assigning it back in afterEach, referring to
BaseExecutor.RETRY_CONFIG, test.beforeEach/test.afterEach and resetStorage to
ensure isolation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7d01d4ca-6f28-470c-ba14-2b73f541fd61

📥 Commits

Reviewing files that changed from the base of the PR and between c289d67 and a886795.

📒 Files selected for processing (1)
  • tests/unit/chat-cooldown-aware-retry.test.ts

Comment on lines +130 to +135
const [updatedConnection] = await providersDb.getProviderConnections({ provider: "openai" });

assert.equal(response.status, 200);
assert.equal(fetchCalls, 4);
assert.equal(fetchCalls, 2);
assert.equal(updatedConnection.id, connection.id);
assert.equal(updatedConnection.rateLimitedUntil, undefined);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Assert connection existence before dereferencing for clearer failures.

Line 134 assumes updatedConnection exists. If Line 130 returns an empty array, this throws a TypeError instead of a precise test assertion.

Suggested patch
 const [updatedConnection] = await providersDb.getProviderConnections({ provider: "openai" });

 assert.equal(response.status, 200);
 assert.equal(fetchCalls, 2);
+assert.ok(updatedConnection, "expected an updated openai provider connection");
 assert.equal(updatedConnection.id, connection.id);
 assert.equal(updatedConnection.rateLimitedUntil, undefined);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const [updatedConnection] = await providersDb.getProviderConnections({ provider: "openai" });
assert.equal(response.status, 200);
assert.equal(fetchCalls, 4);
assert.equal(fetchCalls, 2);
assert.equal(updatedConnection.id, connection.id);
assert.equal(updatedConnection.rateLimitedUntil, undefined);
const [updatedConnection] = await providersDb.getProviderConnections({ provider: "openai" });
assert.equal(response.status, 200);
assert.equal(fetchCalls, 2);
assert.ok(updatedConnection, "expected an updated openai provider connection");
assert.equal(updatedConnection.id, connection.id);
assert.equal(updatedConnection.rateLimitedUntil, undefined);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/chat-cooldown-aware-retry.test.ts` around lines 130 - 135, The
test dereferences updatedConnection without asserting it exists; change the test
around providersDb.getProviderConnections so it first asserts the returned array
has at least one element (or that updatedConnection is defined) before using
updatedConnection.id and updatedConnection.rateLimitedUntil; update assertions
near providersDb.getProviderConnections / updatedConnection to include a clear
failure message if no connection is returned so the test fails with a
descriptive assertion instead of a TypeError.

@NomenAK
NomenAK merged commit dbbcf36 into main May 9, 2026
49 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

capy Generated by capy.ai

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant