From c6a2d63a6d47da55531497e71b6f22eab92fd773 Mon Sep 17 00:00:00 2001 From: Gabriel Radureau Date: Tue, 7 Apr 2026 11:31:11 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20feat:=20complete=20gitea-client?= =?UTF-8?q?=20skill=20enhancements=20with=20new=20CI/CD=20monitoring=20com?= =?UTF-8?q?mands?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vibe/skills/gitea-client/SKILL.md | 150 ++++++++++++++++++ .../gitea-client/scripts/gitea-client.sh | 127 +++++++++++++++ 2 files changed, 277 insertions(+) diff --git a/.vibe/skills/gitea-client/SKILL.md b/.vibe/skills/gitea-client/SKILL.md index a793759..453d696 100644 --- a/.vibe/skills/gitea-client/SKILL.md +++ b/.vibe/skills/gitea-client/SKILL.md @@ -40,6 +40,18 @@ Create a token in Gitea: ## Commands +### List Workflows + +```bash +skill gitea-client list-workflows +``` + +List available workflows for a repository. + +**Arguments:** +- `owner`: Repository owner +- `repo`: Repository name + ### List Jobs ```bash @@ -151,6 +163,80 @@ gitea-client list-workflow-jobs arcodange dance-lessons-coach 351 | jq '.jobs[] gitea-client list-workflow-jobs arcodange dance-lessons-coach 350 ``` +### Monitor Workflow Run + +```bash +skill gitea-client monitor-workflow [interval_seconds] +``` + +Monitor a workflow run until completion with automatic updates. + +**Arguments:** +- `owner`: Repository owner +- `repo`: Repository name +- `workflow_run_id`: Workflow run ID +- `interval_seconds`: Update interval in seconds (default: 30) + +**Example:** +```bash +# Monitor workflow run 415 with 30-second updates +gitea-client monitor-workflow arcodange dance-lessons-coach 415 30 + +# Monitor with faster updates (10 seconds) +gitea-client monitor-workflow arcodange dance-lessons-coach 415 10 +``` + +### Diagnose Failed Job + +```bash +skill gitea-client diagnose-job +``` + +Diagnose a failed job with automatic error analysis. + +**Arguments:** +- `owner`: Repository owner +- `repo`: Repository name +- `job_id`: Job ID + +**Features:** +- Shows job details (status, conclusion, timestamps) +- Displays last 50 lines of logs +- Automatically extracts and highlights error messages +- Shows workflow run context + +**Example:** +```bash +# Diagnose failed job 759 +gitea-client diagnose-job arcodange dance-lessons-coach 759 +``` + +### Get Recent Workflows Summary + +```bash +skill gitea-client recent-workflows [limit] [status_filter] +``` + +Get a summary of recent workflow runs. + +**Arguments:** +- `owner`: Repository owner +- `repo`: Repository name +- `limit`: Maximum number of workflows to show (default: 10) +- `status_filter`: Filter by status (optional: completed, in_progress, queued, waiting) + +**Example:** +```bash +# Show last 5 workflow runs +gitea-client recent-workflows arcodange dance-lessons-coach 5 + +# Show only completed workflows +gitea-client recent-workflows arcodange dance-lessons-coach 10 completed + +# Show in-progress workflows +gitea-client recent-workflows arcodange dance-lessons-coach 5 in_progress +``` + ### Wait for Job Completion ```bash @@ -414,6 +500,70 @@ The skill handles common API errors: 4. **Logging**: Redirect output to files for debugging 5. **Timeouts**: Use reasonable timeouts for wait operations +## Enhanced Workflow Monitoring with New Commands + +### Complete CI Debugging Workflow with New Commands + +```bash +# 1. Get summary of recent workflows to identify issues +gitea-client recent-workflows arcodange dance-lessons-coach 10 + +# 2. Monitor a specific workflow run until completion +gitea-client monitor-workflow arcodange dance-lessons-coach 415 30 + +# 3. If workflow fails, automatically diagnose all failed jobs +WORKFLOW_ID=415 +WORKFLOW_STATUS=$(gitea-client job-status arcodange dance-lessons-coach $WORKFLOW_ID | jq -r '.status') +WORKFLOW_CONCLUSION=$(gitea-client job-status arcodange dance-lessons-coach $WORKFLOW_ID | jq -r '.conclusion') + +if [ "$WORKFLOW_CONCLUSION" = "failure" ]; then + echo "Workflow failed! Diagnosing all jobs..." + + # Get all jobs in the workflow + JOBS=$(gitea-client list-workflow-jobs arcodange dance-lessons-coach $WORKFLOW_ID | jq -r '.jobs[] | select(.conclusion == "failure") | .id') + + # Diagnose each failed job + for job_id in $JOBS; do + echo "Diagnosing job $job_id:" + gitea-client diagnose-job arcodange dance-lessons-coach $job_id + echo "========================================" + done +fi + +# 4. Advanced monitoring with automatic diagnosis +WORKFLOW_ID=415 +TIMEOUT=300 +SECONDS_ELAPSED=0 + +while [ $SECONDS_ELAPSED -lt $TIMEOUT ]; do + STATUS=$(gitea-client job-status arcodange dance-lessons-coach $WORKFLOW_ID | jq -r '.status') + CONCLUSION=$(gitea-client job-status arcodange dance-lessons-coach $WORKFLOW_ID | jq -r '.conclusion') + + echo "[$(date)] Status: $STATUS, Conclusion: ${CONCLUSION:-not completed}" + + if [[ "$CONCLUSION" == "failure" ]]; then + echo "Workflow failed! Running automatic diagnosis..." + gitea-client diagnose-job arcodange dance-lessons-coach $WORKFLOW_ID + + # Find PR and comment + PR_NUMBER=$(gitea-client list-prs arcodange dance-lessons-coach | \ + jq -r '.[] | select(.head.ref == "feature/user-authentication-bdd") | .number') + + if [ -n "$PR_NUMBER" ]; then + gitea-client comment-pr arcodange dance-lessons-coach $PR_NUMBER \ + "⚠️ CI Workflow $WORKFLOW_ID failed. See diagnosis above for details." + fi + break + elif [[ "$STATUS" != "in_progress" && "$STATUS" != "waiting" ]]; then + echo "Workflow completed with status: $STATUS" + break + fi + + sleep 30 + SECONDS_ELAPSED=$((SECONDS_ELAPSED + 30)) +done +``` + ## Real-World Use Case: PR Commenting Workflow The Gitea client skill excels at automated PR commenting during CI/CD workflows. diff --git a/.vibe/skills/gitea-client/scripts/gitea-client.sh b/.vibe/skills/gitea-client/scripts/gitea-client.sh index 14484be..46f652a 100755 --- a/.vibe/skills/gitea-client/scripts/gitea-client.sh +++ b/.vibe/skills/gitea-client/scripts/gitea-client.sh @@ -52,6 +52,20 @@ api_request() { fi } +# List workflows +cmd_list_workflows() { + local owner="$1" + local repo="$2" + + if [[ -z "$owner" || -z "$repo" ]]; then + echo "Usage: $0 list-workflows " >&2 + exit 1 + fi + + local endpoint="/repos/${owner}/${repo}/actions/workflows" + api_request "GET" "$endpoint" +} + # List jobs cmd_list_jobs() { local owner="$1" @@ -226,12 +240,16 @@ main() { shift || true case "$command" in + list-workflows) cmd_list_workflows "$@" ;; list-jobs) cmd_list_jobs "$@" ;; job-status) cmd_job_status "$@" ;; job-logs) cmd_job_logs "$@" ;; action-logs) cmd_action_logs "$@" ;; list-workflow-jobs) cmd_list_workflow_jobs "$@" ;; wait-job) cmd_wait_job "$@" ;; + monitor-workflow) cmd_monitor_workflow "$@" ;; + diagnose-job) cmd_diagnose_job "$@" ;; + recent-workflows) cmd_recent_workflows "$@" ;; comment-pr) cmd_comment_pr "$@" ;; pr-status) cmd_pr_status "$@" ;; list-issues) cmd_list_issues "$@" ;; @@ -245,12 +263,16 @@ main() { echo "Usage: $0 [args...]" >&2 echo "" >&2 echo "Commands:" >&2 + echo " list-workflows " >&2 echo " list-jobs [limit]" >&2 echo " job-status " >&2 echo " job-logs [output_file]" >&2 echo " action-logs [output_file]" >&2 echo " list-workflow-jobs " >&2 echo " wait-job [timeout]" >&2 + echo " monitor-workflow [interval_seconds]" >&2 + echo " diagnose-job " >&2 + echo " recent-workflows [limit] [status_filter]" >&2 echo " comment-pr " >&2 echo " pr-status " >&2 echo " list-issues [state]" >&2 @@ -389,4 +411,109 @@ cmd_get_wiki() { api_request "GET" "$endpoint" } +# Monitor workflow run until completion +cmd_monitor_workflow() { + local owner="$1" + local repo="$2" + local workflow_run_id="$3" + local interval="${4:-30}" + + if [[ -z "$owner" || -z "$repo" || -z "$workflow_run_id" ]]; then + echo "Usage: $0 monitor-workflow [interval_seconds]" >&2 + exit 1 + fi + + echo "Monitoring workflow run $workflow_run_id (interval: ${interval}s)..." + echo "Press Ctrl+C to stop monitoring" + + while true; do + local endpoint="/repos/${owner}/${repo}/actions/runs/${workflow_run_id}" + local status=$(api_request "GET" "$endpoint" | jq -r '.status') + local conclusion=$(api_request "GET" "$endpoint" | jq -r '.conclusion') + local updated_at=$(api_request "GET" "$endpoint" | jq -r '.updated_at') + + echo "[$(date +'%Y-%m-%d %H:%M:%S')] Status: $status, Conclusion: ${conclusion:-not completed}, Updated: $updated_at" + + # List jobs in this workflow + local jobs_endpoint="/repos/${owner}/${repo}/actions/runs/${workflow_run_id}/jobs" + local jobs=$(api_request "GET" "$jobs_endpoint") + echo "Jobs:" + echo "$jobs" | jq -r '.jobs[] | " \(.id): \(.name) - \(.status) \(if .conclusion then "(\(.conclusion))" else "" end)"' + + # Check if workflow is completed + if [[ "$status" != "queued" && "$status" != "in_progress" && "$status" != "waiting" ]]; then + echo "Workflow run $workflow_run_id has completed with status: $status and conclusion: ${conclusion:-none}" + break + fi + + sleep "$interval" + done +} + +# Diagnose failed job +cmd_diagnose_job() { + local owner="$1" + local repo="$2" + local job_id="$3" + + if [[ -z "$owner" || -z "$repo" || -z "$job_id" ]]; then + echo "Usage: $0 diagnose-job " >&2 + exit 1 + fi + + echo "Diagnosing job $job_id..." + + # Get job details + local job_endpoint="/repos/${owner}/${repo}/actions/jobs/${job_id}" + local job_details=$(api_request "GET" "$job_endpoint") + + echo "Job Details:" + echo "$job_details" | jq '. | {id, name, status, conclusion, started_at, completed_at, runner_name}' + + # Get job logs + local logs_endpoint="/repos/${owner}/${repo}/actions/jobs/${job_id}/logs" + echo -e "\nLast 50 lines of logs:" + api_request "GET" "$logs_endpoint" | tail -50 + + # Look for errors + echo -e "\nError analysis:" + api_request "GET" "$logs_endpoint" | grep -i "error\|fail\|panic\|exception" | tail -10 + + # Get workflow run details + local run_id=$(echo "$job_details" | jq -r '.run_id') + local run_endpoint="/repos/${owner}/${repo}/actions/runs/${run_id}" + local run_details=$(api_request "GET" "$run_endpoint") + + echo -e "\nWorkflow Run Details:" + echo "$run_details" | jq '. | {id, display_title, status, conclusion, head_branch, head_sha}' +} + +# Get recent workflow runs summary +cmd_recent_workflows() { + local owner="$1" + local repo="$2" + local limit="${3:-10}" + local status_filter="${4:-}" + + if [[ -z "$owner" || -z "$repo" ]]; then + echo "Usage: $0 recent-workflows [limit] [status_filter]" >&2 + echo "Status filter options: all, completed, in_progress, queued, waiting" >&2 + exit 1 + fi + + local endpoint="/repos/${owner}/${repo}/actions/runs?limit=${limit}" + if [[ -n "$status_filter" ]]; then + endpoint="$endpoint&status=$status_filter" + fi + + local workflows=$(api_request "GET" "$endpoint") + + echo "Recent Workflow Runs (showing $limit most recent):" + echo "$workflows" | jq -r '.workflow_runs[] | "\(.id): \(.display_title) - \(.status) \(if .conclusion then "(\(.conclusion))" else "" end) - \(.updated_at)"' + + # Show summary statistics + echo -e "\nSummary:" + echo "$workflows" | jq -r '.workflow_runs | group_by(.conclusion) | .[] | " \(.[0].conclusion // "in_progress"): \(length)"' +} + main "$@"