Skip to content

Commit

Permalink
feat(tibuild): support commit to build (#219)
Browse files Browse the repository at this point in the history
Usage:

/devbuild trigger --engine tekton -e enterprise tidb v8.5.0-dev
commit/<sha>

Signed-off-by: wuhuizuo <wuhuizuo@126.com>

---------

Signed-off-by: wuhuizuo <wuhuizuo@126.com>
  • Loading branch information
wuhuizuo authored Dec 31, 2024
1 parent 069f4f2 commit 7b83308
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 1 deletion.
2 changes: 1 addition & 1 deletion tibuild/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/PingCAP-QE/ee-apps/tibuild

go 1.23
go 1.23.4

require (
github.com/DATA-DOG/go-sqlmock v1.5.2
Expand Down
23 changes: 23 additions & 0 deletions tibuild/pkg/rest/service/dev_build_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,35 @@ func fillDetailInfoForTekton(ctx context.Context, client GHClient, req *DevBuild
}
req.Spec.GitHash = commit

return nil
case strings.HasPrefix(req.Spec.GitRef, "commit/"):
commit := strings.Replace(req.Spec.GitRef, "commit/", "", 1)
req.Spec.GitHash = commit
branch, err := getBranchForCommit(ctx, client, repo.Owner, repo.Repo, commit)
if err != nil {
return err
}

req.Spec.GitRef = "branch/" + branch
return nil
default:
return nil
}
}

// get the branch name for the commit in github <owner>/<repo> repo.
func getBranchForCommit(ctx context.Context, client GHClient, owner, repo, commit string) (string, error) {
branches, err := client.GetBranchesForCommit(ctx, owner, repo, commit)
if err != nil {
return "", err
}
if len(branches) == 0 {
return "", fmt.Errorf("no branch found for commit %s", commit)
}

return branches[0], nil
}

func fillWithDefaults(req *DevBuild) {
spec := &req.Spec
guessEnterprisePluginRef(spec)
Expand Down
79 changes: 79 additions & 0 deletions tibuild/pkg/rest/service/gh_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package service

import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"regexp"
"strings"

Expand All @@ -15,6 +17,83 @@ var sha1regex *regexp.Regexp = regexp.MustCompile(`^[0-9a-fA-F]{40}$`)

type GitHubClient struct{ *github.Client }

// define a struct for the json data:
/*
{
"branches": [
{
"branch": "master",
"prs": [
{
"number": 57522,
"showPrefix": false,
"repo": {
"name": "tidb",
"ownerLogin": "pingcap"
},
"globalRelayId": "PR_kwDOAoCpQc6CbBGf"
}
]
}
],
"tags": [
"v9.0.0-alpha"
]
}
*/
type branchesForCommitResponse struct {
Branches []struct {
Branch string `json:"branch"`
}
Tags []string `json:"tags"`
}

// GetBranchesForCommit implements GHClient.
func (c GitHubClient) GetBranchesForCommit(ctx context.Context, owner string, repo string, commit string) ([]string, error) {
// check for github owner format with regexp, only support [a-zA-Z0-9_-]
if !regexp.MustCompile(`^[a-zA-Z0-9_-]+$`).MatchString(owner) {
return nil, fmt.Errorf("owner %s is not a valid github owner", owner)
}
// check for github repo name format with regexp, only support [a-zA-Z0-9_-]
if !regexp.MustCompile(`^[a-zA-Z0-9_-]+$`).MatchString(repo) {
return nil, fmt.Errorf("repo %s is not a valid github repo name", repo)
}
// check for commit format
if !sha1regex.MatchString(commit) {
return nil, fmt.Errorf("commit %s is not a valid sha1", commit)
}

rawURL, err := url.JoinPath("https://github.com", owner, repo, "branch_commits", commit)
if err != nil {
return nil, err
}

req, err := http.NewRequestWithContext(ctx, http.MethodGet, rawURL, nil)
if err != nil {
return nil, err
}

req.Header.Add("Accept", "application/json")
res, err := c.Client.Client().Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()

// parse the res body
var data branchesForCommitResponse
// read the response body and unmarshal to `data`
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err
}

var branches []string
for _, branch := range data.Branches {
branches = append(branches, branch.Branch)
}
return branches, nil
}

func (c GitHubClient) GetHash(ctx context.Context, owner, repo, ref string) (string, error) {
if sha1regex.MatchString(ref) {
return ref, nil
Expand Down
39 changes: 39 additions & 0 deletions tibuild/pkg/rest/service/gh_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package service
import (
"context"
"os"
"reflect"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -24,3 +25,41 @@ func TestGetHashSha1(t *testing.T) {
require.NoError(t, err)
require.Equal(t, s, hash)
}

func TestGitHubClient_GetBranchesForCommit(t *testing.T) {
type args struct {
owner string
repo string
commit string
}
tests := []struct {
name string
args args
want []string
wantErr bool
}{
{
name: "test",
args: args{
owner: "pingcap",
repo: "tidb",
commit: "0ccee0e011054ebfc86a6d5faa59a689a0793c05",
},
want: []string{"master"},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := NewGHClient("")
got, err := c.GetBranchesForCommit(context.TODO(), tt.args.owner, tt.args.repo, tt.args.commit)
if (err != nil) != tt.wantErr {
t.Errorf("GitHubClient.GetBranchesForCommit() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("GitHubClient.GetBranchesForCommit() = %v, want %v", got, tt.want)
}
})
}
}
1 change: 1 addition & 0 deletions tibuild/pkg/rest/service/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ type ArtifactHelperService interface {
type GHClient interface {
GetHash(ctx context.Context, owner, repo, ref string) (string, error)
GetPullRequestInfo(ctx context.Context, owner, repo string, prNum int) (*github.PullRequest, error)
GetBranchesForCommit(ctx context.Context, owner, repo, commit string) ([]string, error)
}

0 comments on commit 7b83308

Please sign in to comment.