Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 89 additions & 19 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

71 changes: 71 additions & 0 deletions scripts/ci-lcov-summary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env python3
"""Render the existing LCOV export without another llvm-profdata/llvm-cov pass.

LCOV carries line, function and branch totals, not LLVM region totals.
The raw LCOV artifact remains the source of truth for the merged report.
"""

import argparse
from pathlib import Path

METRICS = (("Lines", "LH", "LF"), ("Functions", "FNH", "FNF"), ("Branches", "BRH", "BRF"))


def read_lcov(text):
files = {}
name, counts = None, {}
for line in text.splitlines():
key, _, value = line.partition(":")
if key == "SF":
if name is not None:
raise ValueError("LCOV record missing end_of_record")
name, counts = value, {}
elif key in {key for _, hit, found in METRICS for key in (hit, found)}:
counts[key] = int(value)
elif line == "end_of_record":
if not name or name in files:
raise ValueError("LCOV source missing or duplicated")
if "LF" not in counts or "LH" not in counts:
raise ValueError(f"LCOV line totals missing: {name}")
for _, hit, found in METRICS:
if not 0 <= counts.get(hit, 0) <= counts.get(found, 0):
raise ValueError(f"Invalid LCOV totals: {name}")
files[name] = counts
name = None
if name is not None or not files:
raise ValueError("LCOV export empty or truncated")
return files


def summary(files, root):
def metric(counts, hit, found):
total, covered = counts.get(found, 0), counts.get(hit, 0)
return f"{covered}/{total} ({100 * covered / total:.2f}%)" if total else "0/0 (-)"

def label(name):
try:
return str(Path(name).relative_to(root))
except ValueError:
return name

rows = [["File", *(name for name, _, _ in METRICS)]]
for name, counts in sorted(files.items()):
rows.append([label(name), *(metric(counts, hit, found) for _, hit, found in METRICS)])
totals = {key: sum(counts.get(key, 0) for counts in files.values())
for _, hit, found in METRICS for key in (hit, found)}
rows.append(["TOTAL", *(metric(totals, hit, found) for _, hit, found in METRICS)])
widths = [max(len(row[i]) for row in rows) for i in range(4)]
return "\n".join(" ".join(value.ljust(widths[i]) if i == 0 else value.rjust(widths[i])
for i, value in enumerate(row)).rstrip() for row in rows) + "\n"


def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("lcov", type=Path)
parser.add_argument("--root", type=Path, default=Path.cwd())
args = parser.parse_args()
print(summary(read_lcov(args.lcov.read_text(encoding="utf-8")), args.root), end="")


if __name__ == "__main__":
main()
56 changes: 56 additions & 0 deletions scripts/ci-reuse-merge-group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env python3
"""Reuse CI only after the merge queue passed this exact main commit.

One bounded, workflow-scoped API read; any missing or unreadable evidence
falls back to running CI. PRs, nightlies and manual runs never reuse results.
"""

import json
import os
import subprocess
from pathlib import Path
from urllib.parse import urlencode


def successful_run(payload, repository, sha):
for run in payload["workflow_runs"]:
if (run.get("event") == "merge_group"
and run.get("head_sha") == sha
and run.get("status") == "completed"
and run.get("conclusion") == "success"
and run.get("path") == ".github/workflows/ci.yml"
and run.get("head_repository", {}).get("full_name") == repository
and run.get("head_branch", "").startswith("gh-readonly-queue/main/")):
return run["id"]
return None


def reusable_run(env):
if env.get("GITHUB_EVENT_NAME") != "push" or env.get("GITHUB_REF") != "refs/heads/main":
return None
try:
repository, sha = env["GITHUB_REPOSITORY"], env["GITHUB_SHA"]
query = urlencode({"event": "merge_group", "head_sha": sha, "per_page": 100})
endpoint = f"repos/{repository}/actions/workflows/ci.yml/runs?{query}"
result = subprocess.run(["gh", "api", endpoint], check=True, capture_output=True,
text=True, timeout=15)
return successful_run(json.loads(result.stdout), repository, sha)
except (OSError, subprocess.SubprocessError, ValueError, KeyError, TypeError, AttributeError) as error:
# Do not print response bodies or stderr, which may contain credentials.
print(f"::notice::Could not verify merge-queue CI ({type(error).__name__}); running all checks.")
return None


