Recently I read a pretty good
article about installing programs on Go. Where a simple example was shown of how to install a binary under “any” (unix friendly) operating system. I decided to write a more detailed cycle of articles on this topic.
Small table of contents
- Building and deploying applications in github releases. Part 1
- Build the deb / rpm package for the golang application. Part 2 (coming soon)
- Place your package in PPA on Launchpad. Part 3 (coming soon)
')
Building and deploying applications in github releases. Part 1
CI / CD
In the example, I will use
the TinyJPG project , and we will collect it in
Travis-ci .
Add to our project a file .travis.yml in which we will describe the sequence of our assembly
.travis.ymllanguage: go go: - tip # The latest version of Go. install: true env: global: - MYAPP=tinyjpg - MYEMAIL=youmail@example.com - secure: ${GH_TOKEN} before_install: - sudo apt-get -qq update install: - go get -u github.com/OrlovEvgeny/$MYAPP - cd $GOPATH/src/github.com/OrlovEvgeny/$MYAPP - go install # build the app,build the package before_deploy: - mkdir -p build/{386,amd64} - GOOS=linux GOARCH=386 go build --ldflags "-X main.version=${TRAVIS_TAG} -X main.build=${TRAVIS_BUILD_NUMBER} -X main.commit=${TRAVIS_COMMIT}" -o build/386/${MYAPP}-386 *.go - GOOS=linux GOARCH=amd64 go build --ldflags "-X main.version=${TRAVIS_TAG} -X main.build=${TRAVIS_BUILD_NUMBER} -X main.commit=${TRAVIS_COMMIT}" -o build/amd64/${MYAPP}-amd64 *.go deploy: provider: releases email: ${MYEMAIL} api_key: secure: ${GH_TOKEN} file: - build/386/${MYAPP}-386 - build/amd64/${MYAPP}-amd64 skip_cleanup: true on: tags: true all_branches: true
Now more about the most important in the subcategory:
-
$ {GH_TOKEN} : nothing more than Personal access tokens, you can generate it in the settings of your account on github in the section Developer settings.
In no case do not transmit it to travis.yml in the clear . You can add this key as Environment Variables via travis-ci settings.
-
before_deploy :
- mkdir -p build/{386,amd64} - GOOS=linux GOARCH=386 go build --ldflags "-X main.version=${TRAVIS_TAG} -X main.build=${TRAVIS_BUILD_NUMBER} -X main.commit=${TRAVIS_COMMIT}" -o build/386/${MYAPP}-386 *.go - GOOS=linux GOARCH=amd64 go build --ldflags "-X main.version=${TRAVIS_TAG} -X main.build=${TRAVIS_BUILD_NUMBER} -X main.commit=${TRAVIS_COMMIT}" -o build/amd64/${MYAPP}-amd64 *.go
GOOS = linux - for which we are building a project, GOARCH = 386 / GOARCH = amd64 is the processor architecture, also known as x86, and x86-64. The flag --ldflags will assign values to global variables version, build, commit in the main package if they were declared there, in our case we will assign TRAVIS_TAG as the version of our project, the build number TRAVIS_BUILD_NUMBER, and the hash of the TRAVIS_COMMIT from which our project was assembled. This approach is very convenient and I believe that it should be used in each of your assembly.
-
deploy :
And finally the publication of binaries in github releases, perhaps the most important thing to note here is our provider: releases, the token about which I wrote a little higher than secure: $ {GH_TOKEN}, and the trigger tags: true, saying that we will only deploy when a tag appears in the gita, tags: true is needed in order to maintain the convenient versioning of our assemblies.
And so, after the end of the build, we will receive an email alert about the success / failure of the build, and if everything is fine, then at
github.com/OrlovEvgeny/TinyJPG/releases we will see Assets, with our two binaries compiled under the i386 and amd64 architectures. And Source code archives, with packaged sources after build.
In this example, I deliberately did not add a build under OSX and Windows to .travis.yml in order not to inflate the article with the same type of information.
Possible values of GOOS:
- linux
- windows
- freebsd
- darwin
Possible GOARCH values:
In general, with linux, windows and freebsd everything is clear. Darwin is MacOS. And if you want to compile for Android (yes, it’s also possible :), then you need to choose GOOS = Linux and GOARCH = arm.
Install
With the assembly over, what's next? You can use the installation example from the
article.
or make a little prettier with a script
install.sh VERSION="$1" PATH="$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin" TARGET_DIR=/usr/local/bin/tinyjpg CONF_DIR=/etc/tinyjpg LOG_DIR=/var/log/tinyjpg PERM="chmod +x /usr/local/bin/tinyjpg" if [ `getconf LONG_BIT` = "32" ]; then ARCH="386" else ARCH="amd64" fi URL="https://github.com/OrlovEvgeny/TinyJPG/releases/download/$VERSION/tinyjpg-$ARCH" CONF_URL="https://raw.githubusercontent.com/OrlovEvgeny/TinyJPG/master/config.yml" if [ -n "`which curl`" ]; then download_cmd="curl -L $URL --output $TARGET_DIR" conf_download_cmd="curl -L $CONF_URL --output $CONF_DIR/config.yml" else die "Failed to download TinyJPG: curl not found, plz install curl" fi mkdir -p $CONF_DIR $LOG_DIR echo -n "Fetching TinyJPG from $URL: " $download_cmd || die "Error when downloading TinyJPG from $URL" $conf_download_cmd || die "Error when downloading config file TinyJPG from $CONF_URL" /bin/echo -e "Install TinyJPG: \x1B[32m done \x1B[0m" echo -n "Set permission execute TinyJPG: " $PERM || die "Error permission execut TinyJPG from $TARGET_DIR" /bin/echo -e "\x1B[32m done \x1B[0m" tinyjpg -v /bin/echo -e "\x1B[32m Finished \x1B[0m"
The script can be committed to the project, and run the installation on any OS (read unix friendly), with the help of one simple command whose arguments we can also transfer the version of the program we want to install.
curl -L https://raw.githubusercontent.com/OrlovEvgeny/TinyJPG/master/tinyjpg_install.sh | sh -s - v0.0.8
Or via ansible
tasks: - name: TinyJPG installed sudo: yes shell: "curl -L https://raw.githubusercontent.com/OrlovEvgeny/TinyJPG/master/tinyjpg_install.sh | sh -s - v0.0.8"
I think this will complete the first series of articles Distributing programs to Go. In the next article we’ll talk about how to build the deb / rpm package from the golang application. I would be happy for your comments and suggestions on this article.
On this topic:
Language can be Simpler
Travis Building a Go Project
Cross compilation in Go