airbyte_ops_mcp.cli.gh

CLI commands for GitHub operations.

Commands:

airbyte-ops gh workflow status - Check GitHub Actions workflow status airbyte-ops gh workflow trigger - Trigger a GitHub Actions CI workflow

CLI reference

The commands below are regenerated by poe docs-generate via cyclopts's programmatic docs API; see docs/generate_cli.py.

airbyte-ops gh COMMAND

GitHub operations.

Commands:

  • workflow: GitHub Actions workflow operations.

airbyte-ops gh workflow

GitHub Actions workflow operations.

airbyte-ops gh workflow status

airbyte-ops gh workflow status [ARGS]

Check the status of a GitHub Actions workflow run.

Provide either --url OR all of (--owner, --repo, --run-id).

Parameters:

  • URL, --url: Full GitHub Actions workflow run URL (e.g., 'https://github.com/owner/repo/actions/runs/12345').
  • OWNER, --owner: Repository owner (e.g., 'airbytehq').
  • REPO, --repo: Repository name (e.g., 'airbyte').
  • RUN-ID, --run-id: Workflow run ID.

airbyte-ops gh workflow trigger

airbyte-ops gh workflow trigger OWNER REPO WORKFLOW-FILE [ARGS]

Trigger a GitHub Actions CI workflow via workflow_dispatch.

This command triggers a workflow in any GitHub repository that has workflow_dispatch enabled. It resolves PR numbers to branch names automatically.

