From b3631211aff833df546e798c8a7ee739e167d042 Mon Sep 17 00:00:00 2001
From: Story Crater Bot <19826264+Riotpiaole@users.noreply.github.com>
Date: Wed, 2 Sep 2026 20:30:21 -0700
Subject: [PATCH] feat: add CI status badge with commit SHA on homelab
experience card
---
.gitea/workflows/build-push.yml | 2 ++
app/api/ci-status/route.ts | 14 +++++---
components/ExperienceTimeline.tsx | 55 +++++++++++++++++++++++++++++--
3 files changed, 64 insertions(+), 7 deletions(-)
diff --git a/.gitea/workflows/build-push.yml b/.gitea/workflows/build-push.yml
index b0a2242..41cd9c0 100644
--- a/.gitea/workflows/build-push.yml
+++ b/.gitea/workflows/build-push.yml
@@ -63,3 +63,5 @@ jobs:
docker push "${IMAGE}:${{ steps.sha.outputs.short_sha }}"
docker push "${IMAGE}:latest"
echo "✓ Image pushed: ${IMAGE}:${{ steps.sha.outputs.short_sha }}"
+
+
diff --git a/app/api/ci-status/route.ts b/app/api/ci-status/route.ts
index c6d44e9..9ca06b1 100644
--- a/app/api/ci-status/route.ts
+++ b/app/api/ci-status/route.ts
@@ -1,9 +1,14 @@
-import { NextResponse } from 'next/server'
+import { NextRequest, NextResponse } from 'next/server'
const FORGEJO_URL = 'https://forgejo.riotpiao.com'
-const REPO = 'rock/riotpiao.com'
+const DEFAULT_REPO = 'rock/riotpiao.com'
+const ALLOWED_REPOS = ['rock/riotpiao.com', 'rock/homelab', 'rock/homelab-frontend', 'rock/poimen', 'rock/poimen-memory', 'rock/poimen-workflows']
-export async function GET() {
+export async function GET(request: NextRequest) {
+ const repo = request.nextUrl.searchParams.get('repo') || DEFAULT_REPO
+ if (!ALLOWED_REPOS.includes(repo)) {
+ return NextResponse.json({ error: 'Repo not allowed' }, { status: 403 })
+ }
const token = process.env.FORGEJO_TOKEN
if (!token) {
@@ -15,7 +20,7 @@ export async function GET() {
try {
const response = await fetch(
- `${FORGEJO_URL}/api/v1/repos/${REPO}/actions/runs?limit=1`,
+ `${FORGEJO_URL}/api/v1/repos/${repo}/actions/runs?limit=1`,
{
headers: {
Authorization: `token ${token}`,
@@ -42,6 +47,7 @@ export async function GET() {
return NextResponse.json({
status: latestRun.status,
conclusion: latestRun.conclusion,
+ sha: latestRun.head_sha,
title: latestRun.display_title || latestRun.head_branch,
branch: latestRun.head_branch,
url: latestRun.html_url,
diff --git a/components/ExperienceTimeline.tsx b/components/ExperienceTimeline.tsx
index ec245ed..0251222 100644
--- a/components/ExperienceTimeline.tsx
+++ b/components/ExperienceTimeline.tsx
@@ -1,8 +1,52 @@
'use client'
import { motion } from 'framer-motion'
+import { useState, useEffect } from 'react'
+import { GitBranch, CheckCircle, XCircle, Loader2 } from 'lucide-react'
import { useLanguage } from '@/lib/LanguageContext'
+interface RepoCI {
+ sha: string
+ status: string
+ url: string
+}
+
+function CIBadge({ repo, forgejoUrl }: { repo: string; forgejoUrl: string }) {
+ const [ci, setCI] = useState