-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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] implement pre/post build hooks #30526
[airbyte-ci] implement pre/post build hooks #30526
Conversation
db634ba
to
8e3804a
Compare
Current dependencies on/for this PR:
This comment was auto-generated by Graphite. |
Before Merging a Connector Pull RequestWow! What a great pull request you have here! 🎉 To merge this PR, ensure the following has been done/considered for each connector added or updated:
If the checklist is complete, but the CI check is failing,
|
73377ba
to
25f394d
Compare
8e3804a
to
82971ce
Compare
PATH_TO_INTEGRATION_CODE = "/airbyte/integration_code" | ||
|
||
@staticmethod | ||
def get_main_file_name(build_customization_module: Optional[ModuleType]) -> str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💅 A docstring here would be lovely!
@@ -76,29 +89,58 @@ async def _provision_builder_container(self, base_container: Container) -> Conta | |||
|
|||
return builder.with_exec(["pip", "install", "--prefix=/install", "."]) | |||
|
|||
def _get_build_customization_module(self) -> Optional[ModuleType]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ We will be doing this for java connectors correct? If so lets move this to a more generic location
async def _build_from_base_image(self) -> Container: | ||
"""Build the connector container using the base image defined in the metadata, in the connectorBuildOptions.baseImage field. | ||
|
||
Returns: | ||
Container: The connector container built from the base image. | ||
""" | ||
base = self._get_base_container() | ||
build_customization_module = self._get_build_customization_module() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Im thinking hooks related functions like _get_build_customization_module
, and calls to pre_connector_install
should move to a folder/file named something like build_hooks
or build_lifecycle
e.g.
# pipelines/builds/hooks/_init__.py
def get_build_customization_module(connector: Connector) -> Optional[ModuleType]:
# ...
def pre_install_hook(connector: Connector, container: Container) -> Container
build_customization_module = get_build_customization_module(connector)
if hasattr(build_customization_module, "pre_connector_install"):
self.logger.info("Adding the pre_connector_install hook to the base")
container = await build_customization_module.pre_connector_install(container)
return container
def post_install_hook(connector: Connector, container: Container) -> Container
build_customization_module = get_build_customization_module(connector)
if hasattr(build_customization_module, "post_connector_install"):
self.logger.info("Adding the post_connector_install hook to the base")
container = await build_customization_module.post_connector_install(container)
return container
It would also give us a focused spot to document the connector lifecycle in a README.md
file
- what hooks are available?
- what do they do?
- how do you use them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion, will do.
25f394d
to
5cc21b3
Compare
f09dfd8
to
0ec7047
Compare
276f1b0
to
404346d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! I agree with ben about pulling the build lifecycle into a separate place so its visible, great suggestion. No blocking comments from me :)
PATH_TO_INTEGRATION_CODE = "/airbyte/integration_code" | ||
|
||
@staticmethod | ||
def get_main_file_name(build_customization_module: Optional[ModuleType]) -> str: | ||
if build_customization_module is not None and hasattr(build_customization_module, "MAIN_FILE_NAME"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have any validation that an existing build_customization.py
will define this constant? if not we might end up with a None
here
@@ -31,9 +33,17 @@ def test_context_with_connector_without_base_image(self, test_context): | |||
def connector_with_base_image(self, all_connectors): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def connector_with_base_image(self, all_connectors): | |
def connector_with_base_image_no_customization(self, all_connectors): |
or something of the sort?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or it might be worth having both of these as separate fixtures. E.g. if I add something to the base image and want to assert that all connectors (regardless of customization) have it, I might want this. If I am changing some behavior that build customization might affect, I want to get the list of non-customized connectors?
pytest.skip("No connector with a connectorBuildOptions.baseImage metadata found") | ||
|
||
@pytest.fixture | ||
def connector_with_base_image_with_build_customization(self, connector_with_base_image): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ seeing that our other fixture uses real connectors, in the future would we potentially change this to return all (real) connectors with build customizations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes why not! It will slow down the test but add coverage.
In any case I think we shall make an automation that will require a review from our team if a connector is implementing a build_customization module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds like a good idea! At least for the foreseeable future, while we work out any kinks and there are few examples to work off of
dummy_build_customization = (Path(__file__).parent / "dummy_build_customization.py").read_text() | ||
(connector_with_base_image.code_directory / "build_customization.py").write_text(dummy_build_customization) | ||
yield connector_with_base_image | ||
(connector_with_base_image.code_directory / "build_customization.py").unlink() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious. what does unlink()
do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It removes the file. Basically a rm
96068a5
to
18693fc
Compare
27bc360
to
62fe3cb
Compare
62fe3cb
to
a728afd
Compare
a728afd
to
fcecb62
Compare
source-zendesk-chat test report (commit
|
Step | Result |
---|---|
Build source-zendesk-chat docker image for platform(s) linux/x86_64 | ✅ |
Unit tests | ✅ |
Acceptance tests | ✅ |
Code format checks | ✅ |
Validate metadata for source-zendesk-chat | ✅ |
Connector version semver check | ✅ |
Connector version increment check | ✅ |
QA checks | ✅ |
☁️ View runs for commit in Dagger Cloud
Please note that tests are only run on PR ready for review. Please set your PR to draft mode to not flood the CI engine and upstream service on following commits.
You can run the same pipeline locally on this branch with the airbyte-ci tool with the following command
airbyte-ci connectors --name=source-zendesk-chat test
This reverts commit 950ff92.
What
Closes #30237
In some scenario a connector might have to customize our default build process: to install a system dependency, a system env var.
To do so we want to expose a pre/post build hook mechanism that connector developers can leverage.
How
build_customization.py
module in the connector code directorypre_connector_install
and/orpost_connector_install
function. They'll mutate the container object of this stage in this function.pre_connector_install
is executed on top of our base image,post_connector_install
is executed after the rest of all the build instructions.