feat(tools): workflow_run_trigger

This commit is contained in:
Mathias Bergqvist
2026-05-04 22:25:10 +02:00
parent c4874ae8d1
commit ba172e3db8
6 changed files with 376 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
package gitea
import (
"context"
"encoding/json"
"fmt"
"strconv"
"strings"
)
// DispatchWorkflowArgs is the request body for a workflow_dispatch trigger.
type DispatchWorkflowArgs struct {
Ref string `json:"ref"`
Inputs map[string]any `json:"inputs,omitempty"`
}
// WorkflowRunTrigger holds the run ID extracted from the Location header.
type WorkflowRunTrigger struct {
RunID int64
}
// DispatchWorkflow triggers a workflow_dispatch event and returns the new run ID.
func (c *Client) DispatchWorkflow(ctx context.Context, owner, repo, workflow string, args DispatchWorkflowArgs) (*WorkflowRunTrigger, error) {
p := fmt.Sprintf("/api/v1/repos/%s/%s/actions/workflows/%s/dispatches", owner, repo, workflow)
payload, err := json.Marshal(args)
if err != nil {
return nil, err
}
resp, err := c.doRaw(ctx, "POST", p, payload)
if err != nil {
return nil, err
}
if resp.Status != 204 {
if mapErr := MapStatus(resp.Status, resp.Body); mapErr != nil {
return nil, mapErr
}
return nil, fmt.Errorf("unexpected status %d", resp.Status)
}
location := resp.Headers.Get("Location")
if location == "" {
return nil, fmt.Errorf("missing Location header in dispatch response")
}
// Location is e.g. "/api/v1/repos/o/r/actions/runs/123" — take the last segment.
parts := strings.Split(strings.TrimRight(location, "/"), "/")
if len(parts) == 0 {
return nil, fmt.Errorf("malformed Location: %s", location)
}
runID, err := strconv.ParseInt(parts[len(parts)-1], 10, 64)
if err != nil {
return nil, fmt.Errorf("parse run id from %q: %w", location, err)
}
return &WorkflowRunTrigger{RunID: runID}, nil
}
// WorkflowRun represents a Gitea Actions run.
type WorkflowRun struct {
ID int64 `json:"id"`
Status string `json:"status"` // queued | in_progress | completed
Conclusion string `json:"conclusion"` // success | failure | cancelled | skipped (only when completed)
StartedAt string `json:"started_at"`
HTMLURL string `json:"html_url"`
}
// GetWorkflowRun fetches the status of a specific Actions run.
func (c *Client) GetWorkflowRun(ctx context.Context, owner, repo string, runID int64) (*WorkflowRun, error) {
p := fmt.Sprintf("/api/v1/repos/%s/%s/actions/runs/%d", owner, repo, runID)
body, status, err := c.GetJSON(ctx, p)
if err != nil {
return nil, err
}
if err := MapStatus(status, body); err != nil {
return nil, err
}
var run WorkflowRun
if err := json.Unmarshal(body, &run); err != nil {
return nil, err
}
return &run, nil
}