Pull to refresh

Распространение программ на Go. Часть 1

Reading time4 min
Views12K
Недавно прочел достаточно неплохую статью о инсталяции программ на Go. Где был показан простой пример того как можно реализовать установку бинарника под «любую» (unix friendly) операционную систему. Решил написать более подробный цикл статей на эту тему.

image


Небольшое оглавление
  • Сборка и деплой приложения в github releases. Часть 1
  • Сборка deb/rpm пакета для golang приложения. Часть 2 (скоро)
  • Размещаем свой пакет в PPA на Launchpad. Часть 3 (скоро)


Сборка и деплой приложения в github releases. Часть 1


CI/CD

В примере я буду использовать проект TinyJPG, а собирать мы его будем в Travis-ci.

Добавим к нашему проекту файл .travis.yml в котором мы будем описывать последовательность нашей сборки

.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


Теперь подробнее о самом важном в подкате:
${GH_TOKEN}: не что иное как Personal access tokens, сгенерировать его можно в настройках вашего аккаунта на github в разделе Developer settings. Ни в коем случае не передавайте его в travis.yml в открытом виде. Вы можете добавить этот ключ как Environment Variables через настройки travis-ci.

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 — ос под которую мы собираем проект, GOARCH=386 / GOARCH=amd64 — архитектура процессора, она же x86, и x86-64. Флаг --ldflags присвоит значения глобальным переменным version, build, commit в пакете main если они были там объявлены, в нашем случае мы присвоим TRAVIS_TAG в качестве версии нашего проекта, номер сборки TRAVIS_BUILD_NUMBER, и хеш коммита TRAVIS_COMMIT из которого собрался наш проект. Такой подход очень удобен и я считаю, что его нужно использовать в каждой Вашей сборке.

deploy:
И наконец публикация бинарников в github releases, пожалуй тут самое важное что можно отметить — это наш provider: releases, токен о котором писал чуть выше secure: ${GH_TOKEN}, и триггер tags: true, говорящий о том, что деплоить мы будем только при появлении тэга в гите, tags: true нужно для того что-бы поддерживать удобную версионность наших сборок.

И так, после окончания сборки мы получим оповещение на email о успешности/провале сборки и если все хорошо то в github.com/OrlovEvgeny/TinyJPG/releases мы увидим Assets, c двумя нашими бинарниками собранными под архитектуры i386 и amd64. И архивы Source code, с упакованными исходниками после сборки.

В данном примере я специально не вносил в .travis.yml сборку под ос OSX и Windows, дабы не раздувать статью однотипной информацией.

Возможные значения GOOS:

  • linux
  • windows
  • freebsd
  • darwin

Возможные значения GOARCH:

  • 386
  • amd64
  • arm

В целом с linux, windows и freebsd все понятно. Darwin — это MacOS. А если хочеться скомпилировать под Android (да, так тоже можно :), то нужно выбрать GOOS=Linux и GOARCH=arm.

Install

Со сборкой покончено, что дальше? Вы можете воспользоваться примером установки из статьи

или сделать немного красивее с помощью скрипта

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"


Скрипт можно закоммитить в проект, и запускать установку на любой ОС (читай unix friendly), с помощью одной простой команды в аргументы которой мы так-же можем передать версию программы которую мы хотим установить себе.

curl -L https://raw.githubusercontent.com/OrlovEvgeny/TinyJPG/master/tinyjpg_install.sh | sh -s - v0.0.8

Или через 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"

Думаю на этом завершим первую серию статей Распространения программ на Go. В следующей статье поговорим о том как можно собрать deb/rpm пакет из golang приложения. Буду рад Вашим замечаниям и предложениям по данной статье.

По теме:

Installation with Go Language can be Simpler
Travis Building a Go Project
Кросс-компиляция в Go
Tags:
Hubs:
Total votes 18: ↑14 and ↓4+10
Comments3

Articles