2

I'm setting up a Jenkins multibranch pipeline for our Go mono repo at work. How do I set the GOPATH so the go tool can find where Jenkins has fetched the repo?

I've tried setting it with the environment syntax, like so:

pipeline {
    agent {
        docker {
            image 'golang:1.9.2'
        }
    }

    triggers {
        gitlab(triggerOnPush: true, triggerOnMergeRequest: true, branchFilterType: 'All')
    }

    post {
        failure {
            updateGitlabCommitStatus name: 'jenkins-build', state: 'failed'
        }
        success {
            updateGitlabCommitStatus name: 'jenkins-build', state: 'success'
        }
    }

    environment {
        GOPATH = "${pwd}"
    }

    stages {
        stage('Build') {
            steps {
                updateGitlabCommitStatus name: 'jenkins-build', state: 'pending'
                echo 'Linting...'
                sh 'go version'
                sh 'go get -u -v github.com/golang/lint/golint'
                sh 'golint -set_exit_status ./...'
                echo 'Building...'
                sh '''
                cd my_app
                go build
                '''
            }
        }
    }
}

The golint command works fine as it's within the right directory, but the go build command can't find any of the other dependencies that are within the root directory. For instance running go build in my_repo/my_app it won't find any of the dependencies in my_repo, say my_repo/my_dep.

I also tried setting GOPATH within the build stage:

stage('Build') {
            steps {
                updateGitlabCommitStatus name: 'jenkins-build', state: 'pending'
                echo 'Building...'
                sh '''
                GOPATH=$(pwd)
                cd fpweb
                go build
                '''
            }
        }

But the same happens.

my_app.go:19:2: cannot find package "my_repo/my_db" in any of:
    /usr/local/go/src/my_repo/my_db (from $GOROOT)
    /data/jenkins_slave/workspace/my_repo-pipeline_master-JHGTBESY3LSHGFEUYYM2777JIAFVR4R7E4Y2YPZA2MI4XW6BBTQQ/src/my_repo/my_db (from $GOPATH)

EDIT: What should I set my GOPATH to?

UPDATE: when I set the GOPATH to the WORKSPACE:

environment {
        GOPATH = "$WORKSPACE"
    }

I get an error:

[my_repo-pipeline_master-JHGTBESY3LSHGFEUYYM2777JIAFVR4R7E4Y2YPZA2MI4XW6BBTQQ] Running shell script
+ pwd
+ // GOPATH=/data/jenkins_slave/workspace/my_repo-pipeline_master-JHGTBESY3LSHGFEUYYM2777JIAFVR4R7E4Y2YPZA2MI4XW6BBTQQ
/data/jenkins_slave/workspace/my_repo-pipeline_master-JHGTBESY3LSHGFEUYYM2777JIAFVR4R7E4Y2YPZA2MI4XW6BBTQQ@tmp/durable-18853a9e/script.sh: 3: /data/jenkins_slave/workspace/my_repo-pipeline_master-JHGTBESY3LSHGFEUYYM2777JIAFVR4R7E4Y2YPZA2MI4XW6BBTQQ@tmp/durable-18853a9e/script.sh: //: Permission denied
bordeltabernacle
  • 1,603
  • 5
  • 24
  • 46
  • You need to put the code in your GOPATH. Unless your repo contains the complete GOPATH structure (which is not recommended), jenkins isn't going to create GOPATH for you. – JimB Jan 29 '18 at 15:02
  • Yeah, I understand that, the problem is that I don't know what to set my GOPATH to. I've tried a number of different paths, and none of them work. – bordeltabernacle Jan 29 '18 at 15:28
  • You can set GOPATH to whatever you want, but nothing will work until you put packages correctly in GOPATH. I don't see anything here attempting to place the packages at their full import path relative to GOPATH. – JimB Jan 29 '18 at 15:34
  • Jenkins just fetches the packages to the workspace, and I need to then manually move them? So, I have to `mv` the repo fetched by git from where Jenkins fetches it to, to wherever I set the `GOPATH`? ie. `cd .. && mv my_repo $GOPATH/src` – bordeltabernacle Jan 29 '18 at 15:49
  • It's really simple. Wherever you have your `$GOPATH` set, your repo and _all_ of its dependencies have to be located within `$GOPATH/src` (or have to be vendored within your repo). Whether that means moving them to the Jenkins folder, or symlinking them (I _think_ that works), or vendoring them (probably the best solution), that's your call. – Kaedys Jan 29 '18 at 17:20
  • Oh, also note that the `$GOPATH` var can be a colon-seperated list just like the `$PATH` var (ex. `GOPATH="my/repo/path:my/normal/gopath"`). So you can add _both_ the jenkins workspace and the normal `$GOPATH` into the var, and the go tool will check both, in order, using the first version it finds. – Kaedys Jan 29 '18 at 17:22

1 Answers1

5

You have to make $GOPATH/src/my_repo/my_db exist. The value of $GOPATH is not really important as far as Go is concerned. $GOPATH/src/my_repo/my_db may be a symlink. We create that symlink as part of the test script in our CI system.

I'm not very familiar with Jenkins, but I'm going to assume that $WORKSPACE is where the code is checked out (e.g. $WORKSPACE/.git exists). In that case, see if you can execute the following script before running any go command:

mkdir -p $GOPATH/src/my_repo
ln -s $WORKSPACE $GOPATH/src/my_repo/my_db

Again, the important thing is that $GOPATH/src/my_repo/my_db exists. How you make this happen is up to you.

Peter
  • 29,454
  • 5
  • 48
  • 60