From 304208b99872f18e1e88d20bea6b702f4d06d502 Mon Sep 17 00:00:00 2001
From: Ben Church <ben@airbyte.io>
Date: Wed, 18 Oct 2023 18:26:50 -0700
Subject: [PATCH] Airbyte-ci: Allow airbyte-ci to run from anywhere in project
 (#31412)

---
 airbyte-ci/connectors/pipelines/README.md     |  1 +
 .../pipelines/pipelines/cli/airbyte_ci.py     | 54 +++++++++++++++++++
 .../pipelines/pipelines/cli/dagger_run.py     |  2 +
 .../connectors/pipelines/pyproject.toml       |  2 +-
 4 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/airbyte-ci/connectors/pipelines/README.md b/airbyte-ci/connectors/pipelines/README.md
index 8385d60810631..ab2b5a15d8fe5 100644
--- a/airbyte-ci/connectors/pipelines/README.md
+++ b/airbyte-ci/connectors/pipelines/README.md
@@ -398,6 +398,7 @@ This command runs the Python tests for a airbyte-ci poetry package.
 ## Changelog
 | Version | PR                                                         | Description                                                                                               |
 |---------| ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
+| 2.1.0   | [#31412](https://github.com/airbytehq/airbyte/pull/31412)  | Run airbyte-ci from any where in airbyte project                                                          |
 | 2.0.4   | [#31487](https://github.com/airbytehq/airbyte/pull/31487)  | Allow for third party connector selections                                                                |
 | 2.0.3   | [#31525](https://github.com/airbytehq/airbyte/pull/31525)  | Refactor folder structure                                                                                 |
 | 2.0.2   | [#31533](https://github.com/airbytehq/airbyte/pull/31533)  | Pip cache volume by python version.                                                                       |
diff --git a/airbyte-ci/connectors/pipelines/pipelines/cli/airbyte_ci.py b/airbyte-ci/connectors/pipelines/pipelines/cli/airbyte_ci.py
index ce6f9d48d209f..90f59e5030208 100644
--- a/airbyte-ci/connectors/pipelines/pipelines/cli/airbyte_ci.py
+++ b/airbyte-ci/connectors/pipelines/pipelines/cli/airbyte_ci.py
@@ -5,9 +5,13 @@
 """This module is the CLI entrypoint to the airbyte-ci commands."""
 
 import importlib
+import logging
+import os
+from pathlib import Path
 from typing import List
 
 import click
+import git
 from github import PullRequest
 from pipelines import main_logger
 from pipelines.airbyte_ci.connectors.commands import connectors
@@ -61,6 +65,55 @@ def get_latest_version() -> str:
     raise Exception("Could not find version in pyproject.toml. Please ensure you are running from the root of the airbyte repo.")
 
 
+def _validate_airbyte_repo(repo: git.Repo) -> bool:
+    """Check if any of the remotes are the airbyte repo."""
+    expected_repo_name = "airbytehq/airbyte"
+    for remote in repo.remotes:
+        if expected_repo_name in remote.url:
+            return True
+
+    warning_message = f"""
+    ⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
+
+    It looks like you are not running this command from the airbyte repo ({expected_repo_name}).
+
+    If this command is run from outside the airbyte repo, it will not work properly.
+
+    Please run this command your local airbyte project.
+
+    ⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
+    """
+
+    logging.warning(warning_message)
+
+    return False
+
+
+def get_airbyte_repo() -> git.Repo:
+    """Get the airbyte repo."""
+    repo = git.Repo(search_parent_directories=True)
+    _validate_airbyte_repo(repo)
+    return repo
+
+
+def get_airbyte_repo_path_with_fallback() -> Path:
+    """Get the path to the airbyte repo."""
+    try:
+        return get_airbyte_repo().working_tree_dir
+    except git.exc.InvalidGitRepositoryError:
+        logging.warning("Could not find the airbyte repo, falling back to the current working directory.")
+        path = Path.cwd()
+        logging.warning(f"Using {path} as the airbyte repo path.")
+        return path
+
+
+def set_working_directory_to_root() -> None:
+    """Set the working directory to the root of the airbyte repo."""
+    working_dir = get_airbyte_repo_path_with_fallback()
+    logging.info(f"Setting working directory to {working_dir}")
+    os.chdir(working_dir)
+
+
 def get_modified_files(
     git_branch: str, git_revision: str, diffed_branch: str, is_local: bool, ci_context: CIContext, pull_request: PullRequest
 ) -> List[str]:
@@ -178,6 +231,7 @@ def airbyte_ci(
 airbyte_ci.add_command(connectors)
 airbyte_ci.add_command(metadata)
 airbyte_ci.add_command(test)
+set_working_directory_to_root()
 
 if __name__ == "__main__":
     airbyte_ci()
diff --git a/airbyte-ci/connectors/pipelines/pipelines/cli/dagger_run.py b/airbyte-ci/connectors/pipelines/pipelines/cli/dagger_run.py
index b1ab352896f8b..7c3ee1c12ff2b 100644
--- a/airbyte-ci/connectors/pipelines/pipelines/cli/dagger_run.py
+++ b/airbyte-ci/connectors/pipelines/pipelines/cli/dagger_run.py
@@ -14,6 +14,7 @@
 
 import pkg_resources
 import requests
+from pipelines.cli.airbyte_ci import set_working_directory_to_root
 
 LOGGER = logging.getLogger(__name__)
 BIN_DIR = Path.home() / "bin"
@@ -89,6 +90,7 @@ def check_dagger_cli_install() -> str:
 
 
 def main():
+    set_working_directory_to_root()
     os.environ[DAGGER_CLOUD_TOKEN_ENV_VAR_NAME_VALUE[0]] = DAGGER_CLOUD_TOKEN_ENV_VAR_NAME_VALUE[1]
     exit_code = 0
     if len(sys.argv) > 1 and any([arg in ARGS_DISABLING_TUI for arg in sys.argv]):
diff --git a/airbyte-ci/connectors/pipelines/pyproject.toml b/airbyte-ci/connectors/pipelines/pyproject.toml
index 6ec93a83309b3..d5db42aa0720b 100644
--- a/airbyte-ci/connectors/pipelines/pyproject.toml
+++ b/airbyte-ci/connectors/pipelines/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
 
 [tool.poetry]
 name = "pipelines"
-version = "2.0.4"
+version = "2.1.0"
 description = "Packaged maintained by the connector operations team to perform CI for connectors' pipelines"
 authors = ["Airbyte <contact@airbyte.io>"]