ci/trunk-based-development #1

Merged
arcodange merged 11 commits from ci/trunk-based-development into main 2026-04-06 13:20:01 +02:00
5 changed files with 741 additions and 0 deletions
Showing only changes of commit 7677b86b06 - Show all commits

View File

@@ -0,0 +1,137 @@
# Gitea Client Skill - Setup Guide
This guide explains how to set up and use the Gitea Client skill for AI agent integration.
## Prerequisites
1. **Gitea Account**: You need access to the Gitea instance at https://gitea.arcodange.lab
2. **Personal Access Token**: Create a token with appropriate permissions
3. **curl and jq**: Required for API interactions
## Setup Instructions
### 1. Create a Personal Access Token
1. Log in to https://gitea.arcodange.lab
2. Go to your profile → Settings → Applications
3. Click "Generate New Token"
4. Set required scopes:
- `read:repository` - Read repository data
- `write:repository` - Comment on PRs
- `read:user` - Read user data
5. Copy the generated token
### 2. Configure Authentication
**Option A: Environment Variable (Simple)**
```bash
export GITEA_API_TOKEN="your_personal_access_token"
```
**Option B: Token File (Recommended for security)**
```bash
echo "your_personal_access_token" > ~/.gitea_token
chmod 600 ~/.gitea_token
export GITEA_API_TOKEN_FILE="$HOME/.gitea_token"
```
### 3. Add to Your Shell Configuration
Add the export command to your `~/.bashrc`, `~/.zshrc`, or equivalent:
```bash
# For environment variable
echo 'export GITEA_API_TOKEN="your_token"' >> ~/.bashrc
# For token file
echo 'export GITEA_API_TOKEN_FILE="$HOME/.gitea_token"' >> ~/.bashrc
```
Then reload your shell:
```bash
source ~/.bashrc
```
## Usage Examples
### Test Your Setup
```bash
# List recent jobs for a workflow
./scripts/gitea-client.sh list-jobs owner repo workflow_id 5
# Check job status
./scripts/gitea-client.sh job-status owner repo job_id
```
### Monitor a CI/CD Job
```bash
# Wait for job completion (5 minute timeout)
./scripts/gitea-client.sh wait-job owner repo job_id 300
# Get logs if failed
./scripts/gitea-client.sh job-logs owner repo job_id
```
### Comment on a Pull Request
```bash
# Add a comment to PR #42
./scripts/gitea-client.sh comment-pr owner repo 42 "Build completed successfully!"
# Get PR status
./scripts/gitea-client.sh pr-status owner repo 42
```
## Troubleshooting
### Common Issues
**401 Unauthorized**
- Check your token is correct
- Verify token has required scopes
- Ensure you're using the right authentication method
**404 Not Found**
- Verify repository owner and name
- Check workflow ID and job ID
- Confirm PR number exists
**429 Too Many Requests**
- Wait and retry
- Consider rate limiting in your scripts
- Contact admin if this persists
### Debugging
Enable verbose output by modifying the script:
```bash
# Change this line in gitea-client.sh
curl -s ... # Remove -s for verbose output
curl ... # Shows full request/response
```
## Security Best Practices
1. **Never commit tokens to version control**
2. **Use token files with restrictive permissions** (`chmod 600`)
3. **Rotate tokens regularly**
4. **Use minimal required scopes**
5. **Revoke tokens when no longer needed**
## API Documentation
- **Swagger**: https://gitea.arcodange.lab/swagger.v1.json
- **Gitea API Docs**: https://docs.gitea.com/api/usage
## Support
For issues with the Gitea instance:
- Contact: system administrators
- Instance: https://gitea.arcodange.lab
For issues with this skill:
- Check the SKILL.md for command reference
- Review this README for setup
- Examine the script for implementation details

View File

