Skip to content

ci: extract shared self-hosted setup into composite actions - #110

Open
luohuan19 wants to merge 1 commit into
hw-native-sys:mainfrom
luohuan19:ci/portable-runner-setup
Open

ci: extract shared self-hosted setup into composite actions#110
luohuan19 wants to merge 1 commit into
hw-native-sys:mainfrom
luohuan19:ci/portable-runner-setup

Conversation

@luohuan19

@luohuan19 luohuan19 commented Jul 23, 2026

Copy link
Copy Markdown

Background

The two self-hosted device jobs each carried ~130 lines of identical setup — checkout, pypto source sync, toolchain pin resolution, ptoas/pto-isa install, conda venv + activate.sh, from-source build — and every host path was hard-coded in the workflow, so a host with a different layout required a repo change.

Changes

Two composite actions

  • .github/actions/setup-ci-job — shared setup for every self-hosted device job
  • .github/actions/kill-orphaned-tasks — task-submit orphan cleanup

Host layout moves to the runner's .env (CONDA_ROOT, CI_CACHE_ROOT, CANN_ROOT, PYPTO_QWEN3_MODEL_DIR, PYPTO_DSV4_MODEL_DIR). No absolute path lives in git any more. Missing or malformed config (e.g. an inline comment in .env, which the runner does not strip) fails in the first step with an actionable message instead of surfacing 40 minutes later as an opaque mid-build error.

Job split: unit-tests becomes unit-tests-qwen and unit-tests-deepseek, so the 8-card DeepSeek borrow schedules independently of the single-card qwen3 runs. Each job takes its own pip cache dir and its own pypto build tree (ci-cache/pypto-src-<namespace>-<runner>) — sharing one tree let concurrent reset --hard / clean -ffdx / rm -rf build run under the other job's in-flight libbacktrace configure, surfacing as intermittent "C compiler cannot create executables".

Fixes carried along

  • Orphan cleanup now uses task-submit --find instead of --list. --list is a human-facing view that truncates the command column to 77 chars, so the old grep for the full checkout path never matched and the cleanup was a silent no-op. Requires task-submit >= 2026-07-14 on the runner.
  • Retry transient git clone/fetch TLS drops with backoff; retry the from-source pypto build after purging its build tree.
  • Detect the ptoas arch from uname -m (with the matching PTOAS_SHA256_<ARCH>) instead of pinning aarch64; download to a mktemp file so two concurrent cache-miss jobs cannot clobber each other.
  • Fall back to a clean re-clone when the incremental checkout fails on a stale submodule object store.
  • Raise task-submit --timeout from 1200s to 3600s; the accuracy guards were being killed before finishing on a loaded host. The DeepSeek job keeps --max-time 2700 from feat(serving): report OpenAI-style token usage in HTTP responses #107.

Deployment requirement

Before merging, each self-hosted runner needs the variables above added to <runner-root>/.env (one bare KEY=VALUE per line, no quotes and no trailing comments) and the runner service restarted. task-submit on the runner also has to be new enough to support --find.

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fd920797-6307-43f9-ac5a-a37253b7b292

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds reusable composite actions for CI environment setup and orphaned task cleanup, then restructures the workflow into separate Qwen3 and DeepSeek jobs with model-directory validation, longer task timeouts, isolated caches, and post-run cleanup.

Changes

CI infrastructure

Layer / File(s) Summary
Shared runner and toolchain setup
.github/actions/setup-ci-job/action.yml
Validates runner prerequisites, prepares isolated caches and environments, synchronizes pinned toolchains, builds the project, and installs ptoas.
Reusable orphaned task cleanup
.github/actions/kill-orphaned-tasks/action.yml
Finds tasks associated with a checkout path and attempts to terminate each matching task.
Qwen3 and DeepSeek CI jobs
.github/workflows/ci.yml
Splits unit tests into two jobs, adds model-directory checks and longer timeouts, uses shared setup, and performs reusable cleanup.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Poem

