feat: add workflow dispatch and run inspection - #1031
Conversation
Workflow discovery, run reads, and dispatch are independent optional provider contracts so GitHub support does not leak into server or frontend boundaries.
A bounded node parser preserves GitHub workflow input types and declaration order while rejecting ambiguous schemas before they reach dispatch forms.
Require a single YAML document and reject unknown workflow_dispatch or input-definition fields so malformed schemas cannot be silently normalized.
GitHub workflow discovery, runs, jobs, environments, and dispatch now normalize through the provider boundary and preserve personal-credential attribution for writes.
Huma routes validate live workflow definitions and dispatch inputs behind repository identity, capability, credential, and rate-limit gates.
Actions stays disabled by default and one persisted mode switch controls every workflow surface and polling owner while leaving provider APIs available.
Task 4 made read_workflows, read_workflow_runs, and workflow_dispatch required members of the generated ProviderCapabilitiesResponse type. Add fail-closed local defaults (false) to each of the four defaultProviderCapabilities objects so the front-end sources compile before provider data loads. No runtime, markup, generated code, or behavior change.
Effect services now deduplicate reads, bound polling and reconciliation, and retain non-idempotent dispatch outcomes across component navigation without replaying writes.
Install cleanup and admitted dispatch handoffs without interruption gaps, restart missed shared demand exactly once, and clear interrupted loading projections when Actions is disabled.
One accessible form renders provider-normalized inputs and one compact run surface reveals jobs while keeping logs and artifacts on the provider.
Preserve definition-scoped drafts, fence duplicate commands, expose accessible validation, and allow only safe provider run links.
Refresh typed drafts on definition changes, release acknowledged submissions for a fresh idle cycle, and keep input and reload ownership collision-free.
Keep reload admission fenced across same-kind controlled updates while resetting only after a real conflict exit or dialog remount.
Enabled users can select a provider repository, dispatch manual workflows, and follow current runs without exposing any Actions demand while the mode is off.
Keep provider read failures visible beside retained data and preserve full-height medium layouts when the repository rail is absent.
The existing responsive Actions menu now survives merged PRs and opens the same explicit workflow confirmation used by the Actions page.
The default-off Actions mode is now covered by a stateful provider fixture, full browser workflow, user guidance, and durable provider, error, polling, and PR interaction contracts.
Failed visible catalog reads now wait for the existing idle cadence instead of restarting the repository loop without delay.
Apply gofmt to the remaining feature-touched server and e2e files so repository formatting hooks accept the completed workflow Actions branch.
Keep pull request lifecycle decisions in the primary action row and group workflow dispatch with workspace utilities. Preserve a single measured Actions overflow for constrained widths while anchoring the wide workflow menu directly to its trigger.
Preserve the workflow dispatch feature while adopting current phone action layouts, provider route ownership, and the pinned lint policy. Keep optional fixture capabilities visible in full-stack e2e coverage.
Maintainers had to leave Forge to trigger provider workflows or look at recent runs, which hurts most when the provider web UI is slow or down. This brings the contributed implementation from issue #1003 into the repository: an opt-in Actions workspace listing manual workflows, recent runs, jobs, and steps; typed dispatch inputs, environments, pull request head-ref defaults, and stale-definition recovery; and a Run workflow entry on pull requests for desktop and phone layouts. The contributed branch was merged from a fork rather than replayed so the original authorship stays intact. Main had since added two fields to the pull detail settings type, so one test fixture in the workflow actions pull detail browser test now spreads the store defaults instead of building the settings object by hand. Closes #1003 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KuhHYTTk1QzpastWi4zD7T
roborev: Combined Review (
|
…-add-workflow-dispatch-and-run-inspection-to-forge
CI could not build the internal/server test package for the workflow Actions branch, which failed the Go, race, and lint jobs at once. Main had moved the package-local doJSON test helper into the shared testutil package in the same window that the branch added two new callers, and the merge kept both without a compile error until they met in CI. This merges current main and points the two workflow Actions call sites at the shared helper. Local Go, lint, and guardrail checks now pass; the remaining local-only failures are tmux and pty timing tests that pass when run without competing load. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KuhHYTTk1QzpastWi4zD7T
roborev: Combined Review (
|
…lker The contributed branch shipped a 400-line hand-written walker over the YAML node tree to find workflow_dispatch inputs. The maintainer does not want to own a GitHub Actions grammar in this repository, so this replaces it with actionlint, which already models the workflow file including typed dispatch inputs, choice options, defaults, and required flags. Forge keeps only the projection onto the provider-neutral definition and the conversion of string defaults into their declared type. actionlint validates the whole file, so fixtures now carry a jobs section like any real workflow, and cases the old walker rejected but GitHub accepts (a boolean-looking string default, a numeric description) are dropped. go.mod pins actionlint to the fork commit behind rhysd/actionlint#730. The released v1.7.12 compiles against yaml/v4 rc.3 and fails to build with the rc.6 already required here; that PR is the upstream fix and the replace directive should be removed once it lands in a release. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
roborev: Combined Review (
|
The contributed frontend carried a 1,200-line Effect service that polled workflow runs, queued dispatches per repository, and matched a dispatched run by actor and time window in the browser. That logic depends on provider state the server already owns, and a browser tab is the wrong place to keep it alive. The dispatch route now returns a dispatch_id and, after the provider accepts, a server goroutine locates the created run, watches it until it completes, and publishes workflow_dispatch_progress events over the existing SSE hub. The browser store shrinks to fetch-on-demand reads plus an event handler that updates the dispatch cycle and the run list in place. No workflow polling remains in the frontend. The workflowapi handler takes a small Runtime interface for publishing events and running background work instead of function fields. The "uncertain" outcome no longer shows candidate runs, since the browser no longer scans runs itself; it tells the user to check the provider. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
roborev: Combined Review (
|
Brings the contributed workflow Actions implementation from #1003 into the repository so maintainers can trigger provider workflows and inspect recent runs without leaving Forge, which matters most when the provider web UI is slow or unavailable.
workflow_dispatch_progressevents over the existing SSE stream. The browser does no workflow polling.Two things changed from the contributed branch during review:
Screenshot from the contributor's implementation:
Closes #1003
🤖 Generated with Claude Code