@@ -0,0 +1,287 @@
name: gitea-client
description: Gitea API client for job monitoring and PR management
# Gitea-Client Skill
A skill for interacting with Gitea API to monitor jobs, track PRs, and manage repository actions.
## Requirements
### Authentication
**Option 1: Environment Variable**
```bash
export GITEA_API_TOKEN="your_personal_access_token"
```
**Option 2: Token File** (Recommended for security)
```bash
export GITEA_API_TOKEN_FILE="/path/to/token_file"
```
Create a token in Gitea:
1. Go to your Gitea profile → Settings → Applications
2. Generate a new token with `read:repository`, `write:repository`, and `read:user` scopes
3. Either export it directly or save to a file and set GITEA_API_TOKEN_FILE
### API Documentation
- Swagger: https://gitea.arcodange.lab/swagger.v1.json
- Base URL: https://gitea.arcodange.lab
## Commands
### List Jobs
```bash
skill gitea-client list-jobs <owner> <repo> <workflow_id> [limit]
```
List workflow jobs for a repository.
**Arguments:**
- `owner`: Repository owner
- `repo`: Repository name
- `workflow_id`: Workflow ID
- `limit`: Maximum number of jobs to return (default: 10)
### Get Job Status
```bash
skill gitea-client job-status <owner> <repo> <job_id>
```
Get the current status of a specific job.
**Arguments:**
- `owner`: Repository owner
- `repo`: Repository name
- `job_id`: Job ID
### Get Job Logs
```bash
skill gitea-client job-logs <owner> <repo> <job_id> [output_file]
```
Fetch logs for a specific job.
**Arguments:**
- `owner`: Repository owner
- `repo`: Repository name
- `job_id`: Job ID
- `output_file`: Optional file to save logs (default: stdout)
**Examples:**
```bash
# Display logs in console
gitea-client job-logs arcodange DanceLessonsCoach 658
# Save logs to file
gitea-client job-logs arcodange DanceLessonsCoach 658 job_logs.txt
```
### Get Action Job Logs
```bash
skill gitea-client action-logs <owner> <repo> <action_job_id> [output_file]
```
Fetch logs for a specific action job (individual job within a workflow run).
**Arguments:**
- `owner`: Repository owner
- `repo`: Repository name
- `action_job_id`: Action job ID (from workflow jobs list)
- `output_file`: Optional file to save logs (default: stdout)
**Examples:**
```bash
# Display action job logs
gitea-client action-logs arcodange DanceLessonsCoach 658
# Save to file for analysis
gitea-client action-logs arcodange DanceLessonsCoach 658 build_job_logs.txt
```
### List Workflow Jobs
```bash
skill gitea-client list-workflow-jobs <owner> <repo> <workflow_run_id>
```
List all jobs for a specific workflow run.
**Arguments:**
- `owner`: Repository owner
- `repo`: Repository name
- `workflow_run_id`: Workflow run ID
**Examples:**
```bash
# List all jobs for workflow run 350
gitea-client list-workflow-jobs arcodange DanceLessonsCoach 350
```
### Wait for Job Completion
```bash
skill gitea-client wait-job <owner> <repo> <job_id> [timeout]
```
Wait for a job to complete and return final status.
**Arguments:**
- `owner`: Repository owner
- `repo`: Repository name
- `job_id`: Job ID
- `timeout`: Maximum wait time in seconds (default: 300)
### Comment on PR
```bash
skill gitea-client comment-pr <owner> <repo> <pr_number> <comment>
```
Add a comment to a pull request.
**Arguments:**
- `owner`: Repository owner
- `repo`: Repository name
- `pr_number`: PR number
- `comment`: Comment text (use quotes for multi-word)
### Get PR Status
```bash
skill gitea-client pr-status <owner> <repo> <pr_number>
```
Get the current status of a pull request.
**Arguments:**
- `owner`: Repository owner
- `repo`: Repository name
- `pr_number`: PR number
## Workflows
### Monitor CI/CD Job
```bash
# List recent jobs
skill gitea-client list-jobs owner repo workflow_id 5
# Wait for specific job to complete
skill gitea-client wait-job owner repo job_id 600
# Get job logs if failed
skill gitea-client job-logs owner repo job_id
```
### Diagnose Failed Job
```bash
# Get job status
skill gitea-client job-status owner repo job_id
# List all jobs in the workflow run
skill gitea-client list-workflow-jobs owner repo workflow_run_id
# Fetch logs for specific action job
skill gitea-client action-logs owner repo action_job_id > action_logs.txt
# Fetch workflow run logs
skill gitea-client job-logs owner repo job_id > workflow_logs.txt
# Analyze logs and comment on PR
skill gitea-client comment-pr owner repo pr_number "Job failed: analysis results"
```
### Complete CI Debugging Workflow
```bash
# 1. Find recent failed jobs
skill gitea-client list-jobs owner repo workflow_id 5
# 2. Get status of failed job
skill gitea-client job-status owner repo failed_job_id
# 3. List all jobs in the workflow to find which ones failed
skill gitea-client list-workflow-jobs owner repo workflow_run_id
# 4. Fetch logs for each failed action job
for job_id in 658 659 660; do
skill gitea-client action-logs owner repo $job_id ${job_id}_logs.txt
echo "Saved logs for job $job_id to ${job_id}_logs.txt"
done
# 5. Search for errors in all logs
grep -i "error\|fail\|panic" *_logs.txt
# 6. Comment on PR with findings
skill gitea-client comment-pr owner repo pr_number "Found the issue: missing swagger docs generation"
```
## Examples
### Basic Job Monitoring
```bash
# List last 3 jobs for workflow 5
gitea-client list-jobs myorg myrepo 5 3
# Check status of job 12345
gitea-client job-status myorg myrepo 12345
# Wait up to 10 minutes for job completion
gitea-client wait-job myorg myrepo 12345 600
```
### PR Interaction
```bash
# Get PR status
gitea-client pr-status myorg myrepo 42
# Add comment to PR
gitea-client comment-pr myorg myrepo 42 "Build completed successfully!"
```
## Error Handling
The skill handles common API errors:
- 401 Unauthorized: Check your GITEA_API_TOKEN or GITEA_API_TOKEN_FILE
- 404 Not Found: Verify repository/owner and job/PR IDs
- 429 Too Many Requests: Wait and retry
- 500+ Server Errors: Retry or check Gitea status
## Best Practices
1. **Token Security**: Use GITEA_API_TOKEN_FILE for better security
2. **Rate Limiting**: Be mindful of API rate limits
3. **Error Handling**: Always check command exit codes
4. **Logging**: Redirect output to files for debugging
5. **Timeouts**: Use reasonable timeouts for wait operations
## Implementation Details
The skill uses:
- `curl` for HTTP requests
- `jq` for JSON processing
- Standard shell utilities
- Gitea REST API v1
All API calls include:
- Authorization header with token
- Proper error handling
- JSON response parsing
- Rate limit awareness
## Future Enhancements
- Webhook integration
- Advanced job filtering
- PR review management
- Repository administration
- Team management

