Compare commits
2
Commits
v0.13.0
...
2bb1fef543
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bb1fef543 | ||
|
|
ee9ac99c40 |
@@ -0,0 +1,52 @@
|
|||||||
|
# Canonical golangci-lint configuration for the estate's Go repos (infra#309
|
||||||
|
# pattern: one canonical file here, a byte-identical copy in each adopter,
|
||||||
|
# and the drift gate in THIS repo comparing sha256).
|
||||||
|
#
|
||||||
|
# Why this exists: 26 Go repos, 3 had a lint config, and all three were
|
||||||
|
# different. The 23 without one ran golangci-lint's v2 default set, which
|
||||||
|
# does NOT include a formatter -- so gofmt/gofumpt drift went uncaught until
|
||||||
|
# it was found by hand (dma-cli#12: two files drifted, nothing flagged them).
|
||||||
|
#
|
||||||
|
# The two configs this replaces (cobalt-dingo, coo-agent) were near-identical
|
||||||
|
# copies of each other AND both invalid under v2: they carried v1-style
|
||||||
|
# `linters-settings` and `issues.exclude-rules` keys, which `golangci-lint
|
||||||
|
# config verify` rejects outright. Their revive settings and test exclusions
|
||||||
|
# were therefore not in effect. Consolidating fixes that too.
|
||||||
|
#
|
||||||
|
# Per-repo variation does NOT belong here -- this file must stay byte-identical
|
||||||
|
# across adopters so the gate is a checksum, not a diff a human has to judge.
|
||||||
|
# A repo with a genuine exception (agentsquad excludes its seeded-bug fixture
|
||||||
|
# tree, which exists precisely to contain broken code) keeps its own config and
|
||||||
|
# is not listed as an adopter.
|
||||||
|
|
||||||
|
version: "2"
|
||||||
|
|
||||||
|
linters:
|
||||||
|
default: none
|
||||||
|
enable:
|
||||||
|
- errcheck # unchecked errors
|
||||||
|
- govet # suspicious constructs
|
||||||
|
- staticcheck # broad static analysis
|
||||||
|
- unused # unused code
|
||||||
|
- misspell # spelling
|
||||||
|
- revive # idiomatic Go
|
||||||
|
- exhaustive # exhaustive switch on enums
|
||||||
|
|
||||||
|
settings:
|
||||||
|
revive:
|
||||||
|
rules:
|
||||||
|
- name: var-naming
|
||||||
|
severity: warning
|
||||||
|
|
||||||
|
exclusions:
|
||||||
|
rules:
|
||||||
|
# Test files: table-driven cases legitimately carry unused struct fields
|
||||||
|
# and long functions.
|
||||||
|
- path: _test\.go
|
||||||
|
linters:
|
||||||
|
- revive
|
||||||
|
- unused
|
||||||
|
|
||||||
|
formatters:
|
||||||
|
enable:
|
||||||
|
- gofumpt
|
||||||
@@ -27,8 +27,8 @@ func TestEmptyPathSegmentRejectedBeforeNetwork(t *testing.T) {
|
|||||||
c := gitea.NewClient(srv.URL, "tok")
|
c := gitea.NewClient(srv.URL, "tok")
|
||||||
|
|
||||||
paths := []string{
|
paths := []string{
|
||||||
"/api/v1/repos/mathias//issues", // empty repo
|
"/api/v1/repos/mathias//issues", // empty repo
|
||||||
"/api/v1/repos//gitea-mcp/contents/", // empty owner
|
"/api/v1/repos//gitea-mcp/contents/", // empty owner
|
||||||
"/api/v1/repos/mathias//issues?state=open", // empty repo before query
|
"/api/v1/repos/mathias//issues?state=open", // empty repo before query
|
||||||
}
|
}
|
||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
|
|||||||
@@ -255,4 +255,3 @@ func (c *Client) GetRepo(ctx context.Context, owner, name string) (*Repo, error)
|
|||||||
}
|
}
|
||||||
return &r, nil
|
return &r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,8 +79,8 @@ func TestCreateRepo_Org(t *testing.T) {
|
|||||||
|
|
||||||
c := gitea.NewClient(srv.URL, "tok")
|
c := gitea.NewClient(srv.URL, "tok")
|
||||||
r, err := c.CreateRepo(context.Background(), gitea.CreateRepoArgs{
|
r, err := c.CreateRepo(context.Background(), gitea.CreateRepoArgs{
|
||||||
Name: "infra",
|
Name: "infra",
|
||||||
Org: "hyperguild",
|
Org: "hyperguild",
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "hyperguild/infra", r.FullName)
|
assert.Equal(t, "hyperguild/infra", r.FullName)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ProtocolVersion = "2025-03-26"
|
ProtocolVersion = "2025-03-26"
|
||||||
maxRequestBodyBytes = 1 << 20 // 1 MiB
|
maxRequestBodyBytes = 1 << 20 // 1 MiB
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ type echoTool struct{}
|
|||||||
func (echoTool) Descriptor() registry.ToolDescriptor {
|
func (echoTool) Descriptor() registry.ToolDescriptor {
|
||||||
return registry.ToolDescriptor{Name: "echo", Description: "echoes its input"}
|
return registry.ToolDescriptor{Name: "echo", Description: "echoes its input"}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (echoTool) Call(_ context.Context, args json.RawMessage) (json.RawMessage, error) {
|
func (echoTool) Call(_ context.Context, args json.RawMessage) (json.RawMessage, error) {
|
||||||
return args, nil
|
return args, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,12 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
const branchCheckExistsResp = `{"name":"feat/x","commit":{"id":"abc","url":"http://example.com"}}`
|
const (
|
||||||
const createBranchResp = `{"name":"feat/new","commit":{"id":"abc","url":"http://example.com"}}`
|
branchCheckExistsResp = `{"name":"feat/x","commit":{"id":"abc","url":"http://example.com"}}`
|
||||||
const upsertFileResp = `{"content":{"path":"doc.md","sha":"filsha","html_url":"http://example.com/doc.md"},"commit":{"sha":"cmt1","html_url":"http://example.com/commit/cmt1"}}`
|
createBranchResp = `{"name":"feat/new","commit":{"id":"abc","url":"http://example.com"}}`
|
||||||
const getRepoResp = `{"name":"myrepo","full_name":"owner/myrepo","default_branch":"main"}`
|
upsertFileResp = `{"content":{"path":"doc.md","sha":"filsha","html_url":"http://example.com/doc.md"},"commit":{"sha":"cmt1","html_url":"http://example.com/commit/cmt1"}}`
|
||||||
|
getRepoResp = `{"name":"myrepo","full_name":"owner/myrepo","default_branch":"main"}`
|
||||||
|
)
|
||||||
|
|
||||||
func TestFileWriteBranchCreatesBranchAndFile(t *testing.T) {
|
func TestFileWriteBranchCreatesBranchAndFile(t *testing.T) {
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const (
|
|||||||
|
|
||||||
func (t *TBDShip) Descriptor() registry.ToolDescriptor {
|
func (t *TBDShip) Descriptor() registry.ToolDescriptor {
|
||||||
return registry.ToolDescriptor{
|
return registry.ToolDescriptor{
|
||||||
Name: "tbd_ship",
|
Name: "tbd_ship",
|
||||||
Description: "Trunk-based ship of a single-file change: branch from base, write the file, open a PR, and auto-merge (squash) to base ONLY when the head commit's CI is fully green. Fails closed to PR-only (never merges) when CI is pending, red, or absent, when the base branch requires reviews, or when the merge isn't clean — returning the PR for manual handling with a reason. Set ci_timeout_seconds to poll CI to completion (default 0 = snapshot, which returns pending right after opening the PR). Returns {merged, pr_url, pr_number, ci_status, reason, branch}.",
|
Description: "Trunk-based ship of a single-file change: branch from base, write the file, open a PR, and auto-merge (squash) to base ONLY when the head commit's CI is fully green. Fails closed to PR-only (never merges) when CI is pending, red, or absent, when the base branch requires reviews, or when the merge isn't clean — returning the PR for manual handling with a reason. Set ci_timeout_seconds to poll CI to completion (default 0 = snapshot, which returns pending right after opening the PR). Returns {merged, pr_url, pr_number, ci_status, reason, branch}.",
|
||||||
InputSchema: json.RawMessage(`{
|
InputSchema: json.RawMessage(`{
|
||||||
"type":"object",
|
"type":"object",
|
||||||
|
|||||||
@@ -52,11 +52,11 @@ func TestWorkflowRunListTool(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "status=all is no-op",
|
name: "status=all is no-op",
|
||||||
input: `{"owner":"mathias","name":"gitea-mcp","status":"all"}`,
|
input: `{"owner":"mathias","name":"gitea-mcp","status":"all"}`,
|
||||||
notQuery: []string{"status"},
|
notQuery: []string{"status"},
|
||||||
respBody: `{"total_count":0,"workflow_runs":[]}`,
|
respBody: `{"total_count":0,"workflow_runs":[]}`,
|
||||||
assert: func(t *testing.T, out string) {},
|
assert: func(t *testing.T, out string) {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "branch filter",
|
name: "branch filter",
|
||||||
|
|||||||
Reference in New Issue
Block a user