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 }