⬆️ ⬇️

Distribution of programs on Go. Part 1

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.



image





Small table of contents



')

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.yml
language: 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:





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

Source: https://habr.com/ru/post/354906/



All Articles