QGC Shared Tooling

August 18, 2026 ยท View on GitHub

tools/common/ contains small, dependency-light helpers shared by QGC developer and CI scripts. Import from the module that defines a helper; common/__init__.py intentionally does not re-export symbols. Explicit imports keep runtime and sparse-checkout dependencies visible.

from common.file_traversal import find_repo_root
from common.proc import run_captured

Module Index

ModulePurpose
analyzer.pyAnalyzer result types, base class, and ordered parallel execution
artifact_metadata.pyValidated GitHub Actions artifact name and size interchange
aws.pyAllowlisted public S3 object checks and uploads
build_config.py.github/build-config.json lookup, validation, and CI export
cmake.pyCMake cache variable parsing
cobertura.pyCobertura line and branch coverage metrics
deps.pyExternal-tool checks and project-aware Python package installation
env.pyCI environment detection
errors.pyShared tooling exceptions
file_traversal.pyRepository-root discovery and filtered C++ file traversal
format.pyHuman-readable byte and size-delta formatting
gh_actions.pyGitHub CLI calls, annotations, outputs, environment, and step summaries
git.pyCaptured Git commands and default-branch discovery
github_runs.pyWorkflow-run loading, filtering, and latest-run selection
io.pyJSON/TOML I/O, checksums, atomic writes, and safe archive extraction
logging.pyColor-aware terminal logging
markdown.pyEscaped GitHub-Flavored Markdown tables
net.pyDependency-free downloads and retry policies
opener.pyCross-platform default-application launching
patterns.pyQGC-specific source-analysis regular expressions
platform.pyOS and CPU architecture normalization
proc.pyCaptured text, byte, and tee subprocess execution
tool_version.pyExternal-tool and uv.lock version lookup
xml.pySafe XML parsing with entity-declaration rejection
shell-utils.shShared shell logging for developer scripts

API behavior and edge cases are covered by matching files under tools/tests/, such as test_proc.py, test_io.py, and test_gh_actions.py.

Bootstrapping Imports

Scripts under tools/ must initialize the tools path before importing common:

from _bootstrap import ensure_tools_dir

ensure_tools_dir(__file__)

from common.proc import run_captured

Scripts under .github/scripts/ use the CI shim instead:

from ci_bootstrap import ensure_tools_dir

ensure_tools_dir(__file__)

from common.gh_actions import write_github_output

The import after ensure_tools_dir is intentionally separated and may need # noqa: E402 in files covered by Ruff's import-position rule. Do not manually modify sys.path in new scripts.

CI jobs that use sparse checkout must include the entrypoint, bootstrap shim, and transitive common modules. test_bootstrap_sparse_checkout.py checks that closure automatically.

Adding or Reusing Helpers

Before adding a helper, search this directory and its call sites. Add shared code only when it has multiple consumers or centralizes a correctness boundary such as safe extraction, retries, GitHub output encoding, or platform normalization.

When a new helper is warranted:

  1. Put it in the narrowest existing module; create a module only for a distinct concern.
  2. Keep imports dependency-light and defer optional packages until the function that needs them.
  3. Export the supported surface through the module's __all__ when it has one.
  4. Add focused tests under tools/tests/.
  5. Run pytest -q tools/tests .github/scripts/tests, Ruff, Pyright, and import-linter.
  6. Update sparse-checkout lists if the automatic policy test reports a missing module.

Standalone packages under tools/skills/ are copied and run outside the repository, so their reference scripts must not depend on tools/common/.