forked from mckinsey/vizro
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CI] Enable PyCafe dashboards in CI (mckinsey#816)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent
f154b65
commit 5b9ba81
Showing
8 changed files
with
233 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
name: PyCafe Dashboards | ||
|
||
on: | ||
push: | ||
branches: [main] | ||
pull_request: | ||
branches: | ||
- main | ||
paths: | ||
- "vizro-core/**" | ||
|
||
defaults: | ||
run: | ||
working-directory: vizro-core | ||
|
||
env: | ||
PYTHON_VERSION: "3.12" | ||
|
||
jobs: | ||
create-links: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Set up Python | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: ${{ env.PYTHON_VERSION }} | ||
- name: Install Hatch | ||
run: pip install hatch | ||
- name: Build vizro-core package | ||
run: | | ||
hatch build -t wheel | ||
- name: Upload artifact | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: pip | ||
path: vizro-core/dist/*.whl | ||
retention-days: 14 | ||
|
||
- name: Create PyCafe links | ||
run: | | ||
hatch run python ../tools/pycafe/create_pycafe_links.py ${{ github.token }} ${{ github.repository }} ${{ github.event.number }} ${{ github.run_id }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
"""Generate PyCafe links for the example dashboards and post them as a comment on the pull request and as status.""" | ||
|
||
import base64 | ||
import datetime | ||
import gzip | ||
import json | ||
import sys | ||
import textwrap | ||
from pathlib import Path | ||
from typing import Optional | ||
from urllib.parse import quote, urlencode | ||
|
||
from github import Auth, Github | ||
|
||
GITHUB_TOKEN = sys.argv[1] | ||
REPO_NAME = sys.argv[2] | ||
PR_NUMBER = int(sys.argv[3]) | ||
RUN_ID = sys.argv[4] | ||
WHL_FILE = next(Path("dist").glob("*.whl")).name | ||
PYCAFE_URL = "https://py.cafe" | ||
VIZRO_RAW_URL = "https://raw.githubusercontent.com/mckinsey/vizro" | ||
|
||
BOT_COMMENT_TEMPLATE = """## View the example dashboards of the current commit live on PyCafe :coffee: :rocket:\n | ||
Updated on: {current_utc_time} | ||
Commit: {commit_sha} | ||
{dashboards} | ||
""" | ||
|
||
# Access | ||
auth = Auth.Token(GITHUB_TOKEN) | ||
g = Github(auth=auth) | ||
|
||
# Get PR and commits | ||
repo = g.get_repo(REPO_NAME) | ||
pr = repo.get_pull(PR_NUMBER) | ||
commit_sha = pr.head.sha | ||
commit = repo.get_commit(commit_sha) | ||
|
||
|
||
def generate_link(directory: str, extra_requirements: Optional[list[str]] = None): | ||
"""Generate a PyCafe link for the example dashboards.""" | ||
base_url = f"{VIZRO_RAW_URL}/{commit_sha}/vizro-core/{directory}" | ||
|
||
# Requirements | ||
requirements = "\n".join( | ||
filter( | ||
None, | ||
[ | ||
f"{PYCAFE_URL}/gh/artifact/mckinsey/vizro/actions/runs/{RUN_ID}/pip/{WHL_FILE}", | ||
*(extra_requirements or []), | ||
], | ||
) | ||
) | ||
|
||
# App file | ||
app_content = Path(directory, "app.py").read_text() | ||
app_content_split = app_content.split('if __name__ == "__main__":') | ||
if len(app_content_split) > 1: | ||
app_content = app_content_split[0] + textwrap.dedent(app_content_split[1]) | ||
|
||
# JSON object | ||
json_object = { | ||
"code": app_content, | ||
"requirements": requirements, | ||
"files": [], | ||
} | ||
|
||
json_object["files"] = [ | ||
{ | ||
"name": str(file_path.relative_to(directory)), | ||
"url": f"{base_url}/{file_path.relative_to(directory).as_posix()}", | ||
} | ||
for file_path in Path(directory).rglob("*") | ||
if not file_path.is_dir() and file_path.relative_to(directory) != Path("app.py") | ||
] | ||
|
||
json_text = json.dumps(json_object) | ||
compressed_json_text = gzip.compress(json_text.encode("utf8")) | ||
base64_text = base64.b64encode(compressed_json_text).decode("utf8") | ||
query = urlencode({"c": base64_text}, quote_via=quote) | ||
return f"{PYCAFE_URL}/snippet/vizro/v1?{query}" | ||
|
||
|
||
def post_comment(urls: dict[str, str]): | ||
"""Post a comment on the pull request with the links to the PyCafe dashboards.""" | ||
# Inspired by https://github.com/snehilvj/dash-mantine-components | ||
|
||
# Find existing comments by the bot | ||
comments = pr.get_issue_comments() | ||
bot_comment = None | ||
for comment in comments: | ||
if comment.body.startswith("## View the example dashboards of the current commit live"): | ||
bot_comment = comment | ||
break | ||
|
||
# Get current UTC datetime | ||
current_utc_time = datetime.datetime.now(datetime.UTC).strftime("%Y-%m-%d %H:%M:%S UTC") | ||
|
||
# Define the comment body with datetime | ||
dashboards = "\n\n".join(f"Link: [{directory}]({url})" for directory, url in urls.items()) | ||
|
||
# Update the existing comment or create a new one | ||
if bot_comment: | ||
bot_comment.edit( | ||
BOT_COMMENT_TEMPLATE.format(current_utc_time=current_utc_time, commit_sha=commit_sha, dashboards=dashboards) | ||
) | ||
print("Comment updated on the pull request.") # noqa | ||
else: | ||
pr.create_issue_comment( | ||
BOT_COMMENT_TEMPLATE.format(current_utc_time=current_utc_time, commit_sha=commit_sha, dashboards=dashboards) | ||
) | ||
print("Comment added to the pull request.") # noqa | ||
|
||
|
||
if __name__ == "__main__": | ||
directories_with_requirements = { | ||
"examples/dev/": ["openpyxl"], | ||
"examples/scratch_dev": None, | ||
"examples/visual-vocabulary/": None, | ||
} | ||
urls = { | ||
directory: generate_link(directory, extra_requirements) | ||
for directory, extra_requirements in directories_with_requirements.items() | ||
} | ||
|
||
# Create status | ||
for directory, url in urls.items(): | ||
# Define the deployment status | ||
state = "success" # Options: 'error', 'failure', 'pending', 'success' | ||
description = "Test out the app live on PyCafe" | ||
context = f"PyCafe Example ({directory})" | ||
|
||
# Create the status on the commit | ||
commit.create_status(state=state, target_url=url, description=description, context=context) | ||
print(f"Status created for {context} with URL: {url}") # noqa | ||
|
||
# Post the comment with the links | ||
post_comment(urls) |
48 changes: 48 additions & 0 deletions
48
vizro-core/changelog.d/20241017_174654_maximilian_schulz_pycafe_in_ci.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<!-- | ||
A new scriv changelog fragment. | ||
Uncomment the section that is right (remove the HTML comment wrapper). | ||
--> | ||
|
||
<!-- | ||
### Highlights ✨ | ||
- A bullet item for the Highlights ✨ category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1)) | ||
--> | ||
<!-- | ||
### Removed | ||
- A bullet item for the Removed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1)) | ||
--> | ||
<!-- | ||
### Added | ||
- A bullet item for the Added category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1)) | ||
--> | ||
<!-- | ||
### Changed | ||
- A bullet item for the Changed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1)) | ||
--> | ||
<!-- | ||
### Deprecated | ||
- A bullet item for the Deprecated category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1)) | ||
--> | ||
<!-- | ||
### Fixed | ||
- A bullet item for the Fixed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1)) | ||
--> | ||
<!-- | ||
### Security | ||
- A bullet item for the Security category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1)) | ||
--> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,7 +28,7 @@ | |
|
||
|
||
page = vm.Page( | ||
title="Diverging bar", | ||
title="Test I", | ||
components=[ | ||
vm.Graph( | ||
figure=px.bar( | ||
|
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters