Spaces:
Build error
Build error
basic commands
Browse files- src/gradio_space_ci/webhook.py +60 -10
src/gradio_space_ci/webhook.py
CHANGED
|
@@ -28,6 +28,9 @@ from huggingface_hub import (
|
|
| 28 |
snapshot_download,
|
| 29 |
space_info,
|
| 30 |
upload_folder,
|
|
|
|
|
|
|
|
|
|
| 31 |
)
|
| 32 |
from huggingface_hub.repocard import RepoCard
|
| 33 |
from huggingface_hub.utils import (
|
|
@@ -248,16 +251,7 @@ async def trigger_ci_on_pr(payload: WebhookPayload, task_queue: BackgroundTasks)
|
|
| 248 |
|
| 249 |
pr_num = payload.discussion.num
|
| 250 |
details = get_discussion_details(repo_id=space_id, repo_type="space", discussion_num=pr_num)
|
| 251 |
-
event_author = details.events[-1]._event["author"]["name"]
|
| 252 |
-
if (
|
| 253 |
-
# Means comment by a trusted author
|
| 254 |
-
payload.event.scope == "discussion.comment"
|
| 255 |
-
and payload.event.action == "create"
|
| 256 |
-
and payload.discussion.isPullRequest
|
| 257 |
-
and payload.discussion.status == "open"
|
| 258 |
-
and event_author in EPHEMERAL_SPACES_CONFIG["trusted_authors"]
|
| 259 |
-
):
|
| 260 |
-
print("Comment detected with content:\n ", payload.comment.content)
|
| 261 |
|
| 262 |
if (
|
| 263 |
# Means "a new PR has been opened"
|
|
@@ -295,8 +289,28 @@ async def trigger_ci_on_pr(payload: WebhookPayload, task_queue: BackgroundTasks)
|
|
| 295 |
if discussion.is_pull_request and discussion.status == "open":
|
| 296 |
if not is_pr_synced(space_id=space_id, pr_num=discussion.num):
|
| 297 |
# Found a PR that is not yet synced
|
|
|
|
|
|
|
|
|
|
| 298 |
task_queue.add_task(sync_ci_space, space_id=space_id, pr_num=discussion.num)
|
| 299 |
has_task = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 300 |
|
| 301 |
if has_task:
|
| 302 |
return Response("Task scheduled to sync/delete Space", status_code=status.HTTP_202_ACCEPTED)
|
|
@@ -463,6 +477,42 @@ def _get_ci_space_id(space_id: str, pr_num: int) -> str:
|
|
| 463 |
return f"{space_id}-ci-pr-{pr_num}"
|
| 464 |
|
| 465 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 466 |
NOTIFICATION_TEMPLATE_CREATED_AND_CONFIGURED = """\
|
| 467 |
Following the creation of this PR, an ephemeral Space [{ci_space_id}](https://huggingface.co/spaces/{ci_space_id}) has been started. Any changes pushed to this PR will be synced with the test Space.
|
| 468 |
Since this PR has been created by a trusted author, the ephemeral Space has been configured with the correct hardware, storage, and secrets.
|
|
|
|
| 28 |
snapshot_download,
|
| 29 |
space_info,
|
| 30 |
upload_folder,
|
| 31 |
+
delete_space_secret,
|
| 32 |
+
delete_space_variable,
|
| 33 |
+
delete_space_storage
|
| 34 |
)
|
| 35 |
from huggingface_hub.repocard import RepoCard
|
| 36 |
from huggingface_hub.utils import (
|
|
|
|
| 251 |
|
| 252 |
pr_num = payload.discussion.num
|
| 253 |
details = get_discussion_details(repo_id=space_id, repo_type="space", discussion_num=pr_num)
|
| 254 |
+
event_author = details.events[-1]._event["author"]["name"] # username of that event
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
|
| 256 |
if (
|
| 257 |
# Means "a new PR has been opened"
|
|
|
|
| 289 |
if discussion.is_pull_request and discussion.status == "open":
|
| 290 |
if not is_pr_synced(space_id=space_id, pr_num=discussion.num):
|
| 291 |
# Found a PR that is not yet synced
|
| 292 |
+
if event_author not in EPHEMERAL_SPACES_CONFIG["trusted_authors"] :
|
| 293 |
+
# if change by untrusted author unset config
|
| 294 |
+
unset_config(space_id=space_id,pr_num=pr_num)
|
| 295 |
task_queue.add_task(sync_ci_space, space_id=space_id, pr_num=discussion.num)
|
| 296 |
has_task = True
|
| 297 |
+
if (
|
| 298 |
+
# Means comment by a trusted author
|
| 299 |
+
payload.event.scope == "discussion.comment"
|
| 300 |
+
and payload.event.action == "create"
|
| 301 |
+
and payload.discussion.isPullRequest
|
| 302 |
+
and payload.discussion.status == "open"
|
| 303 |
+
and event_author in EPHEMERAL_SPACES_CONFIG["trusted_authors"]
|
| 304 |
+
):
|
| 305 |
+
print("Comment detected with content:\n", payload.comment.content)
|
| 306 |
+
if payload.comment.content == "/trust_pr":
|
| 307 |
+
print("trusting pr ...")
|
| 308 |
+
set_config(space_id=space_id,pr_num=pr_num)
|
| 309 |
+
print("pr has been trusted")
|
| 310 |
+
elif payload.comment.content == "/untrust_pr":
|
| 311 |
+
print("untrusting pr ...")
|
| 312 |
+
unset_config(space_id=space_id,pr_num=pr_num)
|
| 313 |
+
print("pr has been untrusted")
|
| 314 |
|
| 315 |
if has_task:
|
| 316 |
return Response("Task scheduled to sync/delete Space", status_code=status.HTTP_202_ACCEPTED)
|
|
|
|
| 477 |
return f"{space_id}-ci-pr-{pr_num}"
|
| 478 |
|
| 479 |
|
| 480 |
+
def set_config(space_id: str, pr_num: str) -> None:
|
| 481 |
+
"""a function to set the ephemerial space config"""
|
| 482 |
+
variables: Dict[str, str] = EPHEMERAL_SPACES_CONFIG["variables"]
|
| 483 |
+
secrets: Dict[str, str] = EPHEMERAL_SPACES_CONFIG["secrets"]
|
| 484 |
+
hardware: Optional[SpaceHardware] = EPHEMERAL_SPACES_CONFIG["hardware"]
|
| 485 |
+
storage: Optional[SpaceHardware] = EPHEMERAL_SPACES_CONFIG["storage"]
|
| 486 |
+
ci_space_id = _get_ci_space_id(space_id=space_id, pr_num=pr_num)
|
| 487 |
+
# Configure space
|
| 488 |
+
for key, value in variables.items():
|
| 489 |
+
add_space_variable(ci_space_id, key, value)
|
| 490 |
+
for key, value in secrets.items():
|
| 491 |
+
add_space_secret(ci_space_id, key, value)
|
| 492 |
+
|
| 493 |
+
# Request hardware/storage for space
|
| 494 |
+
if hardware is not None and hardware != SpaceHardware.CPU_BASIC:
|
| 495 |
+
request_space_hardware(ci_space_id, hardware, sleep_time=5 * 60) # sleep after 5min on PR Spaces with GPU
|
| 496 |
+
if storage is not None:
|
| 497 |
+
request_space_storage(ci_space_id, storage)
|
| 498 |
+
|
| 499 |
+
|
| 500 |
+
def unset_config(space_id: str, pr_num: int) -> None:
|
| 501 |
+
"a function to unset the configuration of an ephemeral space"
|
| 502 |
+
ci_space_id = _get_ci_space_id(space_id=space_id, pr_num=pr_num)
|
| 503 |
+
variables: Dict[str, str] = EPHEMERAL_SPACES_CONFIG["variables"]
|
| 504 |
+
secrets: Dict[str, str] = EPHEMERAL_SPACES_CONFIG["secrets"]
|
| 505 |
+
# Unset space variables and secrets
|
| 506 |
+
for key in variables.keys():
|
| 507 |
+
delete_space_variable(ci_space_id, key)
|
| 508 |
+
for key in secrets.keys():
|
| 509 |
+
delete_space_secret(ci_space_id, key)
|
| 510 |
+
# Reset hardware
|
| 511 |
+
request_space_hardware(ci_space_id,SpaceHardware.CPU_BASIC)
|
| 512 |
+
delete_space_storage(ci_space_id)
|
| 513 |
+
|
| 514 |
+
|
| 515 |
+
|
| 516 |
NOTIFICATION_TEMPLATE_CREATED_AND_CONFIGURED = """\
|
| 517 |
Following the creation of this PR, an ephemeral Space [{ci_space_id}](https://huggingface.co/spaces/{ci_space_id}) has been started. Any changes pushed to this PR will be synced with the test Space.
|
| 518 |
Since this PR has been created by a trusted author, the ephemeral Space has been configured with the correct hardware, storage, and secrets.
|