golang实现JIRA API交互的客户端插件库go-jira的使用

Golang实现JIRA API交互的客户端插件库go-jira的使用

简介

go-jira是一个用于与Atlassian Jira交互的Go客户端库。它提供了与Jira REST API交互的功能,包括创建和检索问题、管理问题状态转换等。

Go client library for Atlassian Jira

安装

使用go get安装:

go get github.com/andygrunwald/go-jira

功能特性

  • 认证支持(HTTP Basic、OAuth、Session Cookie、Bearer Token)
  • 创建和检索问题
  • 创建和检索问题状态转换
  • 可以调用Jira的所有API端点,即使该库没有直接实现

使用示例

获取单个问题

package main

import (
	"fmt"
	jira "github.com/andygrunwald/go-jira"
)

func main() {
	jiraClient, _ := jira.NewClient(nil, "https://issues.apache.org/jira/")
	issue, _, _ := jiraClient.Issue.Get("MESOS-3325", nil)

	fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary)
	fmt.Printf("Type: %s\n", issue.Fields.Type.Name)
	fmt.Printf("Priority: %s\n", issue.Fields.Priority.Name)

	// 输出示例:
	// MESOS-3325: Running mesos-slave@0.23 in a container causes slave to be lost after a restart
	// Type: Bug
	// Priority: Critical
}

认证方式

Token认证(Jira云版)

func main() {
	tp := jira.BasicAuthTransport{
		Username: "<username>",
		Password: "<api-token>",
	}

	client, err := jira.NewClient(tp.Client(), "https://my.jira.com")

	u, _, err = client.User.GetCurrentUser(context.Background())

	fmt.Printf("Email: %v\n", u.EmailAddress)
	fmt.Println("Success!")
}

Bearer Token认证(自托管Jira)

func main() {
	tp := jira.BearerAuthTransport{
		Token: "<personal-access-token>",
	}

	client, err := jira.NewClient(tp.Client(), "https://my.jira.com")
	// 使用client进行后续操作
}

创建问题

package main

import (
	"fmt"
	"github.com/andygrunwald/go-jira"
)

func main() {
	base := "https://my.jira.com"
	tp := jira.BasicAuthTransport{
		Username: "username",
		Password: "token",
	}

	jiraClient, err := jira.NewClient(tp.Client(), base)
	if err != nil {
		panic(err)
	}

	i := jira.Issue{
		Fields: &jira.IssueFields{
			Assignee: &jira.User{
				Name: "myuser",
			},
			Reporter: &jira.User{
				Name: "youruser",
			},
			Description: "Test Issue",
			Type: jira.IssueType{
				Name: "Bug",
			},
			Project: jira.Project{
				Key: "PROJ1",
			},
			Summary: "Just a demo issue",
		},
	}
	issue, _, err := jiraClient.Issue.Create(&i)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary)
}

更改问题状态

package main

import (
	"fmt"
	"github.com/andygrunwald/go-jira"
)

func main() {
    testIssueID := "FART-1"
	base := "https://my.jira.com"
	tp := jira.BasicAuthTransport{
		Username: "username",
		Password: "token",
	}

	jiraClient, err := jira.NewClient(tp.Client(), base)
	if err != nil {
		panic(err)
	}

	issue, _, _ := jiraClient.Issue.Get(testIssueID, nil)
	currentStatus := issue.Fields.Status.Name
	fmt.Printf("Current status: %s\n", currentStatus)

	var transitionID string
	possibleTransitions, _, _ := jiraClient.Issue.GetTransitions(testIssueID)
	for _, v := range possibleTransitions {
		if v.Name == "In Progress" {
			transitionID = v.ID
			break
		}
	}

	jiraClient.Issue.DoTransition(testIssueID, transitionID)
	issue, _, _ = jiraClient.Issue.Get(testIssueID, nil)
	fmt.Printf("Status after transition: %+v\n", issue.Fields.Status.Name)
}

调用未实现的API端点

package main

import (
	"fmt"
	"github.com/andygrunwald/go-jira"
)

