Skip to content
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

airbyte-ci,gradle: replace airbyte-docker with airbyte-ci #30743

Merged
merged 12 commits into from
Oct 4, 2023
Merged
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'application'
id 'airbyte-docker'
id 'airbyte-docker-legacy'
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'application'
id 'airbyte-docker'
id 'airbyte-docker-legacy'
id 'airbyte-integration-test-java'
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'application'
id 'airbyte-docker'
id 'airbyte-docker-legacy'
id 'airbyte-integration-test-java'
id "java-library"
// https://docs.gradle.org/current/userguide/java_testing.html#sec:java_test_fixtures
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ buildscript {

plugins {
id 'application'
id 'airbyte-docker'
id 'airbyte-docker-legacy'
}

import org.jsoup.Jsoup;
Expand Down
1 change: 0 additions & 1 deletion airbyte-cdk/java/airbyte-cdk/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
allprojects {
apply plugin: 'java-library'
apply plugin: 'maven-publish'
apply plugin: 'airbyte-docker'
apply plugin: 'airbyte-java-cdk'
apply plugin: 'airbyte-integration-test-java'
apply plugin: 'airbyte-performance-test-java'
Expand Down
2 changes: 1 addition & 1 deletion airbyte-cdk/python/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'airbyte-python'
id 'airbyte-docker'
id 'airbyte-docker-legacy'
postamar marked this conversation as resolved.
Show resolved Hide resolved
}

def generateComponentManifestClassFiles = tasks.register('generateComponentManifestClassFiles', Exec) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from pathlib import Path
from typing import Iterable, Optional, Set, Tuple

from connector_ops.utils import Connector
from connector_ops.utils import Connector, ConnectorLanguage
from pydash.objects import get


Expand Down Expand Up @@ -235,7 +235,11 @@ def check_connector_has_no_critical_vulnerabilities(connector: Connector) -> boo


def check_metadata_version_matches_dockerfile_label(connector: Connector) -> bool:
return connector.version_in_dockerfile_label == connector.version
version_in_dockerfile = connector.version_in_dockerfile_label
postamar marked this conversation as resolved.
Show resolved Hide resolved
if version_in_dockerfile is None:
# Java connectors don't have Dockerfiles.
return connector.language == ConnectorLanguage.JAVA
return version_in_dockerfile == connector.version


QA_CHECKS = [
Expand Down
21 changes: 10 additions & 11 deletions airbyte-ci/connectors/connector_ops/connector_ops/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,12 +314,8 @@ def language(self) -> ConnectorLanguage:
return ConnectorLanguage.LOW_CODE
if Path(self.code_directory / "setup.py").is_file() or Path(self.code_directory / "pyproject.toml").is_file():
return ConnectorLanguage.PYTHON
try:
with open(self.code_directory / "Dockerfile") as dockerfile:
if "FROM airbyte/integration-base-java" in dockerfile.read():
return ConnectorLanguage.JAVA
except FileNotFoundError:
pass
if Path(self.code_directory / "src" / "main" / "java").exists():
return ConnectorLanguage.JAVA
return None

@property
Expand All @@ -329,11 +325,14 @@ def version(self) -> str:
return self.metadata["dockerImageTag"]

@property
def version_in_dockerfile_label(self) -> str:
with open(self.code_directory / "Dockerfile") as f:
for line in f:
if "io.airbyte.version" in line:
return line.split("=")[1].strip()
def version_in_dockerfile_label(self) -> Optional[str]:
try:
with open(self.code_directory / "Dockerfile") as f:
for line in f:
if "io.airbyte.version" in line:
return line.split("=")[1].strip()
except FileNotFoundError as e:
return None
raise ConnectorVersionNotFound(
"""
Could not find the connector version from its Dockerfile.
Expand Down
10 changes: 10 additions & 0 deletions airbyte-ci/connectors/connector_ops/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion airbyte-ci/connectors/connector_ops/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "connector_ops"
version = "0.2.3"
version = "0.2.4"
description = "Packaged maintained by the connector operations team to perform CI for connectors"
authors = ["Airbyte <contact@airbyte.io>"]

Expand Down
4 changes: 3 additions & 1 deletion airbyte-ci/connectors/pipelines/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ This command runs the Python tests for a airbyte-ci poetry package.
## Changelog
| Version | PR | Description |
|---------| --------------------------------------------------------- |-----------------------------------------------------------------------------------------------------------|
| 1.4.3 | [#30743](https://github.com/airbytehq/airbyte/pull/30743) | Add `--disable-report-auto-open` and `--use-host-gradle-dist-tar` to allow gradle integration. |
| 1.4.2 | [#30595](https://github.com/airbytehq/airbyte/pull/30595) | Remove directory name requirement |
| 1.4.1 | [#30595](https://github.com/airbytehq/airbyte/pull/30595) | Load base migration guide into QA Test container for strict encrypt variants |
| 1.4.0 | [#30330](https://github.com/airbytehq/airbyte/pull/30330) | Add support for pyproject.toml as the prefered entry point for a connector package |
Expand Down Expand Up @@ -414,4 +415,5 @@ This command runs the Python tests for a airbyte-ci poetry package.

## More info
This project is owned by the Connectors Operations team.
We share project updates and remaining stories before its release to production in this [EPIC](https://github.com/airbytehq/airbyte/issues/24403).
We share project updates and remaining stories before its release to production in this [EPIC](https://github.com/airbytehq/airbyte/issues/24403).

5 changes: 3 additions & 2 deletions airbyte-ci/connectors/pipelines/pipelines/bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -624,8 +624,9 @@ async def save(self) -> None:
absolute_path = await local_html_path.resolve()
if self.pipeline_context.is_local:
self.pipeline_context.logger.info(f"HTML report saved locally: {absolute_path}")
self.pipeline_context.logger.info("Opening HTML report in browser.")
webbrowser.open(absolute_path.as_uri())
if self.pipeline_context.open_report_in_browser:
self.pipeline_context.logger.info("Opening HTML report in browser.")
webbrowser.open(absolute_path.as_uri())
if self.remote_storage_enabled:
await self.save_remote(local_html_path, self.html_report_remote_storage_key, "text/html")
self.pipeline_context.logger.info(f"HTML report uploaded to {self.html_report_url}")
Expand Down
13 changes: 5 additions & 8 deletions airbyte-ci/connectors/pipelines/pipelines/builds/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@

import anyio
from connector_ops.utils import ConnectorLanguage
from dagger import Platform
from pipelines.bases import ConnectorReport, StepResult
from pipelines.builds import common, java_connectors, python_connectors
from pipelines.builds import java_connectors, python_connectors
from pipelines.builds.common import LoadContainerToLocalDockerHost, StepStatus
from pipelines.consts import LOCAL_BUILD_PLATFORM
from pipelines.contexts import ConnectorContext


Expand All @@ -25,9 +26,6 @@ class NoBuildStepForLanguageError(Exception):
ConnectorLanguage.JAVA: java_connectors.run_connector_build,
}

BUILD_PLATFORMS = [Platform("linux/amd64"), Platform("linux/arm64")]
LOCAL_BUILD_PLATFORM = Platform(f"linux/{platform.machine()}")


async def run_connector_build(context: ConnectorContext) -> StepResult:
"""Run a build pipeline for a single connector."""
Expand All @@ -50,9 +48,8 @@ async def run_connector_build_pipeline(context: ConnectorContext, semaphore: any
async with context:
build_result = await run_connector_build(context)
step_results.append(build_result)
if context.is_local and build_result.status is common.StepStatus.SUCCESS:
connector_to_load_to_local_docker_host = build_result.output_artifact[LOCAL_BUILD_PLATFORM]
load_image_result = await common.LoadContainerToLocalDockerHost(context, connector_to_load_to_local_docker_host).run()
if context.is_local and build_result.status is StepStatus.SUCCESS:
load_image_result = await LoadContainerToLocalDockerHost(context, LOCAL_BUILD_PLATFORM, build_result.output_artifact).run()
step_results.append(load_image_result)
context.report = ConnectorReport(context, step_results, name="BUILD RESULTS")
return context.report
62 changes: 41 additions & 21 deletions airbyte-ci/connectors/pipelines/pipelines/builds/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,71 @@
#

from abc import ABC
from typing import Tuple
from typing import List, Tuple

import docker
from dagger import Container, Platform
from dagger import Container, ExecError, Platform, QueryError
from pipelines.bases import Step, StepResult, StepStatus
from pipelines.consts import BUILD_PLATFORMS
from pipelines.contexts import ConnectorContext
from pipelines.utils import export_container_to_tarball


class BuildConnectorImageBase(Step, ABC):
class BuildConnectorImagesBase(Step, ABC):
"""
A step to build connector images for a set of platforms.
"""

@property
def title(self):
return f"Build {self.context.connector.technical_name} docker image for platform {self.build_platform}"
plural = "" if len(self.build_platforms) == 1 else "s"
return f"Build {self.context.connector.technical_name} docker image{plural} for platform{plural} {', '.join(self.build_platforms)}"

def __init__(self, context: ConnectorContext, build_platform: Platform) -> None:
self.build_platform = build_platform
def __init__(self, context: ConnectorContext, *build_platforms: List[Platform]) -> None:
self.build_platforms = build_platforms if build_platforms else BUILD_PLATFORMS
super().__init__(context)

async def _run(self, *args) -> StepResult:
build_results_per_platform = {}
for platform in self.build_platforms:
try:
connector = await self._build_connector(platform, *args)
try:
await connector.with_exec(["spec"])
except ExecError:
return StepResult(
self, StepStatus.FAILURE, stderr=f"Failed to run spec on the connector built for platform {platform}."
)
build_results_per_platform[platform] = connector
except QueryError as e:
return StepResult(self, StepStatus.FAILURE, stderr=f"Failed to build connector image for platform {platform}: {e}")
plural = "" if len(self.build_platforms) == 1 else "s"
postamar marked this conversation as resolved.
Show resolved Hide resolved
success_message = (
f"The {self.context.connector.technical_name} docker image{plural} "
f"were successfully built for platform{plural} {', '.join(self.build_platforms)}"
)
return StepResult(self, StepStatus.SUCCESS, stdout=success_message, output_artifact=build_results_per_platform)

class BuildConnectorImageForAllPlatformsBase(Step, ABC):

ALL_PLATFORMS = BUILD_PLATFORMS

title = f"Build connector image for {BUILD_PLATFORMS}"
async def _build_connector(self, platform: Platform, *args) -> Container:
"""Implement the generation of the image for the platform and return the corresponding container.

def get_success_result(self, build_results_per_platform: dict[Platform, Container]) -> StepResult:
return StepResult(
self,
StepStatus.SUCCESS,
stdout="The connector image was successfully built for all platforms.",
output_artifact=build_results_per_platform,
)
Returns:
Container: The container to package as a docker image for this platform.
"""
raise NotImplementedError("`BuildConnectorImagesBase`s must define a '_build_connector' attribute.")


class LoadContainerToLocalDockerHost(Step):
IMAGE_TAG = "dev"

def __init__(self, context: ConnectorContext, container: Container) -> None:
def __init__(self, context: ConnectorContext, platform: Platform, containers: dict[Platform, Container]) -> None:
super().__init__(context)
self.container = container
self.platform = platform
self.container = containers[platform]

@property
def title(self):
return f"Load {self.image_name}:{self.IMAGE_TAG} to the local docker host."
return f"Load {self.image_name}:{self.IMAGE_TAG} for platform {self.platform} to the local docker host."

@property
def image_name(self) -> Tuple:
Expand Down
Loading
Loading