From 6db379dedf94607277037de92ed76c584f8d167e Mon Sep 17 00:00:00 2001 From: Ben Church Date: Wed, 29 May 2024 08:50:27 -0700 Subject: [PATCH] feat(qa-checks): Add AcceptanceTestsEnabledCheck (#38736) Co-authored-by: alafanechere --- airbyte-ci/connectors/connector_ops/README.md | 2 +- .../connector_ops/connector_ops/utils.py | 33 ++++- .../connectors/connector_ops/pyproject.toml | 2 +- airbyte-ci/connectors/connectors_qa/README.md | 4 + .../connectors/connectors_qa/poetry.lock | 2 +- .../connectors/connectors_qa/pyproject.toml | 2 +- .../src/connectors_qa/checks/__init__.py | 2 + .../src/connectors_qa/checks/testing.py | 40 ++++++ .../connectors_qa/src/connectors_qa/models.py | 15 +++ .../connectors_qa/templates/qa_checks.md.j2 | 1 + .../unit_tests/test_checks/test_testing.py | 119 ++++++++++++++++++ .../resources/qa-checks.md | 28 +++++ 12 files changed, 245 insertions(+), 5 deletions(-) create mode 100644 airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/testing.py create mode 100644 airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_testing.py diff --git a/airbyte-ci/connectors/connector_ops/README.md b/airbyte-ci/connectors/connector_ops/README.md index 6de6139b7256f..a9b183a0a877f 100644 --- a/airbyte-ci/connectors/connector_ops/README.md +++ b/airbyte-ci/connectors/connector_ops/README.md @@ -37,5 +37,5 @@ poetry run pytest ``` ## Changelog - +- 0.5.0: Added `cloud_usage` property to `Connector` class. - 0.4.0: Removed acceptance test configuration and allowed hosts checks as they're not used. diff --git a/airbyte-ci/connectors/connector_ops/connector_ops/utils.py b/airbyte-ci/connectors/connector_ops/connector_ops/utils.py index c1c20b4899944..330cdf4150ece 100644 --- a/airbyte-ci/connectors/connector_ops/connector_ops/utils.py +++ b/airbyte-ci/connectors/connector_ops/connector_ops/utils.py @@ -16,6 +16,7 @@ import requests import yaml from ci_credentials import SecretsManager +from pydash.collections import find from pydash.objects import get from rich.console import Console from simpleeval import simple_eval @@ -24,6 +25,7 @@ DIFFED_BRANCH = os.environ.get("DIFFED_BRANCH", "origin/master") OSS_CATALOG_URL = "https://connectors.airbyte.com/files/registries/v0/oss_registry.json" +CLOUD_CATALOG_URL = "https://connectors.airbyte.com/files/registries/v0/cloud_registry.json" BASE_AIRBYTE_DOCS_URL = "https://docs.airbyte.com" CONNECTOR_PATH_PREFIX = "airbyte-integrations/connectors" SOURCE_CONNECTOR_PATH_PREFIX = CONNECTOR_PATH_PREFIX + "/source-" @@ -563,6 +565,17 @@ def normalization_tag(self) -> Optional[str]: def is_using_poetry(self) -> bool: return Path(self.code_directory / "pyproject.toml").exists() + @property + def registry_primary_key_field(self) -> str: + """ + The primary key field of the connector in the registry. + + example: + - source -> sourceDefinitionId + - destination -> destinationDefinitionId + """ + return f"{self.connector_type}DefinitionId" + @property def is_released(self) -> bool: """Pull the the OSS registry and check if it the current definition ID and docker image tag are in the registry. @@ -576,12 +589,30 @@ def is_released(self) -> bool: registry = download_catalog(OSS_CATALOG_URL) for connector in registry[f"{self.connector_type}s"]: if ( - connector[f"{self.connector_type}DefinitionId"] == metadata["definitionId"] + connector[self.registry_primary_key_field] == metadata["definitionId"] and connector["dockerImageTag"] == metadata["dockerImageTag"] ): return True return False + @property + def cloud_usage(self) -> Optional[str]: + """Pull the cloud registry, check if the connector is in the registry and return the usage metrics. + + Returns: + Optional[str]: The usage metrics of the connector, could be one of ["low", "medium", "high"] or None if the connector is not in the registry. + """ + metadata = self.metadata + definition_id = metadata.get("definitionId") + cloud_registry = download_catalog(CLOUD_CATALOG_URL) + + all_connectors_of_type = cloud_registry[f"{self.connector_type}s"] + connector_entry = find(all_connectors_of_type, {self.registry_primary_key_field: definition_id}) + if not connector_entry: + return None + + return get(connector_entry, "generated.metrics.cloud.usage") + def get_secret_manager(self, gsm_credentials: str): return SecretsManager(connector_name=self.technical_name, gsm_credentials=gsm_credentials) diff --git a/airbyte-ci/connectors/connector_ops/pyproject.toml b/airbyte-ci/connectors/connector_ops/pyproject.toml index 45277370a3aeb..5ab0b67a08e96 100644 --- a/airbyte-ci/connectors/connector_ops/pyproject.toml +++ b/airbyte-ci/connectors/connector_ops/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "connector_ops" -version = "0.4.0" +version = "0.5.0" description = "Packaged maintained by the connector operations team to perform CI for connectors" authors = ["Airbyte "] diff --git a/airbyte-ci/connectors/connectors_qa/README.md b/airbyte-ci/connectors/connectors_qa/README.md index 93f1651b835c5..f0e855d0659d9 100644 --- a/airbyte-ci/connectors/connectors_qa/README.md +++ b/airbyte-ci/connectors/connectors_qa/README.md @@ -108,6 +108,10 @@ poe lint ## Changelog +### 1.4.0 + +Added the `IntegrationTestsEnabledCheck` check that verifies if the integration tests are enabled for connectors with higher cloud usage. + ### 1.3.2 Removed documentation checks in `MedatadaCheck` since it's already verified in `DocumentationCheck`. diff --git a/airbyte-ci/connectors/connectors_qa/poetry.lock b/airbyte-ci/connectors/connectors_qa/poetry.lock index 63ccab13f98f5..97181532bfcf6 100644 --- a/airbyte-ci/connectors/connectors_qa/poetry.lock +++ b/airbyte-ci/connectors/connectors_qa/poetry.lock @@ -444,7 +444,7 @@ url = "../common_utils" [[package]] name = "connector-ops" -version = "0.3.4" +version = "0.5.0" description = "Packaged maintained by the connector operations team to perform CI for connectors" optional = false python-versions = "^3.10" diff --git a/airbyte-ci/connectors/connectors_qa/pyproject.toml b/airbyte-ci/connectors/connectors_qa/pyproject.toml index df2daf8f36f94..27ccd0eda762d 100644 --- a/airbyte-ci/connectors/connectors_qa/pyproject.toml +++ b/airbyte-ci/connectors/connectors_qa/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "connectors-qa" -version = "1.3.2" +version = "1.4.0" description = "A package to run QA checks on Airbyte connectors, generate reports and documentation." authors = ["Airbyte "] readme = "README.md" diff --git a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/__init__.py b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/__init__.py index a89490af1b962..a879dccf5a130 100644 --- a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/__init__.py +++ b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/__init__.py @@ -4,6 +4,7 @@ from .metadata import ENABLED_CHECKS as METADATA_CORRECTNESS_CHECKS from .packaging import ENABLED_CHECKS as PACKAGING_CHECKS from .security import ENABLED_CHECKS as SECURITY_CHECKS +from .testing import ENABLED_CHECKS as TESTING_CHECKS ENABLED_CHECKS = ( DOCUMENTATION_CHECKS @@ -11,4 +12,5 @@ + PACKAGING_CHECKS + ASSETS_CHECKS + SECURITY_CHECKS + + TESTING_CHECKS ) diff --git a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/testing.py b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/testing.py new file mode 100644 index 0000000000000..fb70e431fd915 --- /dev/null +++ b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/testing.py @@ -0,0 +1,40 @@ +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. + + +from connector_ops.utils import Connector # type: ignore +from connectors_qa.models import Check, CheckCategory, CheckResult +from pydash.collections import find # type: ignore + + +class TestingCheck(Check): + category = CheckCategory.TESTING + + +class AcceptanceTestsEnabledCheck(TestingCheck): + applies_to_connector_cloud_usage = ["medium", "high"] + applies_to_connector_types = ["source"] + name = "Medium to High Use Connectors must enable acceptance tests" + description = "Medium to High Use Connectors must enable acceptance tests via the `connectorTestSuitesOptions.suite:acceptanceTests` in their respective metadata.yaml file to ensure that the connector is working as expected." + test_suite_name = "acceptanceTests" + + def does_not_have_acceptance_tests_enabled(self, connector: Connector) -> bool: + metadata = connector.metadata + connector_test_suites_options = metadata.get("connectorTestSuitesOptions", []) + acceptance_tests_suite = find(connector_test_suites_options, {"suite": self.test_suite_name}) + return bool(acceptance_tests_suite) is False + + def _run(self, connector: Connector) -> CheckResult: + if self.does_not_have_acceptance_tests_enabled(connector): + return self.create_check_result( + connector=connector, + passed=False, + message=f"The {self.test_suite_name} test suite must be enabled for medium/high use connectors. Please enable this test suite in the connectorTestSuitesOptions field of the metadata.yaml file.", + ) + return self.create_check_result( + connector=connector, + passed=True, + message=f"{connector.cloud_usage} cloud usage connector has enabled {self.test_suite_name}.", + ) + + +ENABLED_CHECKS = [AcceptanceTestsEnabledCheck()] diff --git a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/models.py b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/models.py index c6e075a7b413d..58fd7a487a201 100644 --- a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/models.py +++ b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/models.py @@ -30,6 +30,7 @@ class CheckCategory(Enum): ASSETS = "๐Ÿ’ผ Assets" SECURITY = "๐Ÿ”’ Security" METADATA = "๐Ÿ“ Metadata" + TESTING = "๐Ÿงช Testing" class CheckStatus(Enum): @@ -144,6 +145,15 @@ def applies_to_connector_support_levels(self) -> Optional[List[str]]: """ return None + @property + def applies_to_connector_cloud_usage(self) -> Optional[List[str]]: + """The connector's cloud usage level that the QA check applies to + + Returns: + List[str]: None if connector's cloud usage levels that the QA check applies to is not specified + """ + return None + def run(self, connector: Connector) -> CheckResult: if not self.runs_on_released_connectors and connector.is_released: return self.skip( @@ -172,6 +182,11 @@ def run(self, connector: Connector) -> CheckResult: connector, f"Check does not apply to {connector.support_level} connectors", ) + if self.applies_to_connector_cloud_usage and connector.cloud_usage not in self.applies_to_connector_cloud_usage: + return self.skip( + connector, + f"Check does not apply to {connector.cloud_usage} connectors", + ) return self._run(connector) def _run(self, connector: Connector) -> CheckResult: diff --git a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/templates/qa_checks.md.j2 b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/templates/qa_checks.md.j2 index a8ee6255f3922..7c3849cff988e 100644 --- a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/templates/qa_checks.md.j2 +++ b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/templates/qa_checks.md.j2 @@ -13,6 +13,7 @@ They are by no mean replacing the need for a manual review of the connector code _Applies to the following connector types: {{ ', '.join(check.applies_to_connector_types) }}_ _Applies to the following connector languages: {{ ', '.join(check.applies_to_connector_languages) }}_ _Applies to connector with {{ ', '.join(check.applies_to_connector_support_levels) if check.applies_to_connector_support_levels else 'any' }} support level_ +_Applies to connector with {{ ', '.join(check.applies_to_connector_cloud_usage) if check.applies_to_connector_cloud_usage else 'any' }} Airbyte usage level_ {{ check.description }} {% endfor %} diff --git a/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_testing.py b/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_testing.py new file mode 100644 index 0000000000000..d2b62d1aa4cd3 --- /dev/null +++ b/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_testing.py @@ -0,0 +1,119 @@ +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. + +import pytest +from connector_ops.utils import ConnectorLanguage +from connectors_qa.checks import testing +from connectors_qa.models import CheckStatus + +METADATA_CASE_NO_TEST_SUITE_OPTIONS = { + "foo": "bar", +} + +METADATA_CASE_EMPTY_TEST_SUITE_OPTIONS = { + "connectorTestSuitesOptions": [], +} + +METADATA_CASE_NONE_TEST_SUITE_OPTIONS = { + "connectorTestSuitesOptions": None, +} + +METADATA_CASE_MISSING_ACCEPTANCE_TEST_SUITE_OPTIONS = { + "connectorTestSuitesOptions": [ + { + "suite": "unit", + "testSecrets": {}, + }, + ], +} + +METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS_NO_SECRETS = { + "connectorTestSuitesOptions": [ + { + "suite": testing.AcceptanceTestsEnabledCheck.test_suite_name, + }, + ], +} + +METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS_EMPTY_SECRETS = { + "connectorTestSuitesOptions": [ + { + "suite": testing.AcceptanceTestsEnabledCheck.test_suite_name, + "testSecrets": {}, + }, + ], +} + +METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS_NONE_SECRETS = { + "connectorTestSuitesOptions": [ + { + "suite": testing.AcceptanceTestsEnabledCheck.test_suite_name, + "testSecrets": None, + }, + ], +} + +METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS = { + "connectorTestSuitesOptions": [ + { + "suite": testing.AcceptanceTestsEnabledCheck.test_suite_name, + "testSecrets": { + "testSecret": "test" + }, + }, + { + "suite": "unit", + "testSecrets": {}, + }, + ], +} + +THRESHOLD_USAGE_VALUES = ["high", "medium"] +OTHER_USAGE_VALUES = ["low", "none", "unknown", None, ""] + +DYNAMIC_ACCEPTANCE_TESTS_ENABLED_CASES = [ + METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS, + METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS_NONE_SECRETS, + METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS_EMPTY_SECRETS, + METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS_NO_SECRETS, +] + +DYNAMIC_ACCEPTANCE_TESTS_DISABLED_CASES = [ + METADATA_CASE_NO_TEST_SUITE_OPTIONS, + METADATA_CASE_EMPTY_TEST_SUITE_OPTIONS, + METADATA_CASE_NONE_TEST_SUITE_OPTIONS, + METADATA_CASE_MISSING_ACCEPTANCE_TEST_SUITE_OPTIONS, +] + + +class TestAcceptanceTestsEnabledCheck: + @pytest.mark.parametrize( + "cases_to_test, usage_values_to_test, expected_result", + [ + ( + DYNAMIC_ACCEPTANCE_TESTS_DISABLED_CASES + DYNAMIC_ACCEPTANCE_TESTS_ENABLED_CASES, + OTHER_USAGE_VALUES, + CheckStatus.SKIPPED + ), + ( + DYNAMIC_ACCEPTANCE_TESTS_ENABLED_CASES, + THRESHOLD_USAGE_VALUES, + CheckStatus.PASSED + ), + ( + DYNAMIC_ACCEPTANCE_TESTS_DISABLED_CASES, + THRESHOLD_USAGE_VALUES, + CheckStatus.FAILED + ) + ], + ) + def test_check_always_passes_when_usage_threshold_is_not_met(self, mocker, cases_to_test, usage_values_to_test, expected_result): + for usage_value in usage_values_to_test: + for metadata_case in cases_to_test: + # Arrange + connector = mocker.MagicMock(cloud_usage=usage_value, metadata=metadata_case, language=ConnectorLanguage.PYTHON, connector_type="source") + + # Act + result = testing.AcceptanceTestsEnabledCheck().run(connector) + + # Assert + assert result.status == expected_result, f"Usage value: {usage_value}, metadata case: {metadata_case}, expected result: {expected_result}" diff --git a/docs/contributing-to-airbyte/resources/qa-checks.md b/docs/contributing-to-airbyte/resources/qa-checks.md index 67ae33e7abdb3..4276e43b7245d 100644 --- a/docs/contributing-to-airbyte/resources/qa-checks.md +++ b/docs/contributing-to-airbyte/resources/qa-checks.md @@ -13,6 +13,7 @@ They are by no mean replacing the need for a manual review of the connector code _Applies to the following connector types: source, destination_ _Applies to the following connector languages: java, low-code, python_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ When a breaking change is introduced, we check that a migration guide is available. It should be stored under `./docs/integrations/s/-migrations.md`. This document should contain a section for each breaking change, in order of the version descending. It must explain users which action to take to migrate to the new version. @@ -22,6 +23,7 @@ This document should contain a section for each breaking change, in order of the _Applies to the following connector types: source, destination_ _Applies to the following connector languages: java, low-code, python_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ The user facing connector documentation should be stored under `./docs/integrations/s/.md`. @@ -30,6 +32,7 @@ The user facing connector documentation should be stored under `./docs/integrati _Applies to the following connector types: source, destination_ _Applies to the following connector languages: java, low-code, python_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ Each new version of a connector must have a changelog entry defined in the user facing documentation in `./docs/integrations/s/.md`. @@ -40,6 +43,7 @@ Each new version of a connector must have a changelog entry defined in the user _Applies to the following connector types: source, destination_ _Applies to the following connector languages: java, low-code, python_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ Connectors must have a `metadata.yaml` file at the root of their directory. This file is used to build our connector registry. Its structure must follow our metadata schema. Field values are also validated. This is to ensure that all connectors have the required metadata fields and that the metadata is valid. More details in this [documentation](https://docs.airbyte.com/connector-development/connector-metadata-file). @@ -48,6 +52,7 @@ Connectors must have a `metadata.yaml` file at the root of their directory. This _Applies to the following connector types: source, destination_ _Applies to the following connector languages: java, low-code, python_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ Connectors must have a language tag in their metadata. It must be set in the `tags` field in metadata.yaml. The values can be `language:python` or `language:java`. This checks infers the correct language tag based on the presence of certain files in the connector directory. @@ -56,6 +61,7 @@ Connectors must have a language tag in their metadata. It must be set in the `ta _Applies to the following connector types: source, destination_ _Applies to the following connector languages: python, low-code_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ Python connectors must have a CDK tag in their metadata. It must be set in the `tags` field in metadata.yaml. The values can be `cdk:low-code`, `cdk:python`, or `cdk:file`. @@ -64,6 +70,7 @@ Python connectors must have a CDK tag in their metadata. It must be set in the ` _Applies to the following connector types: source, destination_ _Applies to the following connector languages: java, low-code, python_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ If the connector version has a breaking change, the deadline field must be set to at least a week in the future. @@ -72,6 +79,7 @@ If the connector version has a breaking change, the deadline field must be set t _Applies to the following connector types: source_ _Applies to the following connector languages: java, low-code, python_ _Applies to connector with certified support level_ +_Applies to connector with any Airbyte usage level_ Certified source connectors must have a value filled out for `maxSecondsBetweenMessages` in metadata. This value represents the maximum number of seconds we could expect between messages for API connectors. And it's used by platform to tune connectors heartbeat timeout. The value must be set in the 'data' field in connector's `metadata.yaml` file. @@ -82,6 +90,7 @@ Certified source connectors must have a value filled out for `maxSecondsBetweenM _Applies to the following connector types: source, destination_ _Applies to the following connector languages: python, low-code_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ Connectors must use [Poetry](https://python-poetry.org/) for dependency management. This is to ensure that all connectors use a dependency management tool which locks dependencies and ensures reproducible installs. @@ -90,6 +99,7 @@ Connectors must use [Poetry](https://python-poetry.org/) for dependency manageme _Applies to the following connector types: source, destination_ _Applies to the following connector languages: java, low-code, python_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ Connectors must be licensed under the MIT or Elv2 license. This is to ensure that all connectors are licensed under a permissive license. More details in our [License FAQ](https://docs.airbyte.com/developer-guides/licenses/license-faq). @@ -98,6 +108,7 @@ Connectors must be licensed under the MIT or Elv2 license. This is to ensure tha _Applies to the following connector types: source, destination_ _Applies to the following connector languages: python, low-code_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ Connectors license in metadata.yaml and pyproject.toml file must match. This is to ensure that all connectors are consistently licensed. @@ -106,6 +117,7 @@ Connectors license in metadata.yaml and pyproject.toml file must match. This is _Applies to the following connector types: source, destination_ _Applies to the following connector languages: java, low-code, python_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ Connector version must follow the Semantic Versioning scheme. This is to ensure that all connectors follow a consistent versioning scheme. Refer to our [Semantic Versioning for Connectors](https://docs.airbyte.com/contributing-to-airbyte/#semantic-versioning-for-connectors) for more details. @@ -114,6 +126,7 @@ Connector version must follow the Semantic Versioning scheme. This is to ensure _Applies to the following connector types: source, destination_ _Applies to the following connector languages: python, low-code_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ Connector version in metadata.yaml and pyproject.toml file must match. This is to ensure that connector release is consistent. @@ -122,6 +135,7 @@ Connector version in metadata.yaml and pyproject.toml file must match. This is t _Applies to the following connector types: source_ _Applies to the following connector languages: python, low-code_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ Python connectors must have [PyPi](https://pypi.org/) publishing enabled in their `metadata.yaml` file. This is declared by setting `remoteRegistries.pypi.enabled` to `true` in metadata.yaml. This is to ensure that all connectors can be published to PyPi and can be used in `PyAirbyte`. @@ -132,6 +146,7 @@ Python connectors must have [PyPi](https://pypi.org/) publishing enabled in thei _Applies to the following connector types: source, destination_ _Applies to the following connector languages: java, low-code, python_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ Each connector must have an icon available in at the root of the connector code directory. It must be an SVG file named `icon.svg` and must be a square. @@ -142,6 +157,7 @@ Each connector must have an icon available in at the root of the connector code _Applies to the following connector types: source, destination_ _Applies to the following connector languages: java, low-code, python_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ Connectors must use HTTPS only when making requests to external services. @@ -150,6 +166,18 @@ Connectors must use HTTPS only when making requests to external services. _Applies to the following connector types: source, destination_ _Applies to the following connector languages: python, low-code_ _Applies to connector with any support level_ +_Applies to connector with any Airbyte usage level_ Connectors must use our Python connector base image (`docker.io/airbyte/python-connector-base`), declared through the `connectorBuildOptions.baseImage` in their `metadata.yaml`. This is to ensure that all connectors use a base image which is maintained and has security updates. + +## ๐Ÿงช Testing + +### Medium to High Use Connectors must enable acceptance tests + +_Applies to the following connector types: source_ +_Applies to the following connector languages: java, low-code, python_ +_Applies to connector with any support level_ +_Applies to connector with medium, high Airbyte usage level_ + +Medium to High Use Connectors must enable acceptance tests via the `connectorTestSuitesOptions.suite:acceptanceTests` in their respective metadata.yaml file to ensure that the connector is working as expected.