🤖 feat: complete gitea-client skill enhancements with new CI/CD monitoring commands
This commit is contained in:
@@ -40,6 +40,18 @@ Create a token in Gitea:
|
|||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
|
### List Workflows
|
||||||
|
|
||||||
|
```bash
|
||||||
|
skill gitea-client list-workflows <owner> <repo>
|
||||||
|
```
|
||||||
|
|
||||||
|
List available workflows for a repository.
|
||||||
|
|
||||||
|
**Arguments:**
|
||||||
|
- `owner`: Repository owner
|
||||||
|
- `repo`: Repository name
|
||||||
|
|
||||||
### List Jobs
|
### List Jobs
|
||||||
|
|
||||||
```bash
|
```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
|
gitea-client list-workflow-jobs arcodange dance-lessons-coach 350
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Monitor Workflow Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
skill gitea-client monitor-workflow <owner> <repo> <workflow_run_id> [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 <owner> <repo> <job_id>
|
||||||
|
```
|
||||||
|
|
||||||
|
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 <owner> <repo> [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
|
### Wait for Job Completion
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -414,6 +500,70 @@ The skill handles common API errors:
|
|||||||
4. **Logging**: Redirect output to files for debugging
|
4. **Logging**: Redirect output to files for debugging
|
||||||
5. **Timeouts**: Use reasonable timeouts for wait operations
|
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
|
## Real-World Use Case: PR Commenting Workflow
|
||||||
|
|
||||||
The Gitea client skill excels at automated PR commenting during CI/CD workflows.
|
The Gitea client skill excels at automated PR commenting during CI/CD workflows.
|
||||||
|
|||||||
@@ -52,6 +52,20 @@ api_request() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# List workflows
|
||||||
|
cmd_list_workflows() {
|
||||||
|
local owner="$1"
|
||||||
|
local repo="$2"
|
||||||
|
|
||||||
|
if [[ -z "$owner" || -z "$repo" ]]; then
|
||||||
|
echo "Usage: $0 list-workflows <owner> <repo>" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local endpoint="/repos/${owner}/${repo}/actions/workflows"
|
||||||
|
api_request "GET" "$endpoint"
|
||||||
|
}
|
||||||
|
|
||||||
# List jobs
|
# List jobs
|
||||||
cmd_list_jobs() {
|
cmd_list_jobs() {
|
||||||
local owner="$1"
|
local owner="$1"
|
||||||
@@ -226,12 +240,16 @@ main() {
|
|||||||
shift || true
|
shift || true
|
||||||
|
|
||||||
case "$command" in
|
case "$command" in
|
||||||
|
list-workflows) cmd_list_workflows "$@" ;;
|
||||||
list-jobs) cmd_list_jobs "$@" ;;
|
list-jobs) cmd_list_jobs "$@" ;;
|
||||||
job-status) cmd_job_status "$@" ;;
|
job-status) cmd_job_status "$@" ;;
|
||||||
job-logs) cmd_job_logs "$@" ;;
|
job-logs) cmd_job_logs "$@" ;;
|
||||||
action-logs) cmd_action_logs "$@" ;;
|
action-logs) cmd_action_logs "$@" ;;
|
||||||
list-workflow-jobs) cmd_list_workflow_jobs "$@" ;;
|
list-workflow-jobs) cmd_list_workflow_jobs "$@" ;;
|
||||||
wait-job) cmd_wait_job "$@" ;;
|
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 "$@" ;;
|
comment-pr) cmd_comment_pr "$@" ;;
|
||||||
pr-status) cmd_pr_status "$@" ;;
|
pr-status) cmd_pr_status "$@" ;;
|
||||||
list-issues) cmd_list_issues "$@" ;;
|
list-issues) cmd_list_issues "$@" ;;
|
||||||
@@ -245,12 +263,16 @@ main() {
|
|||||||
echo "Usage: $0 <command> [args...]" >&2
|
echo "Usage: $0 <command> [args...]" >&2
|
||||||
echo "" >&2
|
echo "" >&2
|
||||||
echo "Commands:" >&2
|
echo "Commands:" >&2
|
||||||
|
echo " list-workflows <owner> <repo>" >&2
|
||||||
echo " list-jobs <owner> <repo> <workflow_id> [limit]" >&2
|
echo " list-jobs <owner> <repo> <workflow_id> [limit]" >&2
|
||||||
echo " job-status <owner> <repo> <job_id>" >&2
|
echo " job-status <owner> <repo> <job_id>" >&2
|
||||||
echo " job-logs <owner> <repo> <job_id> [output_file]" >&2
|
echo " job-logs <owner> <repo> <job_id> [output_file]" >&2
|
||||||
echo " action-logs <owner> <repo> <action_job_id> [output_file]" >&2
|
echo " action-logs <owner> <repo> <action_job_id> [output_file]" >&2
|
||||||
echo " list-workflow-jobs <owner> <repo> <workflow_run_id>" >&2
|
echo " list-workflow-jobs <owner> <repo> <workflow_run_id>" >&2
|
||||||
echo " wait-job <owner> <repo> <job_id> [timeout]" >&2
|
echo " wait-job <owner> <repo> <job_id> [timeout]" >&2
|
||||||
|
echo " monitor-workflow <owner> <repo> <workflow_run_id> [interval_seconds]" >&2
|
||||||
|
echo " diagnose-job <owner> <repo> <job_id>" >&2
|
||||||
|
echo " recent-workflows <owner> <repo> [limit] [status_filter]" >&2
|
||||||
echo " comment-pr <owner> <repo> <pr_number> <comment>" >&2
|
echo " comment-pr <owner> <repo> <pr_number> <comment>" >&2
|
||||||
echo " pr-status <owner> <repo> <pr_number>" >&2
|
echo " pr-status <owner> <repo> <pr_number>" >&2
|
||||||
echo " list-issues <owner> <repo> [state]" >&2
|
echo " list-issues <owner> <repo> [state]" >&2
|
||||||
@@ -389,4 +411,109 @@ cmd_get_wiki() {
|
|||||||
api_request "GET" "$endpoint"
|
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 <owner> <repo> <workflow_run_id> [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 <owner> <repo> <job_id>" >&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 <owner> <repo> [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 "$@"
|
main "$@"
|
||||||
|
|||||||
Reference in New Issue
Block a user