def main():
run = reusable_run(os.environ)
reuse = run is not None
with Path(os.environ["GITHUB_OUTPUT"]).open("a", encoding="utf-8") as output:
output.write(f"reuse={'true' if reuse else 'false'}\n")
if reuse:
print(f"Merge-queue CI run {run} passed this SHA; retaining cache builds and the full tier.")
else:
print("No verified merge-queue CI result for this push; running all checks.")


if __name__ == "__main__":
main()
253 changes: 253 additions & 0 deletions scripts/ci-test-durations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
{
"source_run": 37951515328,
"source_jobs": [
113892063480,
113892063546
],
"unit_seconds": 185.45,
"compile_seconds": 2.0,
"default_seconds": 1.0,
"targets": {
"api_retry_e2e": 2.01,
"api_timeout_e2e": 4.29,
"apply": 10.48,
"binary_fetch_error_classification_e2e": 0.01,
"blob_fetcher_edges_e2e": 2.06,
"child_deadline_guard": 0.25,
"cli": 7.69,
"cli_apply_silent": 0.1,
"cli_argv_non_utf8": 0.0,
"cli_config_fallback": 0.18,
"cli_get_silent": 0.06,
"cli_global_args": 0.36,
"cli_parse_apply": 0.05,
"cli_parse_get": 0.1,
"cli_parse_list": 0.44,
"cli_parse_main": 0.12,
"cli_parse_remove": 0.07,
"cli_parse_repair": 0.06,
"cli_parse_rollback": 0.03,
"cli_parse_scan": 0.4,
"cli_parse_vendor": 0.06,
"cli_parse_vex": 1.06,
"cli_path_flags_validated": 0.52,
"cli_remove_silent": 0.28,
"cli_scan_silent": 0.56,
"cli_sigpipe": 0.0,
"command_module_layering": 0.11,
"contract_gradle_codes": 0.93,
"coverage_fix_apply_silent_mute_exit": 4.05,
"coverage_fix_rollback_ecosystem_scoped_hosted": 0.09,
"coverage_fix_scan_hosted_dryrun_vendored": 1.61,
"coverage_fix_vendor_silent_mute_exit": 7.4,
"covgap_api_blob_fetcher": 4.04,
"covgap_commands_get": 1.81,
"covgap_commands_rollback": 1.86,
"covgap_commands_scan_hosted": 1.46,
"covgap_commands_scan_mod": 1.81,
"covgap_commands_vendor": 3.75,
"covgap_commands_vex": 0.2,
"covgap_crawlers_composer_crawler": 0.01,
"covgap_crawlers_npm_crawler": 0.04,
"covgap_patch_apply": 0.06,
"covgap_update_state": 0.01,
"covgap_utils_socket_cli_config": 0.08,
"crawl_fd_limit_e2e": 0.0,
"crawler_cargo_e2e": 0.06,
"crawler_composer_e2e": 0.11,
"crawler_deno_e2e": 0.04,
"crawler_go_e2e": 0.04,
"crawler_gradle_e2e": 0.17,
"crawler_maven_e2e": 0.07,
"crawler_monorepo_gaps": 0.02,
"crawler_npm_e2e": 1.2,
"crawler_nuget_e2e": 0.07,
"crawler_python_e2e": 1.29,
"crawler_ruby_e2e": 0.85,
"crawlers_empty_paths_e2e": 0.03,
"diff_created_file_e2e": 0.15,
"diff_e2e": 0.01,
"docker_e2e_cargo": 0.0,
"docker_e2e_composer": 0.0,
"docker_e2e_deno": 0.0,
"docker_e2e_gem": 0.0,
"docker_e2e_golang": 0.0,
"docker_e2e_maven": 0.0,
"docker_e2e_npm": 0.0,
"docker_e2e_nuget": 0.0,
"docker_e2e_pypi": 0.0,
"docker_e2e_sbt": 0.0,
"docker_e2e_vendor_composer": 0.0,
"docker_e2e_vendor_gem": 0.0,
"docker_e2e_vendor_maven": 0.0,
"docker_e2e_vendor_nuget": 0.0,
"docker_e2e_vendor_pypi_pm": 0.0,
"e2e_bun_lockb": 1.02,
"e2e_cargo": 0.12,
"e2e_composer": 0.11,
"e2e_composer_version_identity": 0.25,
"e2e_embedded_vex": 0.92,
"e2e_gem": 0.09,
"e2e_golang": 0.12,
"e2e_golang_build": 0.0,
"e2e_golang_hosted_build": 0.0,
"e2e_golang_hosted_state": 0.0,
"e2e_golang_workspace_build": 0.0,
"e2e_gradle_agent_build": 0.36,
"e2e_gradle_discovery_build": 0.46,
"e2e_hosted_production": 0.07,
"e2e_maven": 0.12,
"e2e_npm": 0.01,
"e2e_nuget": 0.12,
"e2e_nuget_dotnet_build": 0.0,
"e2e_pypi": 0.01,
"e2e_pypi_multi_copy": 0.18,
"e2e_redirect_bun_build": 0.04,
"e2e_redirect_cargo_build": 2.95,
"e2e_redirect_cargo_shapes": 7.46,
"e2e_redirect_composer_build": 0.0,
"e2e_redirect_gem_stale_install": 0.01,
"e2e_redirect_gradle_build": 0.28,
"e2e_redirect_maven_build": 0.0,
"e2e_redirect_npm_build": 0.01,
"e2e_redirect_pnpm_build": 0.15,
"e2e_redirect_rush_sim": 0.01,
"e2e_redirect_uv_build": 0.0,
"e2e_redirect_vlt_build": 0.05,
"e2e_redirect_yarn_berry_build": 23.13,
"e2e_redirect_yarn_classic_build": 1.04,
"e2e_safety_cargo_build": 0.13,
"e2e_safety_cow": 0.0,
"e2e_safety_internals": 0.01,
"e2e_safety_lock": 1.08,
"e2e_safety_pnpm": 0.01,
"e2e_safety_vlt": 0.04,
"e2e_safety_yarn_pnp": 0.34,
"e2e_sbt": 1.17,
"e2e_sbt_build": 0.02,
"e2e_sbt_hosted": 0.4,
"e2e_sbt_vendor": 2.83,
"e2e_sbt_vendor_build": 0.03,
"e2e_scala_cli_vendor": 0.13,
"e2e_scan": 0.01,
"e2e_socket_yml_policy": 3.98,
"e2e_vendor_bun_build": 0.03,
"e2e_vendor_cargo_build": 10.85,
"e2e_vendor_composer_build": 0.06,
"e2e_vendor_composer_crlf": 0.31,
"e2e_vendor_gem_build": 0.03,
"e2e_vendor_golang_build": 0.0,
"e2e_vendor_gradle_build": 0.32,
"e2e_vendor_jvm_build": 0.3,
"e2e_vendor_maven_build": 0.04,
"e2e_vendor_npm_build": 15.21,
"e2e_vendor_pnpm_build": 0.5,
"e2e_vendor_pypi_build": 0.0,
"e2e_vendor_vlt_build": 0.05,
"e2e_vendor_yarn_berry_build": 14.67,
"e2e_vendor_yarn_classic_build": 0.03,
"e2e_vendor_yarn_classic_dev_flow": 0.03,
"e2e_vendored_production": 0.07,
"e2e_vex": 1.94,
"e2e_vex_build": 0.0,
"e2e_vex_lockfile": 118.65,
"e2e_vex_redirect": 3.28,
"e2e_vex_vendor": 2.72,
"e2e_vlt": 0.76,
"e2e_yarn4_pnpm_linker_build": 13.72,
"e2e_yarn4_workspaces_build": 9.39,
"e2e_yarn_legacy_cachekey_refusal_build": 3.67,
"ecosystem_dispatch_e2e": 0.48,
"fuzzy_match_e2e": 0.0,
"get": 8.01,
"global_probe_spawn_e2e": 0.24,
"global_scope_project_state": 0.88,
"gradle_agent_cli": 2.27,
"help_text_hygiene": 0.05,
"hosted_inventory": 0.06,
"hosted_memory_engine": 1.47,
"hosted_memory_parity": 1.77,
"hosted_memory_rollout": 0.93,
"hosted_superseding_pypi": 0.26,
"in_process_agent_reapply": 0.51,
"in_process_alternate_installers": 0.19,
"in_process_cargo_apply": 5.85,
"in_process_edge_cases": 0.18,
"in_process_gem_apply": 0.02,
"in_process_gem_multi_platform": 0.65,
"in_process_get": 3.45,
"in_process_get_corrupt_manifest": 0.01,
"in_process_get_hosted_ecosystems": 1.26,
"in_process_get_manifest_path": 0.21,
"in_process_get_modes": 1.29,
"in_process_get_update_count": 0.04,
"in_process_get_uuid_fallback": 0.03,
"in_process_pypi_apply": 25.35,
"in_process_pypi_multi_release": 32.83,
"in_process_python_envs": 1.03,
"in_process_redirect": 11.08,
"in_process_redirect_pdm": 2.46,
"in_process_redirect_pipenv": 2.45,
"in_process_redirect_pnpm": 4.63,
"in_process_redirect_poetry": 1.97,
"in_process_remote_ecosystems_apply": 9.9,
"in_process_remove_repair_lifecycle": 0.8,
"in_process_rollback_all_ecosystems": 0.3,
"in_process_rollback_hosted": 4.88,
"in_process_rollback_vendored": 1.02,
"in_process_scan": 2.94,
"in_process_target_ambiguity": 0.14,
"in_process_vendor": 25.4,
"in_process_vendor_bun_takeover": 3.72,
"in_process_vendor_npm_v1_takeover": 0.57,
"in_process_vendor_pnpm_parent_child": 0.67,
"in_process_vendor_pnpm_takeover": 1.62,
"in_process_vendor_pypi_takeover": 0.34,
"json_error_shape": 0.21,
"maven_sidecar_cli": 0.26,
"mode_migration_bun": 0.04,
"mode_migration_cargo": 3.9,
"mode_migration_npm": 0.03,
"mode_migration_pypi": 6.14,
"mode_migration_vlt": 0.04,
"output_helpers_e2e": 0.0,
"package_e2e": 0.02,
"pnpm_hosted": 0.09,
"poetry_hosted": 0.11,
"policy_pypi_names": 0.26,
"proxy_batch_e2e": 0.47,
"redirect_golden": 0.68,
"redirect_sbt_golden": 0.35,
"remedy_commands_parse": 0.56,
"remove": 2.05,
"remove_rollback_api_overrides": 0.07,
"repair": 10.03,
"rollback": 4.66,
"rollback_new_file_e2e": 0.01,
"scan": 9.08,
"scan_api_retry_e2e": 2.42,
"scan_pnpm_relocated_store_cwd_e2e": 0.07,
"scan_requirements_lock_only": 2.68,
"scan_rollout_e2e": 6.6,
"scan_vendor_e2e": 3.11,
"scan_vendor_requirements_unwired": 0.33,
"self_update_e2e": 7.68,
"self_update_failures_e2e": 8.18,
"spawn_env_hygiene": 0.39,
"telemetry_helpers_e2e": 0.01,
"update": 16.45,
"upstream_restore_golden": 8.1,
"uv_hosted": 0.01,
"vendor": 7.77,
"vendor_crash_safety_e2e": 0.67,
"vendor_eject": 0.35,
"vendor_eject_bun_lockb": 2.2,
"vendor_eject_fresh_checkout": 0.63,
"vendor_group_commit_e2e": 10.18,
"vendor_jvm_cli": 6.72,
"vendor_ledger_schema_e2e": 3.13,
"vendor_partial_staging_e2e": 0.56,
"vex_terminal_output": 0.18,
"vlt_locks": 16.39
}
}
Loading
Loading