Skip to content

Commit

Permalink
feat: add job trigger and get log ouput (#771)
Browse files Browse the repository at this point in the history
* feat:add log print function with exit code

ass log ptint func

Log:
Change-Id: I46cb977e39e8c00b794376c70a88384bd555e223

* feat: add job build and wait log with exit code

add job build and wait log with exit code and fix test error

Log:
Change-Id: I8ae90c8649cbbb817e339119f75db54caa6fd0e3
  • Loading branch information
feiguoL authored Jan 16, 2025
1 parent bd33a1b commit c926d60
Show file tree
Hide file tree
Showing 22 changed files with 398 additions and 93 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out

bin/
bin/**/jcli
release/
jcli

Expand Down
12 changes: 12 additions & 0 deletions .jenkins-cli.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
current: test
jenkins_servers:
- name: yourServer
url: http://localhost:8080/jenkins
username: test
token: 211e3a2f0231198856dceaff96f2v75ce3
insecureSkipVerify: true
#mirrors:
#- name: default
# url: http://mirrors.jenkins.io/
# Language context is accept-language for HTTP header, It contains zh-CN/zh-TW/en/en-US/ja and so on
# Goto 'http://localhost:8080/jenkins/me/configure', then you can generate your token.
7 changes: 5 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ COPY . .
RUN CGO_ENABLED=0 go build -v -a -o jcli .

FROM alpine:3.10
COPY --from=builder /work/jcli /usr/bin/jcli
ENV JOB_NAME "test"
COPY --from=builder /work/bin/linux/jcli /usr/bin/jcli
RUN jcli config generate -i=false > ~/.jenkins-cli.yaml
COPY bin/build.sh /usr/bin/jclih
RUN chmod +x /usr/bin/jclih

ENTRYPOINT ["jcli"]
ENTRYPOINT ["jclih"]
8 changes: 4 additions & 4 deletions app/cmd/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/spf13/cobra"
)