func main() {
	base := "https://my.jira.com"
	tp := jira.BasicAuthTransport{
		Username: "username",
		Password: "token",
	}

	jiraClient, err := jira.NewClient(tp.Client(), base)
	req, _ := jiraClient.NewRequest("GET", "rest/api/2/project", nil)

	projects := new([]jira.Project)
	_, err = jiraClient.Do(req, projects)
	if err != nil {
		panic(err)
	}

	for _, project := range *projects {
		fmt.Printf("%s: %s\n", project.Key, project.Name)
	}
}

要求

  • Go >= 1.14
  • Jira v6.3.4 & v7.1.2及以上版本

注意事项

当前v2版本正在开发中,v2将包含破坏性变更。如需稳定版本,请使用v1.*版本。


更多关于golang实现JIRA API交互的客户端插件库go-jira的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang实现JIRA API交互的客户端插件库go-jira的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用go-jira库实现JIRA API交互

go-jira是一个流行的Golang库,用于与Atlassian JIRA进行交互。下面我将详细介绍如何使用这个库实现常见的JIRA操作。

安装go-jira

首先安装go-jira库:

go get github.com/andygrunwald/go-jira/v2

基本配置和认证

go-jira支持多种认证方式,最常用的是基本认证(Basic Auth)和个人访问令牌(PAT)。

1. 基本认证示例

package main

import (
	"fmt"
	"net/http"
	"os"

	jira "github.com/andygrunwald/go-jira/v2/cloud"
)

func main() {
	// JIRA Cloud的API地址
	jiraURL := "https://your-domain.atlassian.net"

	// 创建Transport并设置认证信息
	tp := jira.BasicAuthTransport{
		Username: "your-email@example.com",
		Password: "your-api-token", // 对于JIRA Cloud,使用API令牌而非密码
	}

	// 创建JIRA客户端
	client, err := jira.NewClient(jiraURL, tp.Client())
	if err != nil {
		fmt.Printf("创建JIRA客户端失败: %v\n", err)
		os.Exit(1)
	}

	// 测试连接
	_, _, err = client.User.GetSelf()
	if err != nil {
		fmt.Printf("认证失败: %v\n", err)
		os.Exit(1)
	}

	fmt.Println("成功连接到JIRA!")
}

2. 个人访问令牌(PAT)认证

tp := jira.PATAuthTransport{
	Token: "your-personal-access-token",
}

client, err := jira.NewClient(jiraURL, tp.Client())

常见操作示例

1. 创建Issue

func createIssue(client *jira.Client) {
	i := jira.Issue{
		Fields: &jira.IssueFields{
			Description: "这是一个测试问题",
			Type:        jira.IssueType{Name: "Task"},
			Project:     jira.Project{Key: "PROJ"},
			Summary:     "测试问题",
		},
	}

	issue, _, err := client.Issue.Create(&i)
	if err != nil {
		fmt.Printf("创建问题失败: %v\n", err)
		return
	}

	fmt.Printf("成功创建问题: %s\n", issue.Key)
}

2. 获取Issue详情

func getIssue(client *jira.Client, issueKey string) {
	issue, _, err := client.Issue.Get(issueKey, nil)
	if err != nil {
		fmt.Printf("获取问题失败: %v\n", err)
		return
	}

	fmt.Printf("问题详情:\n")
	fmt.Printf("Key: %s\n", issue.Key)
	fmt.Printf("Summary: %s\n", issue.Fields.Summary)
	fmt.Printf("Status: %s\n", issue.Fields.Status.Name)
	fmt.Printf("Description: %s\n", issue.Fields.Description)
}

3. 搜索Issue

func searchIssues(client *jira.Client, jql string) {
	issues, _, err := client.Issue.Search(jql, nil)
	if err != nil {
		fmt.Printf("搜索问题失败: %v\n", err)
		return
	}

	fmt.Printf("找到 %d 个问题:\n", len(issues))
	for _, issue := range issues {
		fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary)
	}
}

