Skip to content

fix(ci): add fork workflow sync check for community PRs#147

Closed
dev01lay2 wants to merge 1 commit intodevelopfrom
fix/fork-pr-ci
Closed

fix(ci): add fork workflow sync check for community PRs#147
dev01lay2 wants to merge 1 commit intodevelopfrom
fix/fork-pr-ci

Conversation

@dev01lay2
Copy link
Copy Markdown
Collaborator

@dev01lay2 dev01lay2 commented Mar 20, 2026

Problem

Fork PRs (e.g. #142) include stale .github/workflows/ files from the fork. GitHub runs these stale workflows in the merge commit, causing confusing CI failures (missing files, wrong refs, permission errors).

Solution

Add a lightweight fork workflow sync check step after checkout in all PR-triggered workflows. For fork PRs only, it compares .github/workflows/ against the base branch — if files differ, the job fails immediately with clear instructions:

::error::Your fork's .github/workflows/ files are out of sync with the base branch.
::error::Please sync your fork with upstream before pushing:
::error::  git fetch upstream develop
::error::  git checkout upstream/develop -- .github/workflows/
::error::  git commit -m 'sync: align workflow files with upstream'
::error::  git push

Changes:

Workflow Change
ci.yml Fork sync check after checkout
coverage.yml Fork sync check after checkout
home-perf-e2e.yml Fork sync check after checkout
metrics.yml Fork sync check after checkout
pr-build.yml Fork sync check after checkout
screenshot.yml Fork sync check after checkout
e2e.yml Skip fork PRs entirely (requires repo secrets)

Why not pull_request_target?

pull_request_target + checkout PR code = security risk (untrusted code runs with write permissions). Keeping pull_request trigger is safe and testable.

Trade-off

Fork contributors need to sync their .github/workflows/ directory before CI will run. This is a one-time step per sync and the error message tells them exactly what to do.

Fixes CI for #142.

Copy link
Copy Markdown
Collaborator

@Keith-CY Keith-CY left a comment

Choose a reason for hiding this comment

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

Two blockers remain in this revision:

  1. This switches multiple workflows to pull_request_target and then checks out refs/pull/<n>/merge and runs PR-controlled code from that checkout (bun install, npm ci, cargo llvm-cov, cargo test, docker build, etc.). That is the unsafe pull_request_target pattern for fork PRs. The worst case is screenshot.yml, which grants contents: write, builds PR-controlled Docker context, and then pushes back to the repository. GitHub recommends avoiding pull_request_target unless privileged context is strictly necessary, and workflows using it must not explicitly check out untrusted code. A safer shape is to keep execution workflows on pull_request and use a separate metadata-only privileged workflow (workflow_run or similar) to post comments.

  2. screenshot.yml now triggers on pull_request_target, but the final comment steps still require github.event_name == pull_request, so the screenshot comment will never be created or updated.

There is also a correctness regression in coverage.yml and metrics.yml: their concurrency keys still use github.ref, which under pull_request_target is the base branch ref, so unrelated PRs to the same base can cancel each other.

Fork PRs include their own .github/workflows/ files in the merge commit.
If the fork is behind upstream, CI runs stale workflows that reference
deleted files or lack recent fixes — causing confusing failures.

Solution: add a lightweight check step (fork PRs only) after checkout
that compares .github/workflows/ against the base branch. If files
differ, the job fails immediately with clear sync instructions.

- ci.yml, coverage.yml, home-perf-e2e.yml, metrics.yml, pr-build.yml,
  screenshot.yml: add fork workflow sync verification step
- e2e.yml: skip fork PRs entirely (requires repo secrets)
- No trigger changes — keeps pull_request (safe, testable)
- No security implications — no elevated permissions for fork code
@dev01lay2 dev01lay2 changed the title fix(ci): use pull_request_target for fork PR compatibility fix(ci): add fork workflow sync check for community PRs Mar 20, 2026
@github-actions
Copy link
Copy Markdown
Contributor

📊 Test Coverage Report

Metric Base (develop) PR (fix/fork-pr-ci) Delta
Lines 74.59% (6228/8350) 74.59% (6228/8350) ⚪ ±0.00%
Functions 69.12% (714/1033) 69.12% (714/1033) ⚪ ±0.00%
Regions 75.97% (10250/13492) 75.97% (10250/13492) ⚪ ±0.00%

Coverage measured by cargo llvm-cov (clawpal-core + clawpal-cli).

@dev01lay2
Copy link
Copy Markdown
Collaborator Author

Closing — fork CI sync issues can be resolved through contributor communication (asking them to sync their fork with upstream).

@dev01lay2 dev01lay2 closed this Mar 20, 2026
@github-actions
Copy link
Copy Markdown
Contributor

📸 UI Screenshots

Commit: d8da27f863821a627a018a4821f0c64f9524fae5 | Screenshots: Download artifact

Light Mode — Core Pages

Start Page Home Channels
start home channels
Recipes Cron Doctor
recipes cron doctor
Context History Chat Panel
context history chat
Settings (4 scroll positions)
Main Appearance Advanced Bottom
s1 s2 s3 s4
Start Page Sections
Overview Profiles Settings
sp1 sp2 sp3

Dark Mode

Start Home Channels Doctor
d1 d2 d3 d4
Dark mode — more pages
Recipes Cron Settings
d5 d6 d7

Responsive + Dialogs

Home 1024×680 Chat 1024×680 Create Agent
r1 r2 d1

🔧 Harness: Docker + Xvfb + tauri-driver + Selenium | 28 screenshots, 13 flows

@github-actions
Copy link
Copy Markdown
Contributor

📏 Metrics Gate Report

Status: ✅ All gates passed

Commit Size ✅

Metric Value Limit Status
Commits checked 1
All within limit 1/1 ≤ 500 lines
Largest commit 92 lines ≤ 500

Bundle Size ✅

Metric Value Limit Status
JS bundle (raw) 922 KB
JS bundle (gzip) 290 KB ≤ 350 KB
JS initial load (gzip) 164 KB ≤ 180 KB

Perf Metrics E2E ✅

Metric Value Limit Status
Tests 10 passed, 0 failed 0 failures
RSS (test process) 3.3 MB ≤ 20 MB
VMS (test process) 269.9 MB ℹ️
Command P50 latency 17 µs ≤ 1000 µs
Command P95 latency 19 µs ≤ 5000 µs
Command max latency 34 µs ≤ 50000 µs

Command Perf (local) ✅

Metric Value Status
Tests 4 passed, 0 failed
Commands measured 5 ℹ️
RSS (test process) 4.5 MB ℹ️
Local command timings
Command P50 (µs) P95 (µs) Max (µs)
local_openclaw_config_exists 0 8 8
list_ssh_hosts 1 10 10
get_app_preferences 12 31 31
read_app_log 47 62 62
read_error_log 2 5 5

Command Perf (remote SSH) ✅

Metric Value Status
SSH transport OK
Command failures 12/15 runs ℹ️ Docker (no gateway)
Remote command timings (via Docker SSH)
Command Median Max
openclaw_status 1879 ms 1886 ms
cat__root_.openclaw_openclaw.json 244 ms 244 ms
openclaw_gateway 2029 ms 2036 ms
openclaw_cron 1931 ms 1947 ms
openclaw_agent 2036 ms 2154 ms

Home Page Render Probes (real IPC) ✅

Probe Value Limit Status
status 45 ms ≤ 500 ms
version 74 ms ≤ 500 ms
agents 45 ms ≤ 500 ms
models 135 ms ≤ 500 ms
settled 124 ms ≤ 500 ms

Code Readability

File Lines Target Status
commands/doctor_assistant.rs 5636 ≤ 3000 ⚠️
commands/rescue.rs 3402 ≤ 2000 ⚠️
commands/profiles.rs 2477 ≤ 1500 ⚠️
cli_runner.rs 1915 ≤ 1200 ⚠️
commands/sessions.rs 1807 ≤ 1100 ⚠️
commands/credentials.rs 1629 ≤ 1000 ⚠️
openclaw_doc_resolver.rs 1362 ≤ 800 ⚠️
commands/ssh.rs 1232 ≤ 700 ⚠️
commands/doctor.rs 1168 ≤ 700 ⚠️
pages/StartPage.tsx 898 ≤ 500 ⚠️
pages/Settings.tsx 897 ≤ 500 ⚠️
commands/discovery.rs 878 ≤ 500 ⚠️
pages/Home.tsx 875 ≤ 500 ⚠️
install/commands.rs 839 ≤ 500 ⚠️
ssh.rs 826 ≤ 500 ⚠️
commands/backup.rs 788 ≤ 500 ⚠️
lib/use-api.ts 687 ≤ 500 ⚠️
components/SessionAnalysisPanel.tsx 659 ≤ 500 ⚠️
commands/model.rs 645 ≤ 500 ⚠️
bridge_client.rs 645 ≤ 500 ⚠️
components/InstallHub.tsx 619 ≤ 500 ⚠️
agent_fallback.rs 609 ≤ 500 ⚠️
lib/types.ts 550 ≤ 500 ⚠️
install/runners/docker.rs 525 ≤ 500 ⚠️
commands/types.rs 518 ≤ 500 ⚠️
commands/overview.rs 508 ≤ 500 ⚠️
commands/instance.rs 501 ≤ 500 ⚠️
App.tsx 498 ≤ 500
pages/Doctor.tsx 479 ≤ 500
commands/agent.rs 475 ≤ 500
lib/api.ts 467 ≤ 500
pages/Channels.tsx 460 ≤ 500
node_client.rs 452 ≤ 500
commands/discover_local.rs 441 ≤ 500
pages/Cron.tsx 429 ≤ 500
components/__tests__/DoctorRecoveryOverview.test.tsx 429 ≤ 500
commands/config.rs 419 ≤ 500
bug_report/queue.rs 409 ≤ 500
commands/channels.rs 405 ≤ 500
lib/api-read-cache.ts 401 ≤ 500
components/__tests__/InstanceCard.test.tsx 400 ≤ 500
lib/__tests__/guidance.test.ts 399 ≤ 500
components/DoctorRecoveryOverview.tsx 383 ≤ 500
lib/use-cached-query.ts 353 ≤ 500
hooks/useSshConnection.ts 352 ≤ 500
components/DoctorTempProviderDialog.tsx 349 ≤ 500
lib.rs 341 ≤ 500
bug_report/collector.rs 335 ≤ 500
components/InstanceCard.tsx 334 ≤ 500
hooks/useWorkspaceTabs.ts 331 ≤ 500
lib/doctor-report-i18n.ts 328 ≤ 500
recipe.rs 325 ≤ 500
pages/__tests__/overview-loading.test.ts 318 ≤ 500
components/__tests__/SshFormWidget.test.tsx 312 ≤ 500
doctor.rs 303 ≤ 500
Files > 500 lines 27 trend ↓
Files over target 27 0 ⚠️

📊 Metrics defined in docs/architecture/metrics.md

@github-actions
Copy link
Copy Markdown
Contributor

📦 PR Build Artifacts

Platform Download Size
Windows-x64 📥 clawpal-Windows-x64 16.0 MB
macOS-x64 📥 clawpal-macOS-x64 13.1 MB
Linux-x64 📥 clawpal-Linux-x64 103.2 MB
macOS-ARM64 📥 clawpal-macOS-ARM64 12.4 MB

🔨 Built from 356608b · View workflow run
⚠️ Unsigned development builds — for testing only

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.

2 participants