Skip to content

adding owlbot and notebook ci #7810

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

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
752b3d8
adding owlbot and notebook ci
Apr 21, 2022
23bd643
add owlbot.lock.yaml
Apr 21, 2022
5b2cd77
rename to .github/.OwlBot.lock.yaml
parthea Apr 22, 2022
3c7c1a5
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] Apr 22, 2022
4bb32ba
Merge branch 'main' into notebook_ci
loferris May 2, 2022
25d76ab
Merge branch 'main' into notebook_ci
loferris May 3, 2022
cb04375
updating sha value
May 3, 2022
635f8bb
Merge branch 'notebook_ci' of github.com:GoogleCloudPlatform/python-d…
May 3, 2022
df2f719
update digest
May 3, 2022
aaf4377
adding headers, rolling back .github updates
May 3, 2022
9cfedf8
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] May 3, 2022
c95d9d8
fixing flake8 errors
May 3, 2022
fe9607e
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] May 3, 2022
7117493
update post processor image in .github/.OwlBot.lock.yaml
parthea May 4, 2022
b751306
Merge branch 'main' into notebook_ci
parthea May 4, 2022
0dc02e9
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] May 4, 2022
425fceb
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] May 4, 2022
827399e
Merge branch 'notebook_ci' of https://github.com/GoogleCloudPlatform/…
gcf-owl-bot[bot] May 4, 2022
1573817
Merge branch 'main' into notebook_ci
loferris Feb 1, 2023
2c5974d
adding headers
Feb 1, 2023
f299196
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] Feb 1, 2023
6d8dbd6
header check fix
Feb 1, 2023
2ff54a1
header fix
Feb 1, 2023
accd246
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] Feb 1, 2023
ef5ee16
header fix
Feb 1, 2023
60a1d45
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] Feb 1, 2023
9dbbc2a
header fix
Feb 2, 2023
1dbb9a1
Merge branch 'main' into notebook_ci
loferris Feb 2, 2023
c3aef6a
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] Feb 2, 2023
7d81dc3
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] Feb 2, 2023
59bac51
Merge branch 'notebook_ci' of https://github.com/GoogleCloudPlatform/…
gcf-owl-bot[bot] Feb 2, 2023
ac97342
Merge branch 'main' into notebook_ci
loferris Feb 3, 2023
9cfa071
Merge branch 'main' into notebook_ci
engelke May 18, 2023
e3cdf79
Merge branch 'main' into notebook_ci
engelke May 18, 2023
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
30 changes: 30 additions & 0 deletions .cloud-build/CheckPythonVersion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env python
# # Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys

MINIMUM_MAJOR_VERSION = 3
MINIMUM_MINOR_VERSION = 5

if (
sys.version_info.major >= MINIMUM_MAJOR_VERSION
or sys.version_info.minor >= MINIMUM_MINOR_VERSION
):
print(f"Python version acceptable: {sys.version}")
exit(0)
else:
print(
f"Error: Python version less than {MINIMUM_MAJOR_VERSION}.{MINIMUM_MINOR_VERSION}"
)
exit(1)
8 changes: 8 additions & 0 deletions .cloud-build/cleanup/cleanup-cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
steps:
# Install Python dependencies and run cleanup script
- name: ${_PYTHON_IMAGE}
entrypoint: /bin/sh
args:
- -c
- 'python3 -m pip install -U -r .cloud-build/cleanup/cleanup-requirements.txt && python3 .cloud-build/cleanup/cleanup.py'
timeout: 86400s
55 changes: 55 additions & 0 deletions .cloud-build/cleanup/cleanup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env python
# # Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import List
from resource_cleanup_manager import (
ResourceCleanupManager,
DatasetResourceCleanupManager,
EndpointResourceCleanupManager,
ModelResourceCleanupManager,
)


def run_cleanup_managers(managers: List[ResourceCleanupManager], is_dry_run: bool):
for manager in managers:
type_name = manager.type_name

print(f"Fetching {type_name}'s...")
resources = manager.list()
print(f"Found {len(resources)} {type_name}'s")
for resource in resources:
if not manager.is_deletable(resource):
continue

if is_dry_run:
resource_name = manager.resource_name(resource)
print(f"Will delete '{type_name}': {resource_name}")
else:
try:
manager.delete(resource)
except Exception as exception:
print(exception)


is_dry_run = False

# List of all cleanup managers
managers = [
DatasetResourceCleanupManager(),
EndpointResourceCleanupManager(),
ModelResourceCleanupManager(),
]

run_cleanup_managers(managers=managers, is_dry_run=is_dry_run)
1 change: 1 addition & 0 deletions .cloud-build/cleanup/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
google-cloud-aiplatform==1.12.1
102 changes: 102 additions & 0 deletions .cloud-build/cleanup/resource_cleanup_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env python
# # Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import abc
from google.cloud import aiplatform
from typing import Any
from proto.datetime_helpers import DatetimeWithNanoseconds
from google.cloud.aiplatform import base

