Demo: emits cross-repo workflow_dispatch on PR events. Stand-in for meta-orca.
Find a file
2026-05-11 15:00:16 +00:00
.gitea/workflows Switch dispatch-source workflow to orca-ubuntu-latest runner 2026-05-11 15:00:16 +00:00
clean-smoke.md clean smoke: full cycle with linter-runner-latest + return_run_details fix 2026-05-11 14:52:34 +00:00
README.md Document cross-repo workflow_dispatch demo and setup 2026-05-10 12:38:03 +00:00

dispatch-source

Demo: emits a cross-repo workflow_dispatch on PR events. Stand-in for meta-orca.

Paired with mporter/dispatch-target, which runs a build and reports status + a comment back to the PR opened here.

Why this exists

Gitea 1.26 has no repository_dispatch event yet (go-gitea/gitea#24132) and no native syntax for "trigger a workflow in another repo on this event" (#32041). The supported building blocks are:

  • on: workflow_dispatch: with declared inputs: (PR #32059, 1.23+)
  • The dispatch API can return the new run_id so the source can deep-link the triggered run (PR #36706, 1.26+)
  • Standard Gitea API for commit statuses and issue comments

So the recommended pattern for "PR on repo A → CI on repo B → feedback to PR on repo A" is a small bridge workflow on A that calls the workflow_dispatch API on B with the PR metadata as inputs, and a workflow on B that does the build then posts a status + comment back via API.

Architecture

                              ┌──────────────────────────┐
  PR opened/synced  ────────▶ │ dispatch-source          │
                              │  .gitea/workflows/       │
                              │  dispatch-build.yml      │
                              │  • POST .../dispatches   │
                              │  • set "pending" status  │
                              └──────────┬───────────────┘
                                         │ run_id, target run URL
                                         ▼
                              ┌──────────────────────────┐
                              │ dispatch-target          │
                              │  .gitea/workflows/       │
                              │  build-from-pr.yml       │
                              │  • checkout PR head      │
                              │  • build                 │
                              │  • on always:            │
                              │     POST status to       │
                              │     dispatch-source/     │
                              │     statuses + comment   │
                              └──────────────────────────┘

Setup

1. Mint a token

Gitea PAT (or any token) with at minimum write:repository so it can call:

  • POST /api/v1/repos/mporter/dispatch-target/actions/workflows/build-from-pr.yml/dispatches
  • POST /api/v1/repos/mporter/dispatch-source/statuses/{sha}
  • POST /api/v1/repos/mporter/dispatch-source/issues/{n}/comments

2. Add it as a secret in both repos

Settings → Actions → Secrets → add DISPATCH_TOKEN with the token value. Both the source and target workflows reference ${{ secrets.DISPATCH_TOKEN }}.

3. Prime the target workflow (one manual run)

The dispatch API will reject calls to a workflow it hasn't seen yet. Visit dispatch-target → Actions → Build from upstream PR and click Run workflow on main once with these placeholder values:

Input Value
pr_number 1
pr_head_sha 0000000000000000000000000000000000000000
pr_head_ref priming
source_repo mporter/dispatch-source

The run is expected to end in failure — the final feedback step posts a commit status to a non-existent SHA and a comment to a non-existent PR, so both curl -fsS calls 404. That failure is harmless and only appears on dispatch-target's Actions tab. The point of this run is purely to register the workflow with the API so subsequent programmatic dispatches succeed.

4. Smoke test end-to-end

  1. Clone this repo, git checkout -b feature/x, make any trivial change, push, open a PR back to main.
  2. PR page should show a pending status dispatch-target/build within seconds.
  3. dispatch-target Actions tab shows a new run with the four inputs visible in the run view.
  4. After it finishes, the PR's status flips to success and a new comment appears: **dispatch-target build success** — [run log](...).
  5. Push another commit to feature/x. A new status + comment cycle should fire (proves the synchronize plumbing).
  6. Negative test: edit dispatch-target/.gitea/workflows/build-from-pr.yml to add exit 1 in the echo step, push to main, retrigger the source PR. Confirm the PR status flips to failure with the comment text matching.

Workflow

.gitea/workflows/dispatch-build.yml fires on pull_request (opened, synchronize, reopened):

  1. POSTs to the target's workflow_dispatch API with ?returnRunID=true, passing PR number, head SHA, head ref, and source repo as inputs.
  2. Captures the returned run_id from the dispatch response and constructs the target run URL.
  3. Sets a pending commit status on the PR head SHA pointing at that URL, so reviewers see a yellow check on the PR right away.

The target's workflow takes over from there.

Promoting to production (meta-orca → orca-setup)

When you're satisfied with the demo, copy the same two YAML files into:

  • orca/meta-orca/.gitea/workflows/dispatch-build.yml — adjust TARGET_OWNER=orca, TARGET_REPO=orca-setup.
  • orca/orca-setup/.gitea/workflows/build-from-pr.yml — replace the echo step with the real build flow. After actions/checkout of orca-setup, pin the meta-orca submodule (or whisk layer) to inputs.pr_head_sha:
    cd layers/meta-orca   # adjust to actual path
    git fetch origin "refs/pull/${{ inputs.pr_number }}/head"
    git checkout "${{ inputs.pr_head_sha }}"
    
    then run the existing init-build-env --product ... --mode ... flow.