Merge pull request 'Better use of Jenkins API in frontend' (#39) from feature/main-38-JenkinsAPIUsage into main
Reviewed-on: #39
This commit was merged in pull request #39.
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import base64
|
||||
import html
|
||||
from typing import Dict, List
|
||||
|
||||
import requests
|
||||
@@ -26,11 +27,9 @@ def _sort_builds(builds: List[Dict]) -> List[Dict]:
|
||||
return sorted(builds, key=lambda build: build.get("number", 0), reverse=True)
|
||||
|
||||
|
||||
def normalize_build(build: Dict) -> Dict:
|
||||
changes = build.get("changeSets", [])
|
||||
def _extract_commits(build: Dict) -> List[Dict]:
|
||||
commits = []
|
||||
|
||||
for cs in changes:
|
||||
for cs in build.get("changeSets", []):
|
||||
for item in cs.get("items", []):
|
||||
commits.append(
|
||||
{
|
||||
@@ -39,14 +38,33 @@ def normalize_build(build: Dict) -> Dict:
|
||||
"author": item.get("author", {}).get("fullName", "unknown"),
|
||||
}
|
||||
)
|
||||
return commits
|
||||
|
||||
|
||||
def _extract_trigger(build: Dict) -> str:
|
||||
for action in build.get("actions", []):
|
||||
for cause in action.get("causes", []):
|
||||
description = cause.get("shortDescription")
|
||||
if description:
|
||||
return html.unescape(description).strip()
|
||||
return ""
|
||||
|
||||
|
||||
def normalize_build(build: Dict) -> Dict:
|
||||
commits = _extract_commits(build)
|
||||
trigger = _extract_trigger(build)
|
||||
status = (build.get("result") or "RUNNING").lower()
|
||||
if build.get("building"):
|
||||
status = "running"
|
||||
|
||||
return {
|
||||
"number": build.get("number"),
|
||||
"status": (build.get("result") or "RUNNING").lower(),
|
||||
"status": status,
|
||||
"finished_at": build.get("timestamp"),
|
||||
"duration_seconds": build.get("duration", 0) // 1000,
|
||||
"url": build.get("url"),
|
||||
"commits": commits,
|
||||
"trigger": trigger,
|
||||
}
|
||||
|
||||
|
||||
@@ -63,15 +81,16 @@ def fetch_builds(limit: int = 5) -> List[Dict]:
|
||||
raise ValueError("JENKINS_JOB_NAME not configured")
|
||||
url = (
|
||||
f"{settings.jenkins_base_url}/job/{settings.jenkins_job_name}/api/json"
|
||||
"?tree=builds[number,url,result,timestamp,duration,"
|
||||
"changesets[items[commitId,msg,author[fullName]]]]"
|
||||
"?tree=builds[number,url,result,timestamp,duration,building,"
|
||||
"changeSets[items[commitId,msg,author[fullName]]],"
|
||||
"actions[causes[shortDescription]]]"
|
||||
)
|
||||
|
||||
resp = requests.get(url, headers=_auth_header(), timeout=5)
|
||||
resp.raise_for_status()
|
||||
|
||||
builds = resp.json().get("builds", [])
|
||||
return builds[:limit]
|
||||
return _sort_builds(builds)[:limit]
|
||||
|
||||
|
||||
def build_history() -> Dict:
|
||||
|
||||
@@ -61,6 +61,15 @@ def test_build_history(monkeypatch):
|
||||
"timestamp": 1719992400000,
|
||||
"duration": 75000,
|
||||
"url": "http://jenkins.local/job/demo/205",
|
||||
"actions": [
|
||||
{
|
||||
"causes": [
|
||||
{
|
||||
"shortDescription": "Triggered by Merge pull request #37",
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"changeSets": [
|
||||
{
|
||||
"items": [
|
||||
@@ -79,6 +88,7 @@ def test_build_history(monkeypatch):
|
||||
"timestamp": 1719988800000,
|
||||
"duration": 1500,
|
||||
"url": "http://jenkins.local/job/demo/204",
|
||||
"actions": [],
|
||||
"changeSets": [],
|
||||
},
|
||||
]
|
||||
@@ -101,12 +111,14 @@ def test_build_history(monkeypatch):
|
||||
assert first["commits"] == [
|
||||
{"commit": "9ac3f91", "message": "Anade la API de Jenkins", "author": "Dev One"}
|
||||
]
|
||||
assert first["trigger"] == "Triggered by Merge pull request #37"
|
||||
|
||||
second = builds[1]
|
||||
assert second["number"] == 204
|
||||
assert second["status"] == "running"
|
||||
assert second["duration_seconds"] == 1
|
||||
assert second["commits"] == []
|
||||
assert second["trigger"] == ""
|
||||
|
||||
|
||||
def test_build_history_error_returns_empty(monkeypatch):
|
||||
|
||||
@@ -378,7 +378,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
<span class="summary-title">#{build.number}</span>
|
||||
|
||||
{#if build.commits.length === 0}
|
||||
<span class="muted">Ejecución manual</span>
|
||||
<span class="muted">
|
||||
{build.trigger || 'Ejecución manual'}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="summary-commit">
|
||||
{build.commits[0].commit} · {build.commits[0].author}
|
||||
@@ -401,6 +403,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
{#if build.trigger}
|
||||
<p class="history-row">
|
||||
<span>Disparo</span>
|
||||
<span>{build.trigger}</span>
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
<p class="history-row">
|
||||
<span>Duración</span>
|
||||
<span>{build.duration_seconds} s</span>
|
||||
@@ -408,6 +417,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
{#if build.status === 'failure'}
|
||||
<p class="history-message danger">Build fallida</p>
|
||||
{:else if build.status === 'running'}
|
||||
<p class="history-message running">En curso</p>
|
||||
{:else}
|
||||
<p class="history-message success">Correcto</p>
|
||||
{/if}
|
||||
|
||||
@@ -723,6 +723,11 @@ li {
|
||||
box-shadow: 0 0 8px rgba(248, 113, 113, 0.5);
|
||||
}
|
||||
|
||||
.status-dot.running {
|
||||
background: #facc15;
|
||||
box-shadow: 0 0 8px rgba(250, 204, 21, 0.5);
|
||||
}
|
||||
|
||||
.history-body {
|
||||
padding: 0.75rem 0.9rem 0.9rem;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
||||
@@ -758,6 +763,12 @@ li {
|
||||
color: #bbf7d0;
|
||||
}
|
||||
|
||||
.history-message.running {
|
||||
background: rgba(250, 204, 21, 0.16);
|
||||
border-color: rgba(250, 204, 21, 0.5);
|
||||
color: #fef9c3;
|
||||
}
|
||||
|
||||
.history-item[open] {
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.28);
|
||||
}
|
||||
@@ -770,6 +781,10 @@ li {
|
||||
border-color: rgba(248, 113, 113, 0.35);
|
||||
}
|
||||
|
||||
.history-item.running {
|
||||
border-color: rgba(250, 204, 21, 0.35);
|
||||
}
|
||||
|
||||
.chip.danger {
|
||||
background: rgba(248, 113, 113, 0.2);
|
||||
color: #fecdd3;
|
||||
|
||||
Reference in New Issue
Block a user