Parameters:

  • OWNER, --owner: Repository owner (e.g., 'airbytehq'). [required]
  • REPO, --repo: Repository name (e.g., 'airbyte'). [required]
  • WORKFLOW-FILE, --workflow-file: Workflow file name (e.g., 'connector-regression-test.yml'). [required]
  • WORKFLOW-DEFINITION-REF, --workflow-definition-ref: Branch name or PR number for the workflow definition to use. If a PR number is provided, it resolves to the PR's head branch name. Defaults to 'main' if not specified.
  • INPUTS, --inputs: Workflow inputs as a JSON string (e.g., '{"key": "value"}').
  • WAIT, --wait, --no-wait: Wait for the workflow to complete before returning. [default: False]
  • WAIT-SECONDS, --wait-seconds: Maximum seconds to wait for workflow completion (default: 600). [default: 600]
  1# Copyright (c) 2025 Airbyte, Inc., all rights reserved.
  2"""CLI commands for GitHub operations.
  3
  4Commands:
  5    airbyte-ops gh workflow status - Check GitHub Actions workflow status
  6    airbyte-ops gh workflow trigger - Trigger a GitHub Actions CI workflow
  7
  8## CLI reference
  9
 10The commands below are regenerated by `poe docs-generate` via cyclopts's
 11programmatic docs API; see `docs/generate_cli.py`.
 12
 13.. include:: ../../../docs/generated/cli/gh.md
 14   :start-line: 2
 15"""
 16
 17from __future__ import annotations
 18
 19# Hide Python-level members from the pdoc page for this module; the rendered
 20# docs for this CLI group come entirely from the grafted `.. include::` in
 21# the module docstring above.
 22__all__: list[str] = []
 23
 24import json
 25import time
 26from typing import Annotated
 27
 28from cyclopts import Parameter
 29
 30from airbyte_ops_mcp.cli._base import App, app
 31from airbyte_ops_mcp.cli._shared import exit_with_error, print_json
 32from airbyte_ops_mcp.mcp.github_actions import (
 33    check_ci_workflow_status,
 34    trigger_ci_workflow,
 35)
 36
 37# Create the gh sub-app
 38gh_app = App(name="gh", help="GitHub operations.")
 39app.command(gh_app)
 40
 41# Create the workflow sub-app under gh
 42workflow_app = App(name="workflow", help="GitHub Actions workflow operations.")
 43gh_app.command(workflow_app)
 44
 45
 46@workflow_app.command(name="status")
 47def workflow_status(
 48    url: Annotated[
 49        str | None,
 50        Parameter(
 51            help="Full GitHub Actions workflow run URL "
 52            "(e.g., 'https://github.com/owner/repo/actions/runs/12345')."
 53        ),
 54    ] = None,
 55    owner: Annotated[
 56        str | None,
 57        Parameter(help="Repository owner (e.g., 'airbytehq')."),
 58    ] = None,
 59    repo: Annotated[
 60        str | None,
 61        Parameter(help="Repository name (e.g., 'airbyte')."),
 62    ] = None,
 63    run_id: Annotated[
 64        int | None,
 65        Parameter(help="Workflow run ID."),
 66    ] = None,
 67) -> None:
 68    """Check the status of a GitHub Actions workflow run.
 69
 70    Provide either --url OR all of (--owner, --repo, --run-id).
 71    """
 72    # Validate input parameters
 73    if url:
 74        if owner or repo or run_id:
 75            exit_with_error(
 76                "Cannot specify --url together with --owner/--repo/--run-id. "
 77                "Use either --url OR the component parts."
 78            )
 79    elif not (owner and repo and run_id):
 80        exit_with_error(
 81            "Must provide either --url OR all of (--owner, --repo, --run-id)."
 82        )
 83
 84    result = check_ci_workflow_status(
 85        workflow_url=url,
 86        owner=owner,
 87        repo=repo,
 88        run_id=run_id,
 89    )
 90    print_json(result.model_dump())
 91
 92
 93@workflow_app.command(name="trigger")
 94def workflow_trigger(
 95    owner: Annotated[
 96        str,
 97        Parameter(help="Repository owner (e.g., 'airbytehq')."),
 98    ],
 99    repo: Annotated[
100        str,
101        Parameter(help="Repository name (e.g., 'airbyte')."),
102    ],
103    workflow_file: Annotated[
104        str,
105        Parameter(help="Workflow file name (e.g., 'connector-regression-test.yml')."),
106    ],
107    workflow_definition_ref: Annotated[
108        str | None,
109        Parameter(
110            help="Branch name or PR number for the workflow definition to use. "
111            "If a PR number is provided, it resolves to the PR's head branch name. "
112            "Defaults to 'main' if not specified."
113        ),
114    ] = None,
115    inputs: Annotated[
116        str | None,
117        Parameter(
118            help='Workflow inputs as a JSON string (e.g., \'{"key": "value"}\').'
119        ),
120    ] = None,
121    wait: Annotated[
122        bool,
123        Parameter(help="Wait for the workflow to complete before returning."),
124    ] = False,
125    wait_seconds: Annotated[
126        int,
127        Parameter(
128            help="Maximum seconds to wait for workflow completion (default: 600)."
129        ),
130    ] = 600,
131) -> None:
132    """Trigger a GitHub Actions CI workflow via workflow_dispatch.
133
134    This command triggers a workflow in any GitHub repository that has workflow_dispatch
135    enabled. It resolves PR numbers to branch names automatically.
136    """
137    # Parse inputs JSON if provided
138    parsed_inputs: dict[str, str] | None = None
139    if inputs:
140        try:
141            parsed_inputs = json.loads(inputs)
142        except json.JSONDecodeError as e:
143            exit_with_error(f"Invalid JSON for --inputs: {e}")
144
145    # Trigger the workflow
146    result = trigger_ci_workflow(
147        owner=owner,
148        repo=repo,
149        workflow_file=workflow_file,
150        workflow_definition_ref=workflow_definition_ref,
151        inputs=parsed_inputs,
152    )
153
154    print_json(result.model_dump())
155
156    # If wait is enabled and we have a run_id, poll for completion
157    if wait and result.run_id:
158        print(f"\nWaiting for workflow to complete (timeout: {wait_seconds}s)...")
159        start_time = time.time()
160        poll_interval = 10  # seconds
161
162        while time.time() - start_time < wait_seconds:
163            status_result = check_ci_workflow_status(
164                owner=owner,
165                repo=repo,
166                run_id=result.run_id,
167            )
168
169            if status_result.status == "completed":
170                print(
171                    f"\nWorkflow completed with conclusion: {status_result.conclusion}"
172                )
173                print_json(status_result.model_dump())
174                return
175
176            elapsed = int(time.time() - start_time)
177            print(f"  Status: {status_result.status} (elapsed: {elapsed}s)")
178            time.sleep(poll_interval)
179
180        print(f"\nTimeout reached after {wait_seconds}s. Workflow still running.")
181        # Print final status
182        final_status = check_ci_workflow_status(
183            owner=owner,
184            repo=repo,
185            run_id=result.run_id,
186        )
187        print_json(final_status.model_dump())