fix(workflow_run_trigger): 204 dispatch is success; resolve run via listing (#41)
Gitea's workflow_dispatch endpoint returns 204 No Content with no Location header. DispatchWorkflow required that header, so every successful dispatch errored with "missing Location header" and never yielded a run ID — making the tool unusable for CAD dispatch. - DispatchWorkflow now returns error-only; 204 = success, no Location needed. Body already carried ref+inputs; kept and covered by test. - Tool snapshots the newest existing workflow_dispatch run before dispatch, then polls ListWorkflowRuns after and returns the newest run with ID above that baseline (avoids returning a stale prior run). Falls back to an honest "dispatched, run not yet registered" result rather than failing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,9 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// Gitea's dispatch endpoint returns 204 No Content with NO Location header.
|
||||
// Dispatch must succeed and forward ref+inputs in the body; the run ID is
|
||||
// resolved separately by the tool via ListWorkflowRuns.
|
||||
func TestDispatchWorkflow(t *testing.T) {
|
||||
var gotBody []byte
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -22,18 +25,17 @@ func TestDispatchWorkflow(t *testing.T) {
|
||||
var err error
|
||||
gotBody, err = io.ReadAll(r.Body)
|
||||
assert.NoError(t, err)
|
||||
w.Header().Set("Location", "/api/v1/repos/o/r/actions/runs/789")
|
||||
// No Location header — matches real Gitea.
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
c := gitea.NewClient(srv.URL, "tok")
|
||||
result, err := c.DispatchWorkflow(context.Background(), "o", "r", "ci.yml", gitea.DispatchWorkflowArgs{
|
||||
err := c.DispatchWorkflow(context.Background(), "o", "r", "ci.yml", gitea.DispatchWorkflowArgs{
|
||||
Ref: "main",
|
||||
Inputs: map[string]any{"env": "prod"},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(789), result.RunID)
|
||||
|
||||
var body map[string]any
|
||||
require.NoError(t, json.Unmarshal(gotBody, &body))
|
||||
@@ -43,19 +45,6 @@ func TestDispatchWorkflow(t *testing.T) {
|
||||
assert.Equal(t, "prod", inputs["env"])
|
||||
}
|
||||
|
||||
func TestDispatchWorkflowMissingLocation(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// 204 but no Location header
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
c := gitea.NewClient(srv.URL, "tok")
|
||||
_, err := c.DispatchWorkflow(context.Background(), "o", "r", "ci.yml", gitea.DispatchWorkflowArgs{Ref: "main"})
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "Location")
|
||||
}
|
||||
|
||||
func TestDispatchWorkflowError404(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
@@ -63,7 +52,7 @@ func TestDispatchWorkflowError404(t *testing.T) {
|
||||
defer srv.Close()
|
||||
|
||||
c := gitea.NewClient(srv.URL, "tok")
|
||||
_, err := c.DispatchWorkflow(context.Background(), "o", "r", "ci.yml", gitea.DispatchWorkflowArgs{Ref: "main"})
|
||||
err := c.DispatchWorkflow(context.Background(), "o", "r", "ci.yml", gitea.DispatchWorkflowArgs{Ref: "main"})
|
||||
require.Error(t, err)
|
||||
assert.True(t, errors.Is(err, gitea.ErrNotFound))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user