import { NextRequest, NextResponse } from 'next/server' // Woodpecker API configuration const WOODPECKER_URL = process.env.WOODPECKER_URL || 'http://woodpecker-server:8000' const WOODPECKER_TOKEN = process.env.WOODPECKER_TOKEN || '' export interface PipelineStep { name: string state: 'pending' | 'running' | 'success' | 'failure' | 'skipped' exit_code: number error?: string } export interface Pipeline { id: number number: number status: 'pending' | 'running' | 'success' | 'failure' | 'error' event: string branch: string commit: string message: string author: string created: number started: number finished: number steps: PipelineStep[] errors?: string[] } export interface WoodpeckerStatusResponse { status: 'online' | 'offline' pipelines: Pipeline[] lastUpdate: string error?: string } export async function GET(request: NextRequest) { const searchParams = request.nextUrl.searchParams const repoId = searchParams.get('repo') || '1' const limit = parseInt(searchParams.get('limit') || '10') try { // Fetch pipelines from Woodpecker API const response = await fetch( `${WOODPECKER_URL}/api/repos/${repoId}/pipelines?per_page=${limit}`, { headers: { 'Authorization': `Bearer ${WOODPECKER_TOKEN}`, 'Content-Type': 'application/json', }, cache: 'no-store', } ) if (!response.ok) { return NextResponse.json({ status: 'offline', pipelines: [], lastUpdate: new Date().toISOString(), error: `Woodpecker API nicht erreichbar (${response.status})` } as WoodpeckerStatusResponse) } const rawPipelines = await response.json() // Transform pipelines to our format const pipelines: Pipeline[] = rawPipelines.map((p: any) => { // Extract errors from workflows/steps const errors: string[] = [] const steps: PipelineStep[] = [] if (p.workflows) { for (const workflow of p.workflows) { if (workflow.children) { for (const child of workflow.children) { steps.push({ name: child.name, state: child.state, exit_code: child.exit_code, error: child.error }) if (child.state === 'failure' && child.error) { errors.push(`${child.name}: ${child.error}`) } } } } } return { id: p.id, number: p.number, status: p.status, event: p.event, branch: p.branch, commit: p.commit?.substring(0, 7) || '', message: p.message || '', author: p.author, created: p.created, started: p.started, finished: p.finished, steps, errors: errors.length > 0 ? errors : undefined } }) return NextResponse.json({ status: 'online', pipelines, lastUpdate: new Date().toISOString() } as WoodpeckerStatusResponse) } catch (error) { console.error('Woodpecker API error:', error) return NextResponse.json({ status: 'offline', pipelines: [], lastUpdate: new Date().toISOString(), error: 'Fehler beim Abrufen des Woodpecker Status' } as WoodpeckerStatusResponse) } } // Trigger a new pipeline export async function POST(request: NextRequest) { try { const body = await request.json() const { repoId = '1', branch = 'main' } = body const response = await fetch( `${WOODPECKER_URL}/api/repos/${repoId}/pipelines`, { method: 'POST', headers: { 'Authorization': `Bearer ${WOODPECKER_TOKEN}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ branch }), } ) if (!response.ok) { return NextResponse.json( { error: 'Pipeline konnte nicht gestartet werden' }, { status: 500 } ) } const pipeline = await response.json() return NextResponse.json({ success: true, pipeline: { id: pipeline.id, number: pipeline.number, status: pipeline.status } }) } catch (error) { console.error('Pipeline trigger error:', error) return NextResponse.json( { error: 'Fehler beim Starten der Pipeline' }, { status: 500 } ) } } // Get pipeline logs export async function PUT(request: NextRequest) { try { const body = await request.json() const { repoId = '1', pipelineNumber, stepId } = body if (!pipelineNumber || !stepId) { return NextResponse.json( { error: 'pipelineNumber und stepId erforderlich' }, { status: 400 } ) } const response = await fetch( `${WOODPECKER_URL}/api/repos/${repoId}/pipelines/${pipelineNumber}/logs/${stepId}`, { headers: { 'Authorization': `Bearer ${WOODPECKER_TOKEN}`, 'Content-Type': 'application/json', }, } ) if (!response.ok) { return NextResponse.json( { error: 'Logs nicht verfuegbar' }, { status: response.status } ) } const logs = await response.json() return NextResponse.json({ logs }) } catch (error) { console.error('Pipeline logs error:', error) return NextResponse.json( { error: 'Fehler beim Abrufen der Logs' }, { status: 500 } ) } }