markdown · 3209 bytes Raw Blame History

Actions workflows

Read-only access to the workflow files in a repo plus the workflow_dispatch trigger that the HTML "Run workflow" button fires. Workflow runs themselves live at the Actions workflow runs surface.

Scopes:

  • repo:read on the list / single-workflow GETs
  • repo:write on the dispatch POST (same trust boundary as the HTML UI, where any pusher can run a workflow)

Endpoints

GET  /api/v1/repos/{owner}/{repo}/actions/workflows                          list discovered workflows
GET  /api/v1/repos/{owner}/{repo}/actions/workflows/{workflow}               single workflow
POST /api/v1/repos/{owner}/{repo}/actions/workflows/{workflow}/dispatches    workflow_dispatch

Discovery model

shithub does not keep a workflows table. The list endpoint walks .shithub/workflows/ in the git tree at the repo's default-branch HEAD (or ?ref= when provided) and parses each *.yml/*.yaml file to extract its name:. Files that fail to parse still appear in the listing — with their basename as the name — so the listing reflects ground truth rather than silently dropping broken workflows.

The {workflow} path segment is the workflow id or file selector. The id field on each entry is a deterministic 64-bit hash of the file path so gh-shaped clients that pass workflow_id still work: both ci.yml (basename), .shithub/workflows/ci.yml (full path), and the numeric id are accepted on the single-workflow GET. The dispatch endpoint accepts only the basename or full path (the numeric id is rejected with 400 to keep dispatch a single round-trip; clients with only an id should hit the list first to resolve the path).

List response

[
  {
    "id":    7142839129843290000,
    "name":  "CI",
    "path":  ".shithub/workflows/ci.yml",
    "file":  "ci.yml",
    "state": "active"
  }
]

state is always "active" for now — enable/disable knobs land in a follow-up PR alongside a workflow_disabled table.

Dispatch request

POST /api/v1/repos/alice/demo/actions/workflows/ci.yml/dispatches
Content-Type: application/json

{
  "ref":    "trunk",
  "inputs": { "env": "prod", "debug": "true" }
}
  • ref defaults to the repo's default branch when omitted.
  • inputs must match the workflow's declared on.workflow_dispatch.inputs:
    • Unknown inputs → 400 invalid_request.
    • Required (non-boolean) inputs missing → 400.
    • Booleans must be "true" / "false" strings.
    • Choices must match one of the declared options.
  • A workflow without on.workflow_dispatch returns 400.
  • Successful dispatch returns 204 No Content. The run shows up in the actions runs feed shortly after the trigger pipeline enqueues it.

Errors

Status Cause
400 Workflow has no on.workflow_dispatch, or inputs malformed.
400 Numeric id passed to dispatch (use basename or full path).
403 PAT lacks repo:write.
404 Repo, ref, or workflow file unknown.
View source
1 # Actions workflows
2
3 Read-only access to the workflow files in a repo plus the
4 `workflow_dispatch` trigger that the HTML "Run workflow" button
5 fires. Workflow runs themselves live at the
6 [Actions workflow runs](./actions-runs.md) surface.
7
8 Scopes:
9
10 - `repo:read` on the list / single-workflow GETs
11 - `repo:write` on the dispatch POST (same trust boundary as the
12 HTML UI, where any pusher can run a workflow)
13
14 ## Endpoints
15
16 ```
17 GET /api/v1/repos/{owner}/{repo}/actions/workflows list discovered workflows
18 GET /api/v1/repos/{owner}/{repo}/actions/workflows/{workflow} single workflow
19 POST /api/v1/repos/{owner}/{repo}/actions/workflows/{workflow}/dispatches workflow_dispatch
20 ```
21
22 ## Discovery model
23
24 shithub does not keep a `workflows` table. The list endpoint walks
25 `.shithub/workflows/` in the git tree at the repo's default-branch
26 HEAD (or `?ref=` when provided) and parses each `*.yml`/`*.yaml`
27 file to extract its `name:`. Files that fail to parse still appear
28 in the listing — with their basename as the name — so the listing
29 reflects ground truth rather than silently dropping broken
30 workflows.
31
32 The `{workflow}` path segment is the workflow id or file selector.
33 The `id` field on each entry is a deterministic 64-bit hash of the
34 file path so gh-shaped clients that pass `workflow_id` still work:
35 both `ci.yml` (basename), `.shithub/workflows/ci.yml` (full path),
36 and the numeric id are accepted on the single-workflow GET. The
37 dispatch endpoint accepts only the basename or full path (the
38 numeric id is rejected with 400 to keep dispatch a single
39 round-trip; clients with only an id should hit the list first to
40 resolve the path).
41
42 ## List response
43
44 ```json
45 [
46 {
47 "id": 7142839129843290000,
48 "name": "CI",
49 "path": ".shithub/workflows/ci.yml",
50 "file": "ci.yml",
51 "state": "active"
52 }
53 ]
54 ```
55
56 `state` is always `"active"` for now — enable/disable knobs land
57 in a follow-up PR alongside a `workflow_disabled` table.
58
59 ## Dispatch request
60
61 ```
62 POST /api/v1/repos/alice/demo/actions/workflows/ci.yml/dispatches
63 Content-Type: application/json
64
65 {
66 "ref": "trunk",
67 "inputs": { "env": "prod", "debug": "true" }
68 }
69 ```
70
71 - `ref` defaults to the repo's default branch when omitted.
72 - `inputs` must match the workflow's declared
73 `on.workflow_dispatch.inputs`:
74 - Unknown inputs → `400 invalid_request`.
75 - Required (non-boolean) inputs missing → 400.
76 - Booleans must be `"true"` / `"false"` strings.
77 - Choices must match one of the declared options.
78 - A workflow without `on.workflow_dispatch` returns 400.
79 - Successful dispatch returns `204 No Content`. The run shows up in
80 the [actions runs](./actions-runs.md) feed shortly after the
81 trigger pipeline enqueues it.
82
83 ## Errors
84
85 | Status | Cause |
86 |------:|--------------------------------------------------------------|
87 | 400 | Workflow has no `on.workflow_dispatch`, or inputs malformed. |
88 | 400 | Numeric id passed to dispatch (use basename or full path). |
89 | 403 | PAT lacks `repo:write`. |
90 | 404 | Repo, ref, or workflow file unknown. |