// 使用示例
searchIssues(client, "project = PROJ AND status = Open")

4. 更新Issue

func updateIssue(client *jira.Client, issueKey string) {
	// 获取当前问题
	issue, _, err := client.Issue.Get(issueKey, nil)
	if err != nil {
		fmt.Printf("获取问题失败: %v\n", err)
		return
	}

	// 创建更新
	update := jira.Issue{
		Key: issueKey,
		Fields: &jira.IssueFields{
			Summary:     "更新后的摘要",
			Description: "更新后的描述",
		},
	}

	_, err = client.Issue.Update(&update)
	if err != nil {
		fmt.Printf("更新问题失败: %v\n", err)
		return
	}

	fmt.Printf("成功更新问题 %s\n", issueKey)
}

5. 添加评论

func addComment(client *jira.Client, issueKey string, comment string) {
	c := &jira.Comment{
		Body: comment,
	}

	_, _, err := client.Issue.AddComment(issueKey, c)
	if err != nil {
		fmt.Printf("添加评论失败: %v\n", err)
		return
	}

	fmt.Printf("成功添加评论到问题 %s\n", issueKey)
}

高级功能

1. 分页获取结果

func paginatedSearch(client *jira.Client, jql string) {
	opts := &jira.SearchOptions{
		StartAt:    0,
		MaxResults: 50, // 每页数量
	}

	for {
		issues, resp, err := client.Issue.Search(jql, opts)
		if err != nil {
			fmt.Printf("搜索问题失败: %v\n", err)
			break
		}

		fmt.Printf("当前页: %d-%d (总数: %d)\n", 
			opts.StartAt, 
			opts.StartAt+len(issues)-1, 
			resp.Total)

		for _, issue := range issues {
			fmt.Printf("%s: %s\n", issue.Key, issue.Fields.Summary)
		}

		if opts.StartAt+len(issues) >= resp.Total {
			break
		}

		opts.StartAt += len(issues)
	}
}

2. 获取所有自定义字段

func getCustomFields(client *jira.Client) {
	fields, _, err := client.Field.GetList()
	if err != nil {
		fmt.Printf("获取字段列表失败: %v\n", err)
		return
	}

	fmt.Println("自定义字段:")
	for _, field := range fields {
		if field.Custom {
			fmt.Printf("%s (ID: %s)\n", field.Name, field.ID)
		}
	}
}

3. 使用自定义字段创建Issue

func createIssueWithCustomField(client *jira.Client) {
	i := jira.Issue{
		Fields: &jira.IssueFields{
			Type:    jira.IssueType{Name: "Bug"},
			Project: jira.Project{Key: "PROJ"},
			Summary: "带有自定义字段的问题",
			Unknowns: map[string]interface{}{
				"customfield_12345": "自定义值", // 替换为实际的字段ID
			},
		},
	}

	issue, _, err := client.Issue.Create(&i)
	if err != nil {
		fmt.Printf("创建问题失败: %v\n", err)
		return
	}

	fmt.Printf("成功创建带有自定义字段的问题: %s\n", issue.Key)
}

错误处理

go-jira返回的错误通常包含详细的JIRA API错误信息:

_, resp, err := client.Issue.Create(&issue)
if err != nil {
    if resp != nil {
        fmt.Printf("HTTP状态码: %d\n", resp.StatusCode)
        // 读取响应体获取详细错误信息
        body, _ := io.ReadAll(resp.Body)
        fmt.Printf("响应体: %s\n", string(body))
    }
    fmt.Printf("错误详情: %v\n", err)
    return
}

总结

go-jira库提供了全面的JIRA API访问能力,包括:

  1. 问题管理(创建、读取、更新、删除)
  2. 搜索功能(JQL查询)
  3. 工作流操作(转换状态)
  4. 附件管理
  5. 用户和权限管理

通过合理使用这个库,可以构建强大的JIRA集成工具和自动化脚本。记得在生产环境中添加适当的错误处理和日志记录,并考虑使用上下文(Context)来控制请求超时等行为。

回到顶部