//BackupOption is an option for backup
// BackupOption is an option for backup
type BackupOption struct {
RoundTripper http.RoundTripper
BackupDir string
Expand All @@ -38,7 +38,7 @@ var backupCmd = &cobra.Command{
RunE: backupOption.Backup,
}

//Check will find out whether Thin Backup Plugin installed or not
// Check will find out whether Thin Backup Plugin installed or not
func (o *BackupOption) Check() (err error) {
opt := PluginOptions{
Option: common.Option{RoundTripper: o.RoundTripper},
Expand All @@ -47,7 +47,7 @@ func (o *BackupOption) Check() (err error) {
return
}

//Backup will trigger thinBackup plugin to make a backup
// Backup will trigger thinBackup plugin to make a backup
func (o *BackupOption) Backup(cmd *cobra.Command, _ []string) (err error) {
jClient := &client.CoreClient{
JenkinsCore: client.JenkinsCore{
Expand Down Expand Up @@ -88,7 +88,7 @@ func (o *BackupOption) Backup(cmd *cobra.Command, _ []string) (err error) {
return
}

//ThinBackupAPI requests backupManual api
// ThinBackupAPI requests backupManual api
func ThinBackupAPI(client *client.CoreClient) (err error) {
_, err = client.RequestWithoutData(http.MethodGet, "/thinBackup/backupManual", nil, nil, 200)
return err
Expand Down
14 changes: 7 additions & 7 deletions app/cmd/center_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,31 @@ import (
"github.com/spf13/cobra"
)

//LtsURL is the URL of stable Jenkins RSS
// LtsURL is the URL of stable Jenkins RSS
const LtsURL = "https://www.jenkins.io/changelog-stable/rss.xml"

//WidthOfDescription is the width of the description column
// WidthOfDescription is the width of the description column
const WidthOfDescription = 60

//ASCIIOfLineFeed is the ASCII of line feed
// ASCIIOfLineFeed is the ASCII of line feed
const ASCIIOfLineFeed = 10

//ASCIIOfSpace is the ASCII of space
// ASCIIOfSpace is the ASCII of space
const ASCIIOfSpace = 32

//CenterListOption as options for Jenkins RSS
// CenterListOption as options for Jenkins RSS
type CenterListOption struct {
Channel Channel `xml:"channel"`
// RoundTripper http.RoundTripper
}

//Channel as part of CenterListOption
// Channel as part of CenterListOption
type Channel struct {
Title string `xml:"title"`
Items []Item `xml:"item"`
}

//Item as a option for information of newly-released Jenkins
// Item as a option for information of newly-released Jenkins
type Item struct {
Title string `xml:"title"`
Description string `xml:"description"`
Expand Down
2 changes: 1 addition & 1 deletion app/cmd/common/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package common

import "fmt"

//GetJCLIPluginPath returns the path of a jcli plugin
// GetJCLIPluginPath returns the path of a jcli plugin
func GetJCLIPluginPath(userHome, name string, binary bool) string {
suffix := ".yaml"
if binary {
Expand Down
2 changes: 1 addition & 1 deletion app/cmd/condition/plugin_dep.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type PluginDepCheck struct {
pluginName, targetVersion string
}

//NewChecker returns a plugin dep checker
// NewChecker returns a plugin dep checker
func NewChecker(jenkins *appCfg.JenkinsServer, roundTripper http.RoundTripper, pluginName, targetVersion string) (
checker *PluginDepCheck) {
checker = &PluginDepCheck{
Expand Down
62 changes: 45 additions & 17 deletions app/cmd/job_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"strings"
"time"

"github.com/jenkins-zh/jenkins-cli/app/cmd/common"
"github.com/jenkins-zh/jenkins-cli/app/i18n"
Expand All @@ -18,15 +19,18 @@ type JobBuildOption struct {
common.Option
cobra_ext.OutputOption

Param string
ParamArray []string
Param string
ParamArray []string
ParamJsonString string

ParamFilePathArray []string

Wait bool
WaitTime int
Delay int
Cause string
Wait bool
WaitTime int
WaitInterval int
Delay int
Cause string
LogConsole bool
}

var jobBuildOption JobBuildOption
Expand All @@ -40,23 +44,28 @@ func init() {
jobCmd.AddCommand(jobBuildCmd)
jobBuildCmd.Flags().BoolVarP(&jobBuildOption.Batch, "batch", "b", false, "Batch mode, no need confirm")
jobBuildCmd.Flags().StringVarP(&jobBuildOption.Param, "param", "", "",
i18n.T("Parameters of the job which is JSON format"))
i18n.T("Parameters of the job which is JSON format, for example: --param '{\"limit\":\"2\",\"timeoutLimit\":\"10\"}'"))
jobBuildCmd.Flags().StringArrayVar(&jobBuildOption.ParamArray, "param-entry", nil,
i18n.T("Parameters of the job which are the entry format, for example: --param-entry name=value"))
i18n.T("Parameters of the job which are the entry format, for example: --param-entry name1=value1, --param-entry name2=value2"))
jobBuildCmd.Flags().StringArrayVar(&jobBuildOption.ParamFilePathArray, "param-file", nil,
i18n.T("Parameters of the job which is file path, for example: --param-file name=filename"))
jobBuildCmd.Flags().BoolVarP(&jobBuildOption.Wait, "wait", "", false,
i18n.T("If you want to wait for the build ID from Jenkins. You need to install plugin pipeline-restful-api first"))
jobBuildCmd.Flags().IntVarP(&jobBuildOption.WaitTime, "wait-timeout", "", 30,
jobBuildCmd.Flags().IntVarP(&jobBuildOption.WaitTime, "wait-timeout", "", 60,
i18n.T("The timeout of seconds when you wait for the build ID"))
jobBuildCmd.Flags().IntVarP(&jobBuildOption.WaitInterval, "wait-interval", "", 10,
i18n.T("The interval of seconds when you want to wait for buildID... query, use with wait"))
jobBuildCmd.Flags().IntVarP(&jobBuildOption.Delay, "delay", "", 0,
i18n.T("Delay when trigger a Jenkins job"))
jobBuildCmd.Flags().StringVarP(&jobBuildOption.Cause, "cause", "", "triggered by jcli",
i18n.T("The cause of a job build"))
jobBuildCmd.Flags().BoolVarP(&jobBuildOption.LogConsole, "log", "l", false,
i18n.T("If you want to wait for build log and wait log output end"))

jobBuildOption.SetFlagWithHeaders(jobBuildCmd, "Number,URL")
jobBuildOption.BatchOption.Stdio = common.GetSystemStdio()
jobBuildOption.Option.Stdio = common.GetSystemStdio()

}

var jobBuildCmd = &cobra.Command{
Expand All @@ -66,15 +75,28 @@ var jobBuildCmd = &cobra.Command{
You need to give the parameters if your pipeline has them. Learn more about it from https://jenkins.io/doc/book/pipeline/syntax/#parameters.`),
Args: cobra.MinimumNArgs(1),
PreRunE: func(_ *cobra.Command, _ []string) (err error) {
if jobBuildOption.ParamArray == nil && jobBuildOption.ParamFilePathArray == nil {
if jobBuildOption.ParamArray == nil && jobBuildOption.ParamFilePathArray == nil && jobBuildOption.Param == "" {
return
}

paramDefs := make([]client.ParameterDefinition, 0)
if jobBuildOption.Param != "" {
if err = json.Unmarshal([]byte(jobBuildOption.Param), &paramDefs); err != nil {
paramMap := make(map[string]interface{})
if err = json.Unmarshal([]byte(jobBuildOption.Param), &paramMap); err != nil {
logger.Error(fmt.Sprintf("build param unmarshal error %v", err.Error()))
return
}
for key, value := range paramMap {
if key == "" || value == nil {
logger.Error("build param key or value empty")
return
}
paramDefs = append(paramDefs, client.ParameterDefinition{
Name: key,
Value: fmt.Sprintf("%v", value),
Type: client.StringParameterDefinition,
})
}
}

for _, paramEntry := range jobBuildOption.ParamArray {
Expand Down Expand Up @@ -113,6 +135,7 @@ You need to give the parameters if your pipeline has them. Learn more about it f
jclient := &client.JobClient{
JenkinsCore: client.JenkinsCore{
RoundTripper: jobBuildOption.RoundTripper,
Timeout: time.Duration(jobBuildOption.WaitTime) * time.Second,
},
}
getCurrentJenkinsAndClient(&(jclient.JenkinsCore))
Expand Down Expand Up @@ -150,13 +173,18 @@ You need to give the parameters if your pipeline has them. Learn more about it f
}

if err == nil {
options := client.JobCmdOptionsCommon{
Wait: jobBuildOption.Wait,
WaitTime: jobBuildOption.WaitTime,
WaitInterval: jobBuildOption.WaitInterval,
LogConsole: jobBuildOption.LogConsole,
}

if hasParam {
err = jclient.BuildWithParams(name, paramDefs)
} else if jobBuildOption.Wait {
var build client.IdentityBuild
if build, err = jclient.BuildAndReturn(name, jobBuildOption.Cause, jobBuildOption.WaitTime, jobBuildOption.Delay); err == nil {
jobBuildOption.Writer = cmd.OutOrStdout()
err = jobBuildOption.OutputV2([1]client.SimpleJobBuild{build.Build.SimpleJobBuild})
var jobState client.JenkinsBuildState
jobState, err = jclient.BuildWithParamsGetResponse(name, paramDefs, options)
if err == nil && jobBuildOption.LogConsole && jobState.RunId > 0 {
err = printLogRunFunc(name, JobLogOptionGetDefault(int(jobState.RunId)), cmd)
}
} else {
err = jclient.Build(name)
Expand Down
5 changes: 2 additions & 3 deletions app/cmd/job_delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (

"github.com/AlecAivazis/survey/v2/terminal"
"github.com/golang/mock/gomock"
"github.com/hinshun/vt10x"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -180,9 +179,9 @@ func RunTest(t *testing.T, test func(terminal.Stdio) error, procedures ...func(*
// Multiplex output to a buffer as well for the raw bytes.
buf := new(bytes.Buffer)

//c, err := expect.NewConsole(expect.WithStdout(buf))
c, err := expect.NewConsole(expect.WithStdout(buf))
//c, err := expect.NewConsole(expect.WithStdout(os.Stdout))
c, _, err := vt10x.NewVT10XConsole(expect.WithStdout(buf))
//c, _, err := vt10x.New(expect.WithStdout(buf))

require.Nil(t, err)
defer c.Close()
Expand Down
2 changes: 1 addition & 1 deletion app/cmd/job_edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func (j *JobEditOption) getSampleJenkinsfile() string {
`
}

//func getPipeline(name string) (script string, err error) {
// func getPipeline(name string) (script string, err error) {
func (j *JobEditOption) getPipeline(jClient *client.JobClient, name string) (script string, err error) {
script = j.Script //we take the script from input firstly
if script != "" {
Expand Down
Loading

0 comments on commit c926d60

Please sign in to comment.