Skip to content

Commit

Permalink
Merge pull request #22 from lincc-frameworks/issue/19/time-logic
Browse files Browse the repository at this point in the history
Add conclusion time to dashboard
  • Loading branch information
OliviaLynn authored Dec 23, 2023
2 parents adfedf4 + 8ffcb59 commit cf3f360
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 77 deletions.
54 changes: 22 additions & 32 deletions css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ table {
border-collapse: collapse;
margin-bottom: 20px;
font-family: Arial, sans-serif;
background-color: #222; /* Dark background color */
color: #fff; /* Light text color */
background-color: #222;
color: #fff;
font-size: 0.8em;
}

/* Style the table header */
th {
background: none;
text-align: left;
text-align: center;
padding: 8px;
font-weight: bold;
border-bottom: 2px solid #444; /* Slightly darker border color */
border-bottom: 2px solid #444;
}

/* Style the table cells */
Expand All @@ -27,17 +27,17 @@ td {

/* Alternate row background color */
tr:nth-child(even) {
background-color: #333; /* Darker background for even rows */
background-color: #333;
}

/* Hover effect for table rows */
tr:hover {
background-color: #444; /* Slightly lighter background on hover */
background-color: #444;
}

/* Style the links */
a {
color: #70b4eb; /* Light color for links */
color: #70b4eb;
text-decoration: none; /* Remove underlines from links */
}

Expand Down Expand Up @@ -67,36 +67,18 @@ body {
}

/* Define a class for green-colored icons */
.green-icon {
color: #9de598;
}

/* Define a class for red-colored icons (and entire row) */
.red-icon, .alert {
color: #ff5c3f;
}

/* Define a class for green-colored icons */
.green-icon {
td.green-cell {
color: #9de598;
}

/* Define a class for "pending" cells */
.red-cell {
background-color: #ff5c3f;
}

.red-cell>a {
color: black
}

/* Define a class for "pending" cells */
.yellow-cell {
background-color: #aa9d26;
.red-cell, .red-cell>a {
color: #ff5c3f;
font-weight: bold;
}

.yellow-cell>a {
color: black
.yellow-cell, .yellow-cell>a {
color: #bdad21;
font-weight: bold;
}

/* Media query for larger viewports */
Expand All @@ -111,4 +93,12 @@ body {
td {
padding: 8px;
}
}

/* Alignment */
.align-right {
text-align: right;
}
.align-center {
text-align: center;
}
3 changes: 0 additions & 3 deletions src/lf_workflow_dash/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
from .example_module import greetings, meaning

__all__ = ["greetings", "meaning"]
19 changes: 16 additions & 3 deletions src/lf_workflow_dash/data_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ class WorkflowElemData:
workflow_url: str = ""
workflow_status: str = ""
display_class: str = ""
icon_class: str = ""
last_run_url: str = ""
owner: str = ""
repo: str = ""
conclusion_time: str = ""
conclusion_date: str = ""
# TODO add is_stale

def __init__(self, workflow_name, repo_url, owner, repo):
self.workflow_name = workflow_name
Expand All @@ -25,19 +29,28 @@ def __init__(self, workflow_name, repo_url, owner, repo):
self.workflow_url = f"{repo_url}/actions/workflows/{self.workflow_name}"
self.workflow_status = "pending"
self.display_class = "yellow-cell"
self.icon_class = "fa fa-question-circle"
# TODO add is_stale

def set_status(self, status):
def set_status(self, status, conclusion_time):
"""Set the completion status of a workflow. This will also update the display class
to suit the warning level.
TODO update docstring to add is_stale logic
Args:
status (str): how the workflow completed (e.g. "success" or "failure")
"""
self.workflow_status = status
self.conclusion_time = conclusion_time
# TODO self.is_stale = is_stale
# TODO a nested branch here - first check if it's stale, and only if it isn't, check success
if status == "success":
self.display_class = ""
self.display_class = "green-cell"
self.icon_class = "fa fa-check-circle"
elif status == "failure":
self.display_class = "red-cell"
self.icon_class = "fa fa-times-circle"


@dataclass
Expand Down Expand Up @@ -106,7 +119,7 @@ def read_yaml_file(file_path):
all_projects.append(project_data)

timezone = pytz.timezone("America/New_York")
last_updated = datetime.now(timezone).strftime("%H:%M %B %d, %Y")
last_updated = datetime.now(timezone).strftime("%H:%M %B %d, %Y (US-NYC)")

return {
"page_title": page_title,
Expand Down
23 changes: 0 additions & 23 deletions src/lf_workflow_dash/example_module.py

This file was deleted.

38 changes: 37 additions & 1 deletion src/lf_workflow_dash/github_request.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,29 @@
from datetime import datetime
import requests
import pytz

def get_conclusion_time(last_run):
"""Get the workflow conclusion time and set the proper timezone
Args:
last_run (dict): the most recent run of the workflow
"""
timestamp_str = last_run["updated_at"]

# Parse the timestamp
timestamp = datetime.strptime(timestamp_str, "%Y-%m-%dT%H:%M:%SZ")

# Define the time zones for UTC and New York
utc_timezone = pytz.timezone("UTC")
ny_timezone = pytz.timezone("America/New_York")

# Convert the timestamp to New York time
timestamp_ny = timestamp.replace(tzinfo=utc_timezone).astimezone(ny_timezone)

# Format the timestamp
formatted_timestamp = timestamp_ny.strftime("%H:%M<br>%m/%d/%y")

return formatted_timestamp


def update_workflow_status(workflow_elem, token):
Expand All @@ -25,28 +50,39 @@ def update_workflow_status(workflow_elem, token):
response = requests.request("GET", request_url, headers=headers, data=payload, timeout=15)
status_code = response.status_code
conclusion = "pending"
conclusion_time = ""
# TODO set is_stale

# Process data
if status_code == 200: # API was successful
response_json = response.json()
if len(response_json["workflow_runs"]) == 0: # workflow has no runs
conclusion = "not yet run"

else:
last_run = response_json["workflow_runs"][0]

# Get the workflow conclusion ("success", "failure", etc)
conclusion = last_run["conclusion"]

# Get the time this workflow concluded (in New York time)
conclusion_time = get_conclusion_time(last_run)

# Check if the workflow is currently being executed
if conclusion is None:
# try next most recent
if len(response_json["workflow_runs"]) > 1:
last_run = response_json["workflow_runs"][1]
conclusion = last_run["conclusion"]
conclusion_time = get_conclusion_time(last_run)
else:
conclusion = "pending"
conclusion_time = ""

# TODO set is_stale

else:
print(" ", status_code)
conclusion = status_code

workflow_elem.set_status(conclusion)
workflow_elem.set_status(conclusion, conclusion_time)
82 changes: 67 additions & 15 deletions templates/dash_template.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,86 @@
</head>
<body>
<table>
<tr>
<th>Repository</th>
<th>Nightly Test</th>
<th>Nightly <br/> Benchmarks</th>
<th>Build Docs</th>
<th>Live Build</th>
<th>Other <br/> workflows</th>
<tr>
<th colspan="1" scope="colgroup">Repository</th>
<th colspan="3" scope="colgroup">Nightly Test</th>
<th colspan="3" scope="colgroup">Nightly<br>Benchmarks</th>
<th colspan="3" scope="colgroup">Build Docs</th>
<th colspan="3" scope="colgroup">Live Build</th>
<th colspan="1" scope="colgroup">Other Workflows</th>
</tr>
</tr>

{% for project in all_projects %}
<tr>
<td><a href="{{project.repo_url}}">{{project.repo}}</a></td>
<td class="{{project.smoke_test.display_class}}"><a href="{{project.smoke_test.workflow_url}}">{{project.smoke_test.workflow_status}}</a></td>
<td class="{{project.benchmarks.display_class}}"><a href="{{project.benchmarks.workflow_url}}">{{project.benchmarks.workflow_status}}</a></td>
<td class="{{project.build_docs.display_class}}"><a href="{{project.build_docs.workflow_url}}">{{project.build_docs.workflow_status}}</a></td>
<td class="{{project.live_build.display_class}}"><a href="{{project.live_build.workflow_url}}">{{project.live_build.workflow_status}}</a></td>

<!-- Smoke Test -->
<td class="{{project.smoke_test.display_class}} align-right">
{{project.smoke_test.workflow_status}}
</td>
<td class="{{project.smoke_test.display_class}} align-center">
<i class="{{project.smoke_test.icon_class}}"></i>
</td>
<td class="{{project.smoke_test.display_class}}">
<a href="{{project.smoke_test.workflow_url}}">
{{project.smoke_test.conclusion_time}}
</a>
</td>

<!-- Benchmarks -->
<td class="{{project.benchmarks.display_class}} align-right">
{{project.benchmarks.workflow_status}}
</td>
<td class="{{project.benchmarks.display_class}} align-center">
<i class="{{project.benchmarks.icon_class}}"></i>
</td>
<td class="{{project.benchmarks.display_class}}">
<a href="{{project.benchmarks.workflow_url}}">
{{project.benchmarks.conclusion_time}}
</a>
</td>

<!-- Build Docs -->
<td class="{{project.build_docs.display_class}} align-right">
{{project.build_docs.workflow_status}}
</td>
<td class="{{project.build_docs.display_class}} align-center">
<i class="{{project.build_docs.icon_class}}"></i>
</td>
<td class="{{project.build_docs.display_class}}">
<a href="{{project.build_docs.workflow_url}}">
{{project.build_docs.conclusion_time}}
</a>
</td>

<!-- Live Build -->
<td class="{{project.live_build.display_class}} align-right">
{{project.live_build.workflow_status}}
</td>
<td class="{{project.live_build.display_class}} align-center">
<i class="{{project.live_build.icon_class}}"></i>
</td>
<td class="{{project.live_build.display_class}}">
<a href="{{project.live_build.workflow_url}}">
{{project.live_build.conclusion_time}}
</a>
</td>

<!-- Other -->
<td>
{% for workflow in project.other_workflows %}
<a href="{{workflow.url}}">{{workflow.name}} {{workflow.status}}</a>
<a href="{{workflow.url}}">{{workflow.name}} {{workflow.status}}</a>
{% endfor %}
</td>
</tr>
{% endfor %}

</table>

<p>
Last Updated {{last_updated}} |
<a href='https://github.com/lincc-frameworks/{{dash_repo}}'><i class=\"fa fa-github\"></i> {{dash_repo}}</a>
Last Updated {{last_updated}} |
<a href='https://github.com/lincc-frameworks/{{dash_repo}}'><i class=\"fa fa-github\"></i> {{dash_repo}}</a>
</p>

</body>
</html>

0 comments on commit cf3f360

Please sign in to comment.