View File

@@ -0,0 +1,50 @@
# gitea-client Reference
## Overview
Detailed technical reference for the gitea-client skill.
## Key Concepts
### [Concept 1]
[Detailed explanation]
### [Concept 2]
[Detailed explanation]
## API Reference
### [Function/Method Name]
**Description**: [What it does]
**Parameters**:
- - [Type]: [Description]
- - [Type]: [Description]
**Returns**: [Return type and description]
**Example**:
```bash
[example usage]
```
## Troubleshooting
### [Issue 1]
**Symptoms**: [What the user sees]
**Cause**: [Root cause]
**Solution**: [How to fix it]
### [Issue 2]
**Symptoms**: [What the user sees]
**Cause**: [Root cause]
**Solution**: [How to fix it]

View File

@@ -0,0 +1,13 @@
#!/bin/bash
# Example script for gitea-client skill
set -e
echo "This is an example script for the gitea-client skill"
echo "Replace this with your actual script logic"
# Your script implementation goes here
# Example:
# echo "Processing..."
# [command] [arguments]

View File

@@ -0,0 +1,254 @@
#!/bin/bash
# Gitea Client - Main script for interacting with Gitea API
# Usage: gitea-client.sh <command> [args...]
set -e
# Configuration
GITEA_API_BASE="https://gitea.arcodange.lab/api/v1"
# Get authentication token
get_auth_token() {
if [[ -n "${GITEA_API_TOKEN_FILE:-}" ]]; then
if [[ -f "$GITEA_API_TOKEN_FILE" ]]; then
cat "$GITEA_API_TOKEN_FILE"
return
else
echo "Error: Token file $GITEA_API_TOKEN_FILE not found" >&2
exit 1
fi
fi
if [[ -n "${GITEA_API_TOKEN:-}" ]]; then
echo "$GITEA_API_TOKEN"
return
fi
echo "Error: No Gitea API token provided" >&2
echo "Set either GITEA_API_TOKEN or GITEA_API_TOKEN_FILE environment variable" >&2
exit 1
}
# Make API request
api_request() {
local method="$1"
local endpoint="$2"
local data="${3:-}"
local token=$(get_auth_token)
local url="${GITEA_API_BASE}${endpoint}"
local headers=(
"Authorization: token ${token}"
"Accept: application/json"
"Content-Type: application/json"
)
if [[ "$method" == "GET" ]]; then
curl -s -X GET "$url" -H "${headers[0]}" -H "${headers[1]}"
else
curl -s -X "$method" "$url" -H "${headers[0]}" -H "${headers[1]}" -H "${headers[2]}" -d "$data"
fi
}
# List jobs
cmd_list_jobs() {
local owner="$1"
local repo="$2"
local workflow_id="$3"
local limit="${4:-10}"
if [[ -z "$owner" || -z "$repo" || -z "$workflow_id" ]]; then
echo "Usage: $0 list-jobs <owner> <repo> <workflow_id> [limit]" >&2
exit 1
fi
local endpoint="/repos/${owner}/${repo}/actions/workflows/${workflow_id}/runs?limit=${limit}"
api_request "GET" "$endpoint"
}
# Get job status
cmd_job_status() {
local owner="$1"
local repo="$2"
local job_id="$3"
if [[ -z "$owner" || -z "$repo" || -z "$job_id" ]]; then
echo "Usage: $0 job-status <owner> <repo> <job_id>" >&2
exit 1
fi
local endpoint="/repos/${owner}/${repo}/actions/runs/${job_id}"
api_request "GET" "$endpoint"
}
# Get job logs
cmd_job_logs() {
local owner="$1"
local repo="$2"
local job_id="$3"
local output_file="${4:-}"
if [[ -z "$owner" || -z "$repo" || -z "$job_id" ]]; then
echo "Usage: $0 job-logs <owner> <repo> <job_id> [output_file]" >&2
exit 1
fi
local endpoint="/repos/${owner}/${repo}/actions/runs/${job_id}/logs"
local logs=$(api_request "GET" "$endpoint")
if [[ -n "$output_file" ]]; then
echo "$logs" > "$output_file"
echo "Logs saved to: $output_file"
else
echo "$logs"
fi
}
# Get action job logs
cmd_action_logs() {
local owner="$1"
local repo="$2"
local action_job_id="$3"
local output_file="${4:-}"
if [[ -z "$owner" || -z "$repo" || -z "$action_job_id" ]]; then
echo "Usage: $0 action-logs <owner> <repo> <action_job_id> [output_file]" >&2
exit 1
fi
local endpoint="/repos/${owner}/${repo}/actions/jobs/${action_job_id}/logs"
local logs=$(api_request "GET" "$endpoint")
if [[ -n "$output_file" ]]; then
echo "$logs" > "$output_file"
echo "Logs saved to: $output_file"
else
echo "$logs"
fi
}
# List workflow jobs
cmd_list_workflow_jobs() {
local owner="$1"
local repo="$2"
local workflow_run_id="$3"
if [[ -z "$owner" || -z "$repo" || -z "$workflow_run_id" ]]; then
echo "Usage: $0 list-workflow-jobs <owner> <repo> <workflow_run_id>" >&2
exit 1
fi
local endpoint="/repos/${owner}/${repo}/actions/runs/${workflow_run_id}/jobs"
api_request "GET" "$endpoint"
}
# Wait for job completion
cmd_wait_job() {
local owner="$1"
local repo="$2"
local job_id="$3"
local timeout="${4:-300}"
if [[ -z "$owner" || -z "$repo" || -z "$job_id" ]]; then
echo "Usage: $0 wait-job <owner> <repo> <job_id> [timeout]" >&2
exit 1
fi
local start_time=$(date +%s)
local end_time=$((start_time + timeout))
echo "Waiting for job ${job_id} to complete (timeout: ${timeout}s)..."
while [[ $(date +%s) -lt $end_time ]]; do
local status=$(cmd_job_status "$owner" "$repo" "$job_id" | jq -r '.status')
case "$status" in
"completed")
echo "Job completed successfully"
return 0
;;
"failed")
echo "Job failed"
return 1
;;
"cancelled")
echo "Job was cancelled"
return 2
;;
*)
echo "Current status: ${status}"
sleep 5
;;
esac
done
echo "Timeout reached"
return 3
}
# Comment on PR
cmd_comment_pr() {
local owner="$1"
local repo="$2"
local pr_number="$3"
local comment="$4"
if [[ -z "$owner" || -z "$repo" || -z "$pr_number" || -z "$comment" ]]; then
echo "Usage: $0 comment-pr <owner> <repo> <pr_number> <comment>" >&2
exit 1
fi
local endpoint="/repos/${owner}/${repo}/issues/${pr_number}/comments"
local data="{\"body\": \"${comment}\"}"
api_request "POST" "$endpoint" "$data"
}
# Get PR status
cmd_pr_status() {
local owner="$1"
local repo="$2"
local pr_number="$3"
if [[ -z "$owner" || -z "$repo" || -z "$pr_number" ]]; then
echo "Usage: $0 pr-status <owner> <repo> <pr_number>" >&2
exit 1
fi
local endpoint="/repos/${owner}/${repo}/pulls/${pr_number}"
api_request "GET" "$endpoint"
}
# Main command routing
main() {
local command="${1:-}"
shift || true
case "$command" in
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 "$@" ;;
comment-pr) cmd_comment_pr "$@" ;;
pr-status) cmd_pr_status "$@" ;;
*)
echo "Usage: $0 <command> [args...]" >&2
echo "" >&2
echo "Commands:" >&2
echo " list-jobs <owner> <repo> <workflow_id> [limit]" >&2
echo " job-status <owner> <repo> <job_id>" >&2
echo " job-logs <owner> <repo> <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 " wait-job <owner> <repo> <job_id> [timeout]" >&2
echo " comment-pr <owner> <repo> <pr_number> <comment>" >&2
echo " pr-status <owner> <repo> <pr_number>" >&2
exit 1
;;
esac
}
main "$@"