A bunny finds tasks left behind,
And hops through caches neatly aligned.
Qwen and DeepSeek now run their race,
With guarded models and timeout space.
Clean builds bloom when jobs depart—
CI now beats with a tidier heart.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title clearly describes the main change: extracting shared self-hosted CI setup into composite actions.
Description check ✅ Passed The description directly matches the PR changes and explains the setup extraction, job split, and cleanup updates.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@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:
- Around line 137-138: Add a top-level permissions block near the workflow
header granting only contents: read, so both unit-tests-qwen and
unit-tests-deepseek use least-privilege GITHUB_TOKEN access while retaining
checkout and build functionality.
🪄 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: dcce0ad8-68eb-41bb-a5f9-480a4c824690

📥 Commits

Reviewing files that changed from the base of the PR and between 8773989 and 86138bc.

📒 Files selected for processing (3)
  • .github/actions/kill-orphaned-tasks/action.yml
  • .github/actions/setup-ci-job/action.yml
  • .github/workflows/ci.yml

Comment thread .github/workflows/ci.yml
Comment on lines +137 to +138
unit-tests-deepseek:
runs-on: [self-hosted, linux, arm64, npu]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Add an explicit least-privilege permissions: block. The workflow relies on the repository's default GITHUB_TOKEN permissions for both new self-hosted jobs, which zizmor flags as an overly broad posture. These jobs only checkout and build, so scope the token down — ideally a top-level permissions: block (applies to unit-tests-qwen too), or per-job blocks.

🔒️ Suggested top-level block (add near the top of the workflow)
permissions:
  contents: read
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 137-214: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)

🤖 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 @.github/workflows/ci.yml around lines 137 - 138, Add a top-level permissions
block near the workflow header granting only contents: read, so both
unit-tests-qwen and unit-tests-deepseek use least-privilege GITHUB_TOKEN access
while retaining checkout and build functionality.

Source: Linters/SAST tools

@luohuan19
luohuan19 force-pushed the ci/portable-runner-setup branch 3 times, most recently from c763ab7 to 9c98e78 Compare July 23, 2026 08:07
The two self-hosted device jobs duplicated ~130 lines of setup (checkout,
pypto source sync, toolchain pins, ptoas/pto-isa install, conda venv +
activate.sh, build) and every host path was hard-coded in git. Pull all of
it into .github/actions/setup-ci-job, and the task-submit cleanup into
.github/actions/kill-orphaned-tasks.

Host layout now comes from the runner's .env (CONDA_ROOT, CI_CACHE_ROOT,
CANN_ROOT, PYPTO_{QWEN3,DSV4}_MODEL_DIR) instead of absolute paths in the
workflow, so a differently-laid-out host needs no repo change. Missing or
malformed config fails in the first step with an actionable message rather
than as an opaque mid-build error 40 minutes in.

Also in this change:

- Split unit-tests into unit-tests-qwen and unit-tests-deepseek so the
  8-card DeepSeek borrow schedules independently of the single-card qwen3
  runs. Each job takes its own pip cache dir and its own pypto build tree
  (ci-cache/pypto-src-<namespace>-<runner>) — a shared tree let concurrent
  syncs reset --hard / clean -ffdx under each other's in-flight configure.
- Kill orphaned tasks via `task-submit --find` instead of `--list`: --list
  truncates the command column to 77 chars, so the old grep never matched
  and the cleanup was silently a no-op.
- Retry transient git clone/fetch TLS drops with backoff, and retry the
  from-source pypto build after purging its build tree.
- Detect the ptoas arch from `uname -m` (with the matching PTOAS_SHA256_<ARCH>)
  instead of pinning aarch64; download to a mktemp file so concurrent
  cache-miss jobs cannot clobber each other.
- Fall back to a clean re-clone when the incremental checkout fails on a
  stale submodule object store.
- Raise task-submit --timeout from 1200s to 3600s; the accuracy guards were
  being killed before finishing on a loaded host.
@luohuan19
luohuan19 force-pushed the ci/portable-runner-setup branch from 9c98e78 to edeb760 Compare July 24, 2026 01:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant