yunxiao

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 12, 2026 License: MIT Imports: 13 Imported by: 0

README

yunxiao-go

CI Go Reference

云效(Alibaba Cloud DevOps / Yunxiao原生 Go SDK,并附带 CLI。

  • 不包装 MCP,不依赖 Node.js / npx 运行时
  • 使用个人访问令牌(x-yunxiao-token)直接调用 OpenAPI
  • 中心站默认接入点:openapi-rdc.aliyuncs.com
  • 收录约 212 个操作 · 版本 0.1.0 · stdlib-only(运行时零第三方依赖)

能力来源:从官方 alibabacloud-devops-mcp-serveroperations/* 解析生成,与 MCP 的 central / region 路径规则对齐。


安装

# 作为库
go get github.com/leganck/yunxiao-go@latest

# 作为 CLI
go install github.com/leganck/yunxiao-go/cmd/yunxiao@latest

也可从 Releases 下载多平台二进制。

环境变量模板见 .env.example。Token 申请见官方文档:获取个人访问令牌


SDK 快速开始

package main

import (
	"context"
	"fmt"
	"os"
	"time"

	yunxiao "github.com/leganck/yunxiao-go"
	"github.com/leganck/yunxiao-go/codeup"
	"github.com/leganck/yunxiao-go/flow"
)

func main() {
	c, err := yunxiao.NewWithDefaults(yunxiao.Config{
		Token:          os.Getenv("YUNXIAO_ACCESS_TOKEN"),
		OrganizationID: os.Getenv("YUNXIAO_ORG_ID"), // 中心版建议设置
	})
	if err != nil {
		panic(err)
	}

	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	u, err := c.GetCurrentUser(ctx)
	if err != nil {
		panic(err)
	}
	fmt.Println("user:", u.Name)

	// 领域 Service:请求 *Request + 响应强类型 / Decoded / Into
	repos, err := codeup.New(c).ListRepositoriesTyped(ctx, &codeup.ListRepositoriesRequest{
		Page: 1, PerPage: 20,
	})
	if err != nil {
		panic(err)
	}
	fmt.Println("repos:", len(repos))

	pipes, err := flow.New(c).ListPipelinesTyped(ctx, &flow.ListPipelinesRequest{
		Page: 1,
	})
	if err != nil {
		panic(err)
	}
	fmt.Println("pipelines:", len(pipes))

	// 通用调用(与 CLI 相同路径)
	raw, err := c.CallOp(ctx, "list_pipelines", "", nil, map[string]any{"page": 1}, nil)
	if err != nil {
		panic(err)
	}
	_ = raw
}

更多示例:

go run ./examples/whoami
go run ./examples/list_repos
领域包
包路径 说明
github.com/leganck/yunxiao-go 核心 Client、catalog、Call / CallOp、平台 whoami/orgs
…/codeup 代码库、分支、提交、变更请求等
…/flow 流水线、变量组、主机组、标签等
…/appstack 应用交付、发布流、编排、变更单等
…/organization 成员、部门、角色
…/packages 制品仓库
…/projex 项目、工作项、迭代
…/testhub 测试库、用例、测试计划

每个领域包约定:

文件 内容
service.go New(c *yunxiao.Client) *Service
zz_types_gen.go 请求 domain:*Request
zz_gen.go Method(ctx, *Request) (json.RawMessage, error)MethodInto(...)
zz_response_gen.go 响应 domain 与 *Decoded
typed.go 手写便捷封装(可选)
// 三种用法(任选)
raw, _ := svc.ListRepositories(ctx, req)           // 原始 JSON
list, _ := svc.ListRepositoriesDecoded(ctx, req)   // 生成响应类型
_ = svc.ListRepositoriesInto(ctx, req, &myStruct)  // 解到自定义类型
Client 配置要点
yunxiao.Config{
    Token:              "...",  // 必填
    BaseURL:            "",     // 默认中心站 openapi-rdc.aliyuncs.com
    Edition:            "",     // central | region,可空并自动推断
    OrganizationID:     "",     // 中心版默认组织
    RegionDefaultOrgID: "default",
    MaxRetries:         2,      // NewWithDefaults 默认开启
    Debug:              false,
}

错误类型:*yunxiao.APIError(Status / Code / Message / RequestID),可用 yunxiao.AsAPIError / IsNotFound / IsUnauthorized


CLI

构建
./build.ps1
# 产物: dist/yunxiao.exe  (或 Linux/macOS 下 dist/yunxiao)
配置

优先级:命令行 flag > 环境变量 > ~/.yunxiao/config.json > 默认值

export YUNXIAO_ACCESS_TOKEN=pt-xxxx
export YUNXIAO_ORG_ID=<organizationId>   # 之后多数命令可省略 --organizationId
// ~/.yunxiao/config.json
{
  "token": "pt-xxxx",
  "organizationId": "<org>",
  "apiBase": "https://openapi-rdc.aliyuncs.com",
  "edition": "central",
  "timeout": 60
}
用法
yunxiao <domain> <operation> [flags]
yunxiao <domain> list
yunxiao <domain> describe <operation>
yunxiao whoami
yunxiao orgs
yunxiao domains

yunxiao codeup list
yunxiao codeup describe list_repositories
yunxiao codeup list_repositories --page 1 --perPage 20

yunxiao flow list_pipelines --page 1
yunxiao projex search_projects --body '{}'
yunxiao appstack list_applications
Domain 操作约数 常用别名
codeup 23 code, repo
flow 48 pipeline, ci
appstack 68 app
organization 12 org(带操作时)
packages 3 package, artifact
projex 40 project, workitem
testhub 18 test

yunxiao org 单独执行 = 当前组织信息;yunxiao org <op> = organization 域。

常用 flag
Flag 环境变量 说明
--token YUNXIAO_ACCESS_TOKEN 个人访问令牌
--org YUNXIAO_ORG_ID 默认 organizationId
--api-base YUNXIAO_API_BASE_URL API Base URL
--edition YUNXIAO_EDITION central / region
--body 请求体 JSON
--json 合并 path/query/body 的 JSON 对象
--output json(默认)或 raw
--debug 请求摘要 + HTTP 调试日志
--timeout 超时秒数(默认 60)
--config YUNXIAO_CONFIG 配置文件路径

完整参数与操作列表以本机为准:

yunxiao help
yunxiao <domain> list
yunxiao <domain> describe <operation>

仓库结构

.
├── *.go, catalog.json          # 核心 package yunxiao
├── codeup/ flow/ appstack/ …   # 领域包
├── cmd/yunxiao/                # CLI
├── internal/cli|cliconfig/     # CLI 实现(不对外)
├── examples/                   # 可运行示例
├── tools/codegen/
│   ├── mcp/                    # MCP → 请求 / 方法
│   ├── response/               # 响应 domain + samples/
│   └── out/                    # 中间产物(gitignore)
├── build.ps1
└── .github/workflows/          # CI + Release

开发与生成

# 测试 + 构建 CLI
./build.ps1

# 从官方 MCP dist 刷新请求 domain 与方法
./build.ps1 -Dist C:\path\to\alibabacloud-devops-mcp-server\dist

# 按 samples/ 重建响应 domain
./build.ps1 -HelpDocs
产物 来源 勿手改
zz_types_gen.go / zz_gen.go MCP 管线
zz_response_gen.go 响应样例管线
service.go / typed.go 手写

详情见 tools/codegen/README.md

说明
  • 官方 MCP 中少量能力是本地编排/YAML 生成,不是单一 OpenAPI;本库收录底层 OpenAPI。
  • 运行时第三方 Go 依赖;仅维护者刷新 API 时需要 Node.js。
  • 操作清单以 catalog.jsonyunxiao <domain> list 为准。

发布

打 tag 后由 GitHub Actions + GoReleaser 发布多平台 CLI(无 Docker):

git tag v0.1.0
git push origin v0.1.0

.goreleaser.yaml.github/workflows


License

MIT © leganck

Documentation

Overview

Package yunxiao is a native Go client for Alibaba Cloud DevOps (Yunxiao) OpenAPI.

It does not wrap the Node MCP server; requests use the x-yunxiao-token header against openapi-rdc.aliyuncs.com (central) or a region edition base URL.

Layout

this package (module root) — core Client, HTTP, path, catalog, platform
codeup/ flow/ appstack/ …  — domain services (public subpackages)
cmd/yunxiao                — optional CLI
internal/cli, cliconfig    — CLI only
tools/codegen/mcp          — MCP → requests + methods
tools/codegen/response     — response domain samples + generator

Quick start

c, err := yunxiao.New(yunxiao.Config{
    Token:          os.Getenv("YUNXIAO_ACCESS_TOKEN"),
    OrganizationID: os.Getenv("YUNXIAO_ORG_ID"),
    MaxRetries:     2,
})
svc := codeup.New(c)
repos, err := svc.ListRepositoriesTyped(ctx, &codeup.ListRepositoriesRequest{Page: 1})

Domain packages contain:

  • zz_types_gen.go / zz_gen.go — request models + Call/Into (from MCP)
  • zz_response_gen.go — response models + Decoded (from samples)
  • typed.go — hand-written convenience wrappers

Domains: codeup, flow, appstack, organization, packages, projex, testhub.

Index

Constants

View Source
const DefaultBaseURL = "https://openapi-rdc.aliyuncs.com"
View Source
const DefaultClientRetries = 2

DefaultMaxRetries is used when Config.MaxRetries is negative (unset sentinel not used; zero means no retries; omit by leaving at 0 and set explicitly, or use DefaultClientRetries).

View Source
const Version = "0.1.0"

Version is the SDK release version. CLI defaults to the same value unless overridden at build time.

Variables

This section is empty.

Functions

func CloneQuery

func CloneQuery(query map[string]any) map[string]any

CloneQuery returns a shallow copy of query (nil-safe).

func DecodeJSON

func DecodeJSON[T any](raw json.RawMessage, dest *T) error

DecodeJSON unmarshals raw into dest.

func DecodeList

func DecodeList[T any](raw json.RawMessage) ([]T, error)

DecodeList unmarshals either a JSON array or an object with an items/list/data array field.

func EncodeRepositoryID

func EncodeRepositoryID(repositoryID string) string

EncodeRepositoryID encodes org/name style repository ids.

func FillPath

func FillPath(template string, vars map[string]string) (string, error)

FillPath replaces {param} placeholders. Values should already be encoded if needed.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound reports whether err is an API 404.

func IsRetriable

func IsRetriable(err error) bool

IsRetriable reports whether the client should retry the request. Network errors are treated as retriable; API errors only when Temporary.

func IsUnauthorized

func IsUnauthorized(err error) bool

IsUnauthorized reports whether err is an API 401/403.

func Paginate

func Paginate[T any](ctx context.Context, opt PageOptions, fetch FetchPage[T]) ([]T, error)

Paginate walks pages until a short/empty page or MaxPages is reached.

func PaginateQuery

func PaginateQuery[T any](ctx context.Context, baseQuery map[string]any, opt PageOptions, fetch func(ctx context.Context, query map[string]any) ([]T, error)) ([]T, error)

PaginateQuery is a convenience for APIs that take map[string]any query with page/perPage.

func PathEscape

func PathEscape(filePath string) string

PathEscape keeps slashes unescaped for file paths (MCP pathEscape).

func WithPage

func WithPage(query map[string]any, page, perPage int) map[string]any

WithPage sets page/perPage keys on a copy of query.

func WithPageKeys

func WithPageKeys(query map[string]any, pageKey, perPageKey string, page, perPage int) map[string]any

WithPageKeys is like WithPage but allows custom query key names.

Types

type APIError

type APIError struct {
	Status    int
	Method    string
	URL       string
	Body      []byte
	Code      string
	Message   string
	RequestID string
}

APIError is a non-2xx Yunxiao OpenAPI response.

func AsAPIError

func AsAPIError(err error) (*APIError, bool)

AsAPIError extracts *APIError from err if present.

func ParseAPIErrorBody

func ParseAPIErrorBody(status int, method, url string, body []byte) *APIError

ParseAPIErrorBody fills Code/Message/RequestID from JSON body when possible.

func (*APIError) Error

func (e *APIError) Error() string

func (*APIError) Temporary

func (e *APIError) Temporary() bool

Temporary reports whether the API error is likely transient.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a native Yunxiao OpenAPI client (no MCP).

func New

func New(cfg Config) (*Client, error)

New creates a Client. Retries are off unless MaxRetries > 0.

func NewWithDefaults

func NewWithDefaults(cfg Config) (*Client, error)

NewWithDefaults creates a Client with DefaultClientRetries when MaxRetries is 0.

func (*Client) BaseURL

func (c *Client) BaseURL() string

BaseURL returns configured API base.

func (*Client) Call

func (c *Client) Call(ctx context.Context, method, organizationID, regionTemplate, centralTemplate string, pathVars map[string]string, query map[string]any, body any) (json.RawMessage, error)

Call is a generic OpenAPI invocation used by generated methods and CLI.

func (*Client) CallOp

func (c *Client) CallOp(ctx context.Context, opName, organizationID string, pathVars map[string]string, query map[string]any, body any) (json.RawMessage, error)

CallOp looks up catalog operation by name and executes it.

func (*Client) Clone

func (c *Client) Clone() *Client

Clone returns a shallow copy of the client (shared HTTP client).

func (*Client) Do

func (c *Client) Do(ctx context.Context, method, p string, query map[string]any, body any) (json.RawMessage, error)

Do performs a raw OpenAPI request. path may be absolute or start with /. Retriable failures honor MaxRetries / RetryWait (see Config).

func (*Client) GetCurrentOrganizationInfo

func (c *Client) GetCurrentOrganizationInfo(ctx context.Context) (*CurrentOrganizationInfo, error)

GetCurrentOrganizationInfo maps /platform/user like the MCP server.

func (*Client) GetCurrentUser

func (c *Client) GetCurrentUser(ctx context.Context) (*CurrentUser, error)

GetCurrentUser returns the token user.

func (*Client) GetUserOrganizations

func (c *Client) GetUserOrganizations(ctx context.Context) ([]Organization, error)

GetUserOrganizations lists organizations for current user. Organization response fields are generated from help docs (see zz_response_gen.go).

func (*Client) IsRegion

func (c *Client) IsRegion() bool

IsRegion reports region edition.

func (*Client) LastOrganizationID

func (c *Client) LastOrganizationID() string

LastOrganizationID returns cached organization id if known.

func (*Client) ResolveOrganizationID

func (c *Client) ResolveOrganizationID(ctx context.Context, explicit string) (string, error)

ResolveOrganizationID mirrors MCP resolveOrganizationId behavior.

func (*Client) ResolvePath

func (c *Client) ResolvePath(ctx context.Context, organizationID, regionTemplate, centralTemplate string, vars map[string]string) (string, error)

ResolvePath picks region/central template and fills params. organizationId is resolved when the chosen template needs it.

func (*Client) SetLastOrganizationID

func (c *Client) SetLastOrganizationID(id string)

SetLastOrganizationID overrides cached organization id.

func (*Client) WithOrganization

func (c *Client) WithOrganization(organizationID string) *Client

WithOrganization returns a clone with default organization id set.

type Config

type Config struct {
	// Token is the personal access token (x-yunxiao-token).
	Token string
	// BaseURL defaults to https://openapi-rdc.aliyuncs.com
	BaseURL string
	// Edition is "central" or "region". Empty auto-detects from BaseURL.
	Edition string
	// RegionDefaultOrgID used when edition is region (default "default").
	RegionDefaultOrgID string
	// OrganizationID is the default organization for central edition path resolution.
	OrganizationID string
	// HTTPClient optional custom client. If nil, a client with 60s timeout is used.
	HTTPClient *http.Client
	// Debug enables request logging via Logger (defaults to stderr when true).
	Debug bool
	// Logger receives debug lines. Optional; when Debug is true and Logger is nil, stderr is used.
	Logger Logger
	// MaxRetries is the number of retries after the first attempt for retriable failures
	// (network errors, 429, 502, 503, 504). 0 disables retries. Default when using
	// NewWithDefaults is DefaultClientRetries; New leaves 0 unless set.
	MaxRetries int
	// RetryWait is the base backoff between retries (doubled each attempt). Default 200ms.
	RetryWait time.Duration
	// UserAgent overrides the default User-Agent header when non-empty.
	UserAgent string
}

Config configures the Yunxiao OpenAPI client.

type CurrentOrganizationInfo

type CurrentOrganizationInfo struct {
	LastOrganization string `json:"lastOrganization"`
	UserID           string `json:"userId"`
	UserName         string `json:"userName"`
}

CurrentOrganizationInfo is a mapped view used by MCP get_current_organization_info.

type CurrentUser

type CurrentUser struct {
	ID               string `json:"id"`
	Name             string `json:"name"`
	Email            string `json:"email"`
	LastOrganization string `json:"lastOrganization"`
	CreatedAt        string `json:"createdAt"`
}

CurrentUser is GET /oapi/v1/platform/user

type FetchPage

type FetchPage[T any] func(ctx context.Context, page, perPage int) ([]T, error)

FetchPage loads a single page of results. page is 1-based. Return fewer than perPage items (or empty) to signal the last page.

type FuncLogger

type FuncLogger func(format string, v ...any)

FuncLogger adapts a function to Logger.

func (FuncLogger) Printf

func (f FuncLogger) Printf(format string, v ...any)

Printf implements Logger.

type Logger

type Logger interface {
	Printf(format string, v ...any)
}

Logger is a minimal debug logger. Implementations must be safe for concurrent use if the Client is shared across goroutines.

type OpSpec

type OpSpec struct {
	Name        string   `json:"name"`
	GoName      string   `json:"goName"`
	Domain      string   `json:"domain"`
	Method      string   `json:"method"`
	RegionPath  string   `json:"regionPath"`
	CentralPath string   `json:"centralPath"`
	PathParams  []string `json:"pathParams"`
	QueryKeys   []string `json:"queryKeys"`
	BodyKeys    []string `json:"bodyKeys"`
	Required    []string `json:"required"`
	HasBody     bool     `json:"hasBody"`
	Source      string   `json:"source"`
	File        string   `json:"file"`
}

OpSpec describes one OpenAPI operation derived from MCP server source.

func LookupOperation

func LookupOperation(name string) (OpSpec, bool, error)

LookupOperation finds an operation by cli name, Go name, or source name.

func Operations

func Operations() ([]OpSpec, error)

Operations returns all parsed OpenAPI operations.

func (OpSpec) MissingRequired

func (op OpSpec) MissingRequired(values map[string]any) []string

MissingRequired returns required params not present in values.

type Organization

type Organization struct {
	CreatedAt   string `json:"createdAt,omitempty"`
	CreatorID   string `json:"creatorId,omitempty"`
	DefaultRole string `json:"defaultRole,omitempty"`
	Description string `json:"description,omitempty"`
	ID          string `json:"id,omitempty"`
	Name        string `json:"name,omitempty"`
	UpdateAt    string `json:"updateAt,omitempty"`
}

Organization response domain model.

source: samples/organization_list.json

func DecodeOrganizationList

func DecodeOrganizationList(raw json.RawMessage) ([]Organization, error)

DecodeOrganizationList decodes organization list payloads.

type PageOptions

type PageOptions struct {
	// StartPage defaults to 1.
	StartPage int
	// PerPage defaults to 20.
	PerPage int
	// MaxPages caps how many pages to fetch; 0 means unlimited (until a short page).
	MaxPages int
	// PageKey defaults to "page".
	PageKey string
	// PerPageKey defaults to "perPage".
	PerPageKey string
}

PageOptions controls automatic pagination helpers.

type WriterLogger

type WriterLogger struct {
	W io.Writer
}

WriterLogger logs to an io.Writer (e.g. os.Stderr).

func (WriterLogger) Printf

func (l WriterLogger) Printf(format string, v ...any)

Printf implements Logger.

Directories

Path Synopsis
cmd
yunxiao command
examples
list_repos command
Example: list Codeup repositories via the domain service.
Example: list Codeup repositories via the domain service.
whoami command
Example: print current Yunxiao user.
Example: print current Yunxiao user.
internal
cli

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL