Skip to content

feat(cli): use new central Dockerfile locations, add capability to locate airbyte_repo_root, use multi-purpose CONNECTOR positional arg in CLI commands #530

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 7, 2025
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
32 changes: 15 additions & 17 deletions airbyte_cdk/cli/airbyte_cdk/_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,14 @@

import rich_click as click

# from airbyte_cdk.test.standard_tests import pytest_hooks
from airbyte_cdk.cli.airbyte_cdk._util import resolve_connector_name_and_directory
from airbyte_cdk.test.standard_tests.test_resources import find_connector_root_from_name
from airbyte_cdk.test.standard_tests.util import create_connector_test_suite

# from airbyte_cdk.test.standard_tests import pytest_hooks
from airbyte_cdk.utils.connector_paths import (
find_connector_root_from_name,
resolve_connector_name_and_directory,
)

click.rich_click.TEXT_MARKUP = "markdown"

pytest: ModuleType | None
Expand Down Expand Up @@ -98,15 +101,11 @@ def connector_cli_group() -> None:


@connector_cli_group.command()
@click.option(
"--connector-name",
@click.argument(
"connector",
required=False,
type=str,
help="Name of the connector to test. Ignored if --connector-directory is provided.",
)
@click.option(
"--connector-directory",
type=click.Path(exists=True, file_okay=False, path_type=Path),
help="Path to the connector directory.",
metavar="[CONNECTOR]",
)
@click.option(
"--collect-only",
Expand All @@ -115,15 +114,17 @@ def connector_cli_group() -> None:
help="Only collect tests, do not run them.",
)
def test(
connector_name: str | None = None,
connector_directory: Path | None = None,
connector: str | Path | None = None,
*,
collect_only: bool = False,
) -> None:
"""Run connector tests.

This command runs the standard connector tests for a specific connector.

[CONNECTOR] can be a connector name (e.g. 'source-pokeapi'), a path to a connector directory, or omitted to use the current working directory.
If a string containing '/' is provided, it is treated as a path. Otherwise, it is treated as a connector name.

If no connector name or directory is provided, we will look within the current working
directory. If the current working directory is not a connector directory (e.g. starting
with 'source-') and no connector name or path is provided, the process will fail.
Expand All @@ -133,10 +134,7 @@ def test(
"pytest is not installed. Please install pytest to run the connector tests."
)
click.echo("Connector test command executed.")
connector_name, connector_directory = resolve_connector_name_and_directory(
connector_name=connector_name,
connector_directory=connector_directory,
)
connector_name, connector_directory = resolve_connector_name_and_directory(connector)

connector_test_suite = create_connector_test_suite(
connector_name=connector_name if not connector_directory else None,
Expand Down
34 changes: 16 additions & 18 deletions airbyte_cdk/cli/airbyte_cdk/_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

import rich_click as click

from airbyte_cdk.cli.airbyte_cdk._util import resolve_connector_name_and_directory
from airbyte_cdk.models.connector_metadata import MetadataFile
from airbyte_cdk.utils.connector_paths import resolve_connector_name_and_directory
from airbyte_cdk.utils.docker import (
ConnectorImageBuildError,
build_connector_image,
Expand All @@ -28,41 +28,38 @@ def image_cli_group() -> None:


@image_cli_group.command()
@click.option(
"--connector-name",
@click.argument(
"connector",
required=False,
type=str,
help="Name of the connector to test. Ignored if --connector-directory is provided.",
)
@click.option(
"--connector-directory",
type=click.Path(exists=True, file_okay=False, path_type=Path),
help="Path to the connector directory.",
metavar="[CONNECTOR]",
)
@click.option("--tag", default="dev", help="Tag to apply to the built image (default: dev)")
@click.option("--no-verify", is_flag=True, help="Skip verification of the built image")
@click.option(
"--dockerfile",
type=click.Path(exists=True, file_okay=True, path_type=Path),
help="Optional. Override the Dockerfile used for building the image.",
)
def build(
connector_name: str | None = None,
connector_directory: Path | None = None,
connector: str | None = None,
*,
tag: str = "dev",
no_verify: bool = False,
dockerfile: Path | None = None,
) -> None:
"""Build a connector Docker image.

This command builds a Docker image for a connector, using either
the connector's Dockerfile or a base image specified in the metadata.
The image is built for both AMD64 and ARM64 architectures.
[CONNECTOR] can be a connector name (e.g. 'source-pokeapi'), a path to a connector directory, or omitted to use the current working directory.
If a string containing '/' is provided, it is treated as a path. Otherwise, it is treated as a connector name.
"""
if not verify_docker_installation():
click.echo(
"Docker is not installed or not running. Please install Docker and try again.", err=True
)
sys.exit(1)

connector_name, connector_directory = resolve_connector_name_and_directory(
connector_name=connector_name,
connector_directory=connector_directory,
)
connector_name, connector_directory = resolve_connector_name_and_directory(connector)

metadata_file_path: Path = connector_directory / "metadata.yaml"
try:
Expand All @@ -81,6 +78,7 @@ def build(
metadata=metadata,
tag=tag,
no_verify=no_verify,
dockerfile_override=dockerfile or None,
)
except ConnectorImageBuildError as e:
click.echo(
Expand Down
47 changes: 14 additions & 33 deletions airbyte_cdk/cli/airbyte_cdk/_secrets.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
from rich.console import Console
from rich.table import Table

from airbyte_cdk.cli.airbyte_cdk._util import (
from airbyte_cdk.utils.connector_paths import (
resolve_connector_name,
resolve_connector_name_and_directory,
)
Expand Down Expand Up @@ -73,15 +73,11 @@ def secrets_cli_group() -> None:


@secrets_cli_group.command()
@click.option(
"--connector-name",
@click.argument(
"connector",
required=False,
type=str,
help="Name of the connector to fetch secrets for. Ignored if --connector-directory is provided.",
)
@click.option(
"--connector-directory",
type=click.Path(exists=True, file_okay=False, path_type=Path),
help="Path to the connector directory.",
metavar="[CONNECTOR]",
)
@click.option(
"--gcp-project-id",
Expand All @@ -97,8 +93,7 @@ def secrets_cli_group() -> None:
default=False,
)
def fetch(
connector_name: str | None = None,
connector_directory: Path | None = None,
connector: str | Path | None = None,
gcp_project_id: str = AIRBYTE_INTERNAL_GCP_PROJECT,
print_ci_secrets_masks: bool = False,
) -> None:
Expand All @@ -107,24 +102,24 @@ def fetch(
This command fetches secrets for a connector from Google Secret Manager and writes them
to the connector's secrets directory.

[CONNECTOR] can be a connector name (e.g. 'source-pokeapi'), a path to a connector directory, or omitted to use the current working directory.
If a string containing '/' is provided, it is treated as a path. Otherwise, it is treated as a connector name.

If no connector name or directory is provided, we will look within the current working
directory. If the current working directory is not a connector directory (e.g. starting
with 'source-') and no connector name or path is provided, the process will fail.

The `--print-ci-secrets-masks` option will print the GitHub CI mask for the secrets.
This is useful for masking secrets in CI logs.

WARNING: This action causes the secrets to be printed in clear text to `STDOUT`. For security
reasons, this function will only execute if the `CI` environment variable is set. Otherwise,
masks will not be printed.
WARNING: The `--print-ci-secrets-masks` option causes the secrets to be printed in clear text to
`STDOUT`. For security reasons, this argument will be ignored if the `CI` environment
variable is not set.
"""
click.echo("Fetching secrets...", err=True)

client = _get_gsm_secrets_client()
connector_name, connector_directory = resolve_connector_name_and_directory(
connector_name=connector_name,
connector_directory=connector_directory,
)
connector_name, connector_directory = resolve_connector_name_and_directory(connector)
secrets_dir = _get_secrets_dir(
connector_directory=connector_directory,
connector_name=connector_name,
Expand Down Expand Up @@ -289,21 +284,7 @@ def _get_secrets_dir(
connector_name: str,
ensure_exists: bool = True,
) -> Path:
try:
connector_name, connector_directory = resolve_connector_name_and_directory(
connector_name=connector_name,
connector_directory=connector_directory,
)
except FileNotFoundError as e:
raise FileNotFoundError(
f"Could not find connector directory for '{connector_name}'. "
"Please provide the --connector-directory option with the path to the connector. "
"Note: This command requires either running from within a connector directory, "
"being in the airbyte monorepo, or explicitly providing the connector directory path."
) from e
except ValueError as e:
raise ValueError(str(e))

_ = connector_name # Unused, but it may be used in the future for logging
secrets_dir = connector_directory / "secrets"
if ensure_exists:
secrets_dir.mkdir(parents=True, exist_ok=True)
Expand Down
69 changes: 0 additions & 69 deletions airbyte_cdk/cli/airbyte_cdk/_util.py

This file was deleted.

2 changes: 1 addition & 1 deletion airbyte_cdk/test/standard_tests/connector_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from airbyte_cdk.test.standard_tests.models import (
ConnectorTestScenario,
)
from airbyte_cdk.test.standard_tests.test_resources import (
from airbyte_cdk.utils.connector_paths import (
ACCEPTANCE_TEST_CONFIG,
find_connector_root,
)
Expand Down
2 changes: 1 addition & 1 deletion airbyte_cdk/test/standard_tests/declarative_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from airbyte_cdk.test.standard_tests._job_runner import IConnector
from airbyte_cdk.test.standard_tests.models import ConnectorTestScenario
from airbyte_cdk.test.standard_tests.source_base import SourceTestSuiteBase
from airbyte_cdk.test.standard_tests.test_resources import MANIFEST_YAML
from airbyte_cdk.utils.connector_paths import MANIFEST_YAML


def md5_checksum(file_path: Path) -> str:
Expand Down
69 changes: 0 additions & 69 deletions airbyte_cdk/test/standard_tests/test_resources.py

This file was deleted.

Loading
Loading