Cleanup: Remove unnecessary Library folder and keep plug files at root
All checks were successful
Build SilverBullet Plug / build (push) Successful in 31s

This commit is contained in:
2026-02-17 13:45:09 -08:00
parent 62d4ba1006
commit a11c6bd906
947 changed files with 434513 additions and 10 deletions

32
gitea-push-watch/SKILL.md Normal file
View File

@@ -0,0 +1,32 @@
---
name: gitea-push-watch
description: Monitor and debug Gitea Actions after a push. Use when a user asks to check if an action ran or failed on a Gitea instance, and use the provided API token for authentication.
---
# Gitea Push Watch
This skill provides tools to monitor Gitea Actions and debug failures using the Gitea API.
## Workflow
1. **Identify Repository Info**: Extract the Gitea server URL and repository path (e.g., `owner/repo`) from the project context or git remote.
2. **Authenticate**: Use the user-provided API token. Ensure it is passed as a `token <value>` header in API calls.
3. **Monitor Run**: Use the `scripts/gitea_action_monitor.py` script to check the status of the latest run.
4. **Analyze Failures**: If a run fails, use the Gitea API to fetch specific job logs to identify the root cause (e.g., permission issues, network errors).
## Script Usage
```bash
python3 scripts/gitea_action_monitor.py <server_url> <repo_path> <api_token>
```
Example:
```bash
python3 scripts/gitea_action_monitor.py https://gitea.example.com sstent/my-repo MY_TOKEN
```
## Common Gitea API Endpoints
- List runs: `GET /api/v1/repos/{owner}/{repo}/actions/runs`
- Get run details: `GET /api/v1/repos/{owner}/{repo}/actions/runs/{id}`
- List jobs: `GET /api/v1/repos/{owner}/{repo}/actions/runs/{id}/jobs`

View File

@@ -0,0 +1,77 @@
import os
import sys
import json
import urllib.request
import urllib.error
import time
def get_action_runs(server_url, repo, token, limit=1):
url = f"{server_url}/api/v1/repos/{repo}/actions/runs?limit={limit}"
req = urllib.request.Request(url)
req.add_header("Authorization", f"token {token}")
try:
with urllib.request.urlopen(req) as response:
return json.loads(response.read().decode())
except urllib.error.HTTPError as e:
print(f"Error fetching action runs: {e.code} {e.reason}")
return None
except Exception as e:
print(f"Error: {str(e)}")
return None
def monitor_run(server_url, repo, token, run_id):
url = f"{server_url}/api/v1/repos/{repo}/actions/runs/{run_id}"
req = urllib.request.Request(url)
req.add_header("Authorization", f"token {token}")
try:
with urllib.request.urlopen(req) as response:
return json.loads(response.read().decode())
except Exception as e:
print(f"Error monitoring run: {str(e)}")
return None
def main():
if len(sys.argv) < 4:
print("Usage: python3 gitea_action_monitor.py <server_url> <repo> <token>")
sys.exit(1)
server_url = sys.argv[1].rstrip('/')
repo = sys.argv[2]
token = sys.argv[3]
print(f"Checking Gitea Actions for {repo}...")
runs_data = get_action_runs(server_url, repo, token)
if not runs_data or not runs_data.get('workflow_runs'):
print("No action runs found.")
return
latest_run = runs_data['workflow_runs'][0]
run_id = latest_run['id']
status = latest_run['status']
conclusion = latest_run.get('conclusion', 'unknown')
name = latest_run.get('name', 'unnamed')
print(f"Latest Run: {name} (ID: {run_id})")
print(f"Status: {status}")
if status == "running":
print("Waiting for completion...")
for _ in range(10): # Max 10 attempts
time.sleep(10)
run_data = monitor_run(server_url, repo, token, run_id)
if not run_data: break
status = run_data['status']
if status != "running":
conclusion = run_data.get('conclusion', 'unknown')
break
print(".", end="", flush=True)
print(f"
Final Status: {status} ({conclusion})")
else:
print(f"Conclusion: {conclusion}")
if __name__ == "__main__":
main()