Skip to content

feat: GitHub Actions semantic extraction — workflows, jobs, steps, uses/needs edges #450

Description

@ilyabrykau-orca

What problem does this solve?

CI/CD defined in .github/ is effectively invisible to the graph. When a repo's .github/workflows/*.yml is not .cbmignored, CBM does index it — but only via the generic grammar_yaml.c path, which emits one top-level-key Variable node per file (e.g. a jobs node). No jobs, steps, action references, or job-dependency edges exist.

Concrete misses on real repos:

  • No CI impact analysis. "What breaks if I change this composite action / rename this reusable workflow / remove this secret?" is unanswerable — no edges from a calling workflow to the action/workflow it uses:.
  • No reusable-workflow graph. uses: ./.github/workflows/_test.yml (this repo does exactly this: _build.yml, _lint.yml, _test.yml, _security.yml are called as reusable workflows) produces no cross-file edge.
  • No job DAG. needs: [build, lint] ordering is dropped, so deploy-gating logic is untraceable.
  • Composite/local actions (.github/actions/**/action.yml) aren't modeled as callable units.

Evidence: on an indexed repo, .github/workflows/terraform.yaml yields exactly one node — jobs (label Variable) — and nothing else.

Proposed solution

Add a dedicated GHA extractor mirroring the existing K8s/Kustomize path (internal/cbm/extract_k8s.c, shipped for #86):

  1. New CBM_LANG_GHA in lang_specs.{c,h}, detected by path:
    • **/.github/workflows/*.{yml,yaml} -> workflow
    • **/.github/actions/**/action.{yml,yaml} and repo-root action.{yml,yaml} -> action definition
  2. New internal/cbm/extract_gha.c, dispatched from cbm.c alongside the existing if (lang == K8S || KUSTOMIZE) cbm_extract_k8s() (~line 595). Reuse the vendored YAML tree-sitter grammar and extract_k8s.c's get_scalar_text / flow_node-unwrap helpers.
  3. Nodes: Workflow (per file) -> Job (per jobs.<id>) -> Step (per steps[]).
  4. Edges:
    • uses: ./.github/workflows/x.yml -> IMPORTS/CALLS to the local reusable Workflow (cross-file).
    • uses: owner/repo/...@ref -> external action node (mirrors existing external-dep representation).
    • uses: ./.github/actions/foo -> edge to local composite-action node.
    • needs: [a, b] -> Job->Job dependency edge.
    • optional: secrets: / with: inputs as Fields for config tracing.

Public OSS test beds (rich reusable workflows + composite actions):

  • cli/cli — many workflows + composite actions.
  • grafana/grafana — heavy reusable-workflow (uses: ./.github/workflows/...).
  • actions/checkout — canonical action.yml (node action).
  • home-assistant/core — large job DAGs with needs:.
  • DeusData/codebase-memory-mcp (this repo) — _build/_lint/_test/_security/_smoke/_soak.yml reusable-workflow pattern.

Alternatives considered

  • Generic YAML only (status quo): loses all structure; a workflow = one opaque Variable. No CI impact analysis.
  • Treat uses: as a string via search_code: grep-findable but no edges, so trace_path/impact queries can't traverse CI.
  • External GHA linters (actionlint): validate syntax, do not populate a cross-file/cross-repo code graph.

Confirmations

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestparsing/qualityGraph extraction bugs, false positives, missing edgespriority/normalStandard review queue; useful PR with ordinary maintainer urgency.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions