一键导入
ci-fix-port
// Fetch CI build failure logs from GitHub Actions or PRs, diagnose the root cause, and fix the failing port or patch. Use when: a CI job fails after a port upgrade, a patch no longer applies, or a build option changed upstream.
// Fetch CI build failure logs from GitHub Actions or PRs, diagnose the root cause, and fix the failing port or patch. Use when: a CI job fails after a port upgrade, a patch no longer applies, or a build option changed upstream.
| name | ci-fix-port |
| description | Fetch CI build failure logs from GitHub Actions or PRs, diagnose the root cause, and fix the failing port or patch. Use when: a CI job fails after a port upgrade, a patch no longer applies, or a build option changed upstream. |
| argument-hint | pr=<number|url>; run=<id|url>; job=<name>; port=<name>; mode=diagnose|fix |
Use this skill to pull build failure information from GitHub Actions, diagnose the cause, and fix the affected port or patch.
Repository: atframework/cmake-toolset
(remote may be owent/cmake-toolset)
The agent needs access to GitHub data. Try these sources in order and use the first that works:
mcp_github_*) — search
for mcp_github with tool_search_tool_regexgh CLI — run gh --version to testfetch_webpage — read job HTML pages or API
JSON directlyFallback strategy: When log download returns 403 or "Sign in to view logs", switch to the indirect diagnosis methods in Phase 3 instead of retrying. Do not waste time on blocked endpoints.
Parse user input for:
pr= — PR number or URLrun= — Actions run ID or URLjob= — job name filter (e.g., gcc.no-rtti.test)port= — port name hint (optional)mode= — diagnose (read-only) or fix (default)If no input is given, auto-detect:
main from that
branch, or the latest CI run on that branch.fetch_webpage with the GitHub API:
https://api.github.com/repos/{owner}/{repo}/actions/runs?branch={branch}&per_page=5
Gather job data:
/actions/runs/{run_id}/jobs?per_page=30
status and conclusion.started_at to completed_at), runner labels.main
for the same jobs — this confirms whether the
failure is a regression.Try to get actual log text using the methods below. If all fail, proceed to Phase 3 with indirect methods.
gh CLIgh run view <run-id> --repo owent/cmake-toolset \
--log-failed
Invoke-RestMethod `
"$base/actions/jobs/<job-id>/logs" `
-Headers @{
Authorization = "Bearer $env:GITHUB_TOKEN"
}
Even without log access, annotations contain error summaries:
/repos/{owner}/{repo}/check-runs/{job-id}/annotations
These are usually just "Process completed with exit code 1" but occasionally contain cmake error lines.
fetch_webpage on job HTMLhttps://github.com/{owner}/{repo}/actions/runs/{run_id}/job/{job_id}
Note: This often returns "Sign in to view logs" for private repos or when unauthenticated.
CI logs are very large. The build pipeline outputs
all port build logs first, then prints the
failing port's CMakeConfigureLog.yaml at the end.
Do not read the entire log sequentially — this
wastes context and tokens. Instead:
Select-String (PowerShell) or grep to find
lines containing error, FAILED,
fatal error, CMake Error, or
ATFRAMEWORK_CMAKE_TOOLSET_THIRD_PARTY_CI_MODE
in the downloaded log file.CMakeConfigureLog.yaml dump
and the final error summary, which are the most
diagnostic.gh run view --log-failed, the output
is already filtered to failed steps, but can
still be large. Apply the same search-first
strategy.Parse the log output and classify the failure:
| Pattern | Likely Cause |
|---|---|
error: patch failed / git apply error | Patch no longer applies cleanly |
Unknown CMake command / option error | Deprecated or renamed build option |
fatal error: … not found | Missing dependency or include order |
undefined reference / link error | ABI or library mismatch |
FAILED: … test | Runtime test regression |
Could not find … package / include could not find | Config-package bug or find_package failure |
| Cross-compile host tool error | Host-tool not built or not found |
-lc++abi / compiler not found | CI environment change (runner OS update) |
When logs are inaccessible, use these strategies:
Timing analysis — classify failures by duration:
Platform grouping — if all MSVC jobs fail but Linux passes, the issue is platform-specific. Similarly for macOS-only failures.
BUILD_SHARED_LIBS grouping — if shared jobs
fail but static passes (or vice versa), the issue
involves library type handling (config packages,
DLL exports, etc.). Note: the actual shared/static
decision per port is resolved by
project_third_party_check_build_shared_lib() in
ports/Configure.cmake:
${FULL_PORT_NAME}_USE_SHARED > _USE_STATIC >
BUILD_SHARED_LIBS / ATFRAMEWORK_USE_DYNAMIC_LIBRARY
default static. A port may be static even when
BUILD_SHARED_LIBS=ONif its_USE_STATICis set.
Diff analysis — compare main..dev changes:
ProjectBuildTools.cmake,
FindConfigurePackage.cmake) changed?Local reproduction — the most powerful tool
when logs are unavailable. Build the suspected
port locally and test find_package:
# Example: test a port's config package
cmake -S <upstream-src> -B build `
-DBUILD_SHARED_LIBS=OFF `
-DCMAKE_INSTALL_PREFIX=install
cmake --build build --target install
# Then test find_package:
cmake -S test_project -B test_build `
-DCMAKE_PREFIX_PATH=install
CI script analysis — read ci/do_ci.sh and
ci/do_ci.ps1 for the failing job's configuration.
Check for:
-D flags in a single quoted string
(PowerShell bug)Compare with last main CI — fetch the last
successful main run's jobs to confirm the same
jobs passed before. This isolates regressions
from pre-existing flakiness.
Record for each failure:
BUILD_SHARED_LIBS value for the jobmainBased on diagnosis, apply the appropriate fix:
This is a common issue when upstream cmake config
files (<Pkg>Config.cmake) have bugs:
BUILD_SHARED_LIBS setting as the failing CI job.lib/cmake/<Pkg>/).include() without
OPTIONAL, missing target aliases, or assumptions
about which components are installed.*Config.cmake.in template.find_package(<Pkg> REQUIRED) in
a minimal test cmake project.Follow patch-workflow.md:
test/third_party/packages/.git apply --check <patch>..cross.patch
separately.test/third_party/packages/ afterward.Follow deprecated-options.md:
test/CMakeLists.txt for correct include
order.MODULE.bazel / CMakeLists.txt
for changed dependency pins.When the failure is caused by runner OS changes, not port code:
do_ci.sh / do_ci.ps1) for the affected job.-lc++abi on macOS, versioned compiler binaries,
SDK paths).# Fallback: try without -lc++abi (macOS bundles
# it into libc++)
cmd1 || cmd1_without_abi || FAIL=1
Follow cross-compilation.md.
If the fix is a patch, test it locally:
cd test/third_party/packages/<port>-<version>
git -c "core.autocrlf=input" apply --check <patch>
If the fix touches a config package, do a full local verification:
find_package() in a test cmake projectBUILD_SHARED_LIBS=ON and OFF
if both variants are used in CIReview test/CMakeLists.txt,
.github/workflows/build.yaml, and ci/do_ci.*
for related job combinations that may be affected.
Clean up all local test artifacts:
test/third_party/packages/<port>-*test/build_* temp directoriesSummarize: what failed, root cause, files changed, and any remaining risks.
cmake-format -i on every modified
.cmake, .cmake.in, and CMakeLists.txt file
(excluding test/third_party/ and
test/build_jobs_*/). Alternatively run
bash ci/format.sh to format the entire tree.
CI will reject unformatted files..cross.patch separately from normal
patches.test/third_party/packages/ and any
temp build directories after testing.CMAKE_FIND_PACKAGE_PREFER_CONFIG=TRUE is set
(as in this repo), all find_package calls prefer
config mode. Upstream *Config.cmake bugs surface
immediately.core.autocrlf=input
since the repo uses this setting.Upgrade cmake-toolset ports to newer upstream versions. Use when: checking releases, resolving dependency pins, validating patches, handling cross-compiling host tools, or reviewing CI impact.
Fetch CI build failure logs from GitHub Actions or PRs, diagnose the root cause, and fix the failing port or patch. Use when: a CI job fails after a port upgrade, a patch no longer applies, or a build option changed upstream.