feat(dispatch): implement dispatch-workflow.sh with dispatch, poll, and timeout
CI — gitea-ci-library / feature (push) Failing after 1s
CI — gitea-ci-library / master (push) Has been skipped

Add dispatch-workflow.sh script that dispatches a Gitea workflow
in another repository and polls synchronously for completion.
Refactor mock-api.sh to use Python3 HTTP server with sequence
support, enabling stateful poll-response simulation in tests.
This commit is contained in:
moilanik
2026-06-08 16:07:35 +03:00
parent dcc51f9f5c
commit 00b99f3841
8 changed files with 460 additions and 19 deletions
+130
View File
@@ -0,0 +1,130 @@
#!/usr/bin/env bats
setup() {
source tests/helpers/mock-api.sh
export GITEA_API_URL="http://localhost:18080"
export GITEA_TOKEN="test-token-abc123"
export DISPATCH_POLL_INTERVAL="0.1"
}
teardown() {
mock_stop
}
@test "dispatch succeeds: POST 201, poll running x3 then success → exit 0" {
mock_set_sequence '[
{"code":201},
{"code":200,"body":{"workflow_runs":[{"id":1,"status":"running"}]}},
{"code":200,"body":{"id":1,"status":"running"}},
{"code":200,"body":{"id":1,"status":"running"}},
{"code":200,"body":{"id":1,"status":"running"}},
{"code":200,"body":{"id":1,"status":"completed","conclusion":"success"}}
]'
mock_start
run bash scripts/dispatch-workflow.sh "test-owner/test-repo" "test.yml" "main" '{"version":"1.2.3"}'
[ "$status" -eq 0 ]
}
@test "dispatch: poll returns failure conclusion → exit 1" {
mock_set_sequence '[
{"code":201},
{"code":200,"body":{"workflow_runs":[{"id":1,"status":"running"}]}},
{"code":200,"body":{"id":1,"status":"running"}},
{"code":200,"body":{"id":1,"status":"completed","conclusion":"failure"}}
]'
mock_start
run bash scripts/dispatch-workflow.sh "test-owner/test-repo" "test.yml" "main" '{"version":"1.2.3"}'
[ "$status" -eq 1 ]
}
@test "dispatch: poll returns cancelled conclusion → exit 1" {
mock_set_sequence '[
{"code":201},
{"code":200,"body":{"workflow_runs":[{"id":1,"status":"running"}]}},
{"code":200,"body":{"id":1,"status":"running"}},
{"code":200,"body":{"id":1,"status":"completed","conclusion":"cancelled"}}
]'
mock_start
run bash scripts/dispatch-workflow.sh "test-owner/test-repo" "test.yml" "main" '{"version":"1.2.3"}'
[ "$status" -eq 1 ]
}
@test "timeout: poll never completes, exceeds timeout_minutes → exit 124" {
mock_set_sequence '[
{"code":201},
{"code":200,"body":{"workflow_runs":[{"id":1,"status":"running"}]}},
{"code":200,"body":{"id":1,"status":"running"}},
{"code":200,"body":{"id":1,"status":"running"}},
{"code":200,"body":{"id":1,"status":"running"}},
{"code":200,"body":{"id":1,"status":"running"}},
{"code":200,"body":{"id":1,"status":"running"}},
{"code":200,"body":{"id":1,"status":"running"}},
{"code":200,"body":{"id":1,"status":"running"}},
{"code":200,"body":{"id":1,"status":"running"}}
]'
mock_start
run bash scripts/dispatch-workflow.sh "test-owner/test-repo" "test.yml" "main" '{"version":"1.2.3"}' "0.001"
[ "$status" -eq 124 ]
}
@test "dispatch API returns 500 → exit 1" {
mock_set_sequence '[
{"code":500}
]'
mock_start
run bash scripts/dispatch-workflow.sh "test-owner/test-repo" "test.yml" "main" '{"version":"1.2.3"}'
[ "$status" -eq 1 ]
}
@test "POST dispatch is called with correct URL and payload" {
mock_set_sequence '[
{"code":201},
{"code":200,"body":{"workflow_runs":[{"id":1,"status":"running"}]}},
{"code":200,"body":{"id":1,"status":"completed","conclusion":"success"}}
]'
mock_start
run bash scripts/dispatch-workflow.sh "test-owner/test-repo" "test.yml" "main" '{"version":"1.2.3"}'
[ "$status" -eq 0 ]
path=$(mock_get_first_request_path)
[[ "$path" == *"/api/v1/repos/test-owner/test-repo/actions/workflows/test.yml/dispatches"* ]]
method=$(mock_get_first_request_method)
[[ "$method" == "POST" ]]
body=$(mock_get_first_request_body)
[[ "$body" == *'"ref":"main"'* ]]
[[ "$body" == *'"inputs"'* ]]
[[ "$body" == *'"version":"1.2.3"'* ]]
}
@test "missing GITEA_API_URL → exit 1 with error message" {
unset GITEA_API_URL
run bash scripts/dispatch-workflow.sh "test-owner/test-repo" "test.yml" "main" '{"version":"1.2.3"}'
[ "$status" -eq 1 ]
[[ "$output" == *"ERROR"* || "$output" == *"GITEA_API_URL"* ]]
}
@test "missing GITEA_TOKEN → exit 1 with error message" {
unset GITEA_TOKEN
run bash scripts/dispatch-workflow.sh "test-owner/test-repo" "test.yml" "main" '{"version":"1.2.3"}'
[ "$status" -eq 1 ]
[[ "$output" == *"ERROR"* || "$output" == *"GITEA_TOKEN"* ]]
}
@test "missing target_repo argument → exit 1" {
run bash scripts/dispatch-workflow.sh "" "test.yml" "main" '{}'
[ "$status" -eq 1 ]
}
@test "missing workflow_file argument → exit 1" {
run bash scripts/dispatch-workflow.sh "test-owner/test-repo" "" "main" '{}'
[ "$status" -eq 1 ]
}
@test "missing ref argument → exit 1" {
run bash scripts/dispatch-workflow.sh "test-owner/test-repo" "test.yml" "" '{}'
[ "$status" -eq 1 ]
}
@test "missing inputs_json argument → exit 1" {
run bash scripts/dispatch-workflow.sh "test-owner/test-repo" "test.yml" "main" ""
[ "$status" -eq 1 ]
}