# If a resource was updated within this number of seconds, do not delete.
RESOURCE_UPDATE_BUFFER_IN_SECONDS = 60 * 60 * 8


class ResourceCleanupManager(abc.ABC):
@property
@abc.abstractmethod
def type_name(str) -> str:
pass

@abc.abstractmethod
def list(self) -> Any:
pass

@abc.abstractmethod
def resource_name(self, resource: Any) -> str:
pass

@abc.abstractmethod
def delete(self, resource: Any):
pass

@abc.abstractmethod
def get_seconds_since_modification(self, resource: Any) -> float:
pass

def is_deletable(self, resource: Any) -> bool:
time_difference = self.get_seconds_since_modification(resource)

if self.resource_name(resource).startswith("perm"):
print(f"Skipping '{resource}' due to name starting with 'perm'.")
return False

# Check that it wasn't created too recently, to prevent race conditions
if time_difference <= RESOURCE_UPDATE_BUFFER_IN_SECONDS:
print(
f"Skipping '{resource}' due update_time being '{time_difference}', which is less than '{RESOURCE_UPDATE_BUFFER_IN_SECONDS}'."
)
return False

return True


class VertexAIResourceCleanupManager(ResourceCleanupManager):
@property
@abc.abstractmethod
def vertex_ai_resource(self) -> base.VertexAiResourceNounWithFutureManager:
pass

@property
def type_name(self) -> str:
return self.vertex_ai_resource._resource_noun

def list(self) -> Any:
return self.vertex_ai_resource.list()

def resource_name(self, resource: Any) -> str:
return resource.display_name

def delete(self, resource):
resource.delete()

def get_seconds_since_modification(self, resource: Any) -> bool:
update_time = resource.update_time
current_time = DatetimeWithNanoseconds.now(tz=update_time.tzinfo)
return (current_time - update_time).total_seconds()


class DatasetResourceCleanupManager(VertexAIResourceCleanupManager):
vertex_ai_resource = aiplatform.datasets._Dataset


class EndpointResourceCleanupManager(VertexAIResourceCleanupManager):
vertex_ai_resource = aiplatform.Endpoint

def delete(self, resource):
resource.delete(force=True)


class ModelResourceCleanupManager(VertexAIResourceCleanupManager):
vertex_ai_resource = aiplatform.Model
100 changes: 100 additions & 0 deletions .cloud-build/execute_changed_notebooks_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/usr/bin/env python
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""A CLI to process changed notebooks and execute them on Google Cloud Build"""

import argparse
import pathlib
import execute_changed_notebooks_helper


def str2bool(v):
if isinstance(v, bool):
return v
if v.lower() in ("yes", "true", "t", "y", "1"):
return True
elif v.lower() in ("no", "false", "f", "n", "0"):
return False
else:
raise argparse.ArgumentTypeError("String value expected.")


parser = argparse.ArgumentParser(description="Run changed notebooks.")
parser.add_argument(
"--test_paths_file",
type=pathlib.Path,
help="The path to the file that has newline-limited folders of notebooks that should be tested.",
required=True,
)
parser.add_argument(
"--base_branch",
help="The base git branch to diff against to find changed files.",
required=False,
)
parser.add_argument(
"--container_uri",
type=str,
help="The container uri to run each notebook in.",
required=True,
)
parser.add_argument(
"--variable_project_id",
type=str,
help="The GCP project id. This is used to inject a variable value into the notebook before running.",
required=True,
)
parser.add_argument(
"--variable_region",
type=str,
help="The GCP region. This is used to inject a variable value into the notebook before running.",
required=True,
)
parser.add_argument(
"--staging_bucket",
type=str,
help="The GCS bucket for staging temporary files.",
required=True,
)
parser.add_argument(
"--artifacts_bucket",
type=str,
help="The GCP directory for storing executed notebooks.",
required=True,
)
parser.add_argument(
"--should_parallelize",
type=str2bool,
nargs="?",
const=True,
default=True,
help="Should run notebooks in parallel.",
)

args = parser.parse_args()

notebooks = execute_changed_notebooks_helper.get_changed_notebooks(
test_paths_file=args.test_paths_file,
base_branch=args.base_branch,
)

execute_changed_notebooks_helper.process_and_execute_notebooks(
notebooks=notebooks,
container_uri=args.container_uri,
staging_bucket=args.staging_bucket,
artifacts_bucket=args.artifacts_bucket,
variable_project_id=args.variable_project_id,
variable_region=args.variable_region,
should_parallelize=args.should_parallelize,
)
Loading