Both ForgeMade and Tags took the tool's wrapper for the pull request / the tag list, so every forge-made merge read "#0 is not merged" and bridge_tags failed, leaving builds unnumbered. Quick fix: unwrap "result" in forgeAPI (the one Go reader of gitea_api). Thorough fix (chosen, the kind was met twice and hid behind a drifted fake): bridge.API answers what the tool answers, forgeBody is the one reader of that shape and refuses an answer without a result, naming it; ForgeMade refuses number 0 as "no pull request"; the unit fakes answer the tool's real wrapped shape, with rows for the bare body. Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
67 lines
2.9 KiB
Go
67 lines
2.9 KiB
Go
package bridge
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
// ForgePull is a pull request as the forge itself says it: what the bridge needs of a merge made on the forge, not
|
|
// through the gate (a recovery merge or the operator's own, which the gate holds no merge of; issue 1966).
|
|
type ForgePull struct {
|
|
Number int
|
|
Branch string // the pull request's head branch
|
|
Head string // the head commit
|
|
Merge string // the merge commit into the trunk
|
|
}
|
|
|
|
// ForgeMade reads, through the forge module's gitea_api (the path the bridge reads the forge by), the merged pull
|
|
// request whose merge commit is merge: by number when number is given (the pull request's merge commit must then equal
|
|
// merge), else by the merge commit (the forge's commit-to-pull-request lookup). A pull request not merged, merged into
|
|
// another branch than the trunk, or merged at another commit is refused.
|
|
func ForgeMade(api API, owner, repo string, number int, merge string) (ForgePull, error) {
|
|
path := fmt.Sprintf("/repos/%s/%s/commits/%s/pull", url.PathEscape(owner), url.PathEscape(repo), url.PathEscape(merge))
|
|
if number > 0 {
|
|
path = fmt.Sprintf("/repos/%s/%s/pulls/%d", url.PathEscape(owner), url.PathEscape(repo), number)
|
|
}
|
|
raw, err := api(path)
|
|
if err != nil {
|
|
return ForgePull{}, fmt.Errorf("the forge did not answer %s: %w", path, err)
|
|
}
|
|
body, err := forgeBody(raw)
|
|
if err != nil {
|
|
return ForgePull{}, fmt.Errorf("the forge's answer for %s: %w", path, err)
|
|
}
|
|
var p struct {
|
|
Number int `json:"number"`
|
|
Merged bool `json:"merged"`
|
|
MergeCommitSHA string `json:"merge_commit_sha"`
|
|
Head struct {
|
|
Label string `json:"label"`
|
|
SHA string `json:"sha"`
|
|
} `json:"head"`
|
|
Base struct {
|
|
Ref string `json:"ref"`
|
|
} `json:"base"`
|
|
}
|
|
if err := json.Unmarshal(body, &p); err != nil {
|
|
return ForgePull{}, fmt.Errorf("the forge's answer for %s is no pull request: %w", path, err)
|
|
}
|
|
switch {
|
|
case p.Number == 0:
|
|
return ForgePull{}, fmt.Errorf("the forge's answer for %s is no pull request (no number)", path)
|
|
case !p.Merged:
|
|
return ForgePull{}, fmt.Errorf("the forge says the pull request %s/%s#%d is not merged", owner, repo, p.Number)
|
|
case p.MergeCommitSHA != merge:
|
|
return ForgePull{}, fmt.Errorf("the forge says %s/%s#%d was merged at %s, not at %s", owner, repo, p.Number, p.MergeCommitSHA, merge)
|
|
case p.Base.Ref != Trunk:
|
|
return ForgePull{}, fmt.Errorf("the forge says %s/%s#%d was merged into %s, not the trunk %s", owner, repo, p.Number, p.Base.Ref, Trunk)
|
|
}
|
|
// For a merged pull request the forge's head.ref is "refs/pull/N/head"; the branch is in head.label (same-repository pull requests).
|
|
if p.Head.Label == "" || strings.HasPrefix(p.Head.Label, "refs/") {
|
|
return ForgePull{}, fmt.Errorf("the forge gives no head branch for %s/%s#%d (label %q)", owner, repo, p.Number, p.Head.Label)
|
|
}
|
|
return ForgePull{Number: p.Number, Branch: p.Head.Label, Head: p.Head.SHA, Merge: p.MergeCommitSHA}, nil
|
|
}
|