次ログ

次ログ

ゆるりと働いているSREの技術ブログのような何か。趣味の話も書く

Go言語でクロスコンパイルした実行ファイルをGitHubにリリースしてみた

前書き

せっかく作ったツールなので、いろんな環境用に実行ファイルを生成して、 GitHubからダウンロードできるようにしたいと考える人は多いと思います。

幸いにもGo言語は標準でクロスコンパイルをサポートしてくれています。 ちょろっとシェルスクリプトを書くだけで、一発で異なる環境用の実行ファイルを作成で きます。 問題は、それを公開する方法です。

僕は今までDropboxで配布していましたが、 なんというか、すごく古臭いやりかたなイメージ。 それとGitHubのリリース機能を今まで使ったことがなかったので、 これを機会に少しだけリリース機能を使ってみよう、という趣旨です。

今回はGo言語で書かれたソースからリリースするためのツールの GoReleaseというサードパーティ製のツールを利用して、リ リースしてみます。

今回の成果物

作成したリポジトリ GitHub - jiro4989/md4pt: マークダウンのテキストをプレーンテキストで表示したときに読みやすく整形

リリースした実行ファイル Releases · jiro4989/md4pt · GitHub

環境

項目 内容
OS Ubuntu Gnome 17.04
Go言語 1.9
プロセッサ Intel(R) Core(TM) i7-3667U CPU @ 2.00GHz
メモリ 8GB RAM

僕の今までのやり方

今回Go言語で書いたツールを配布するまでは、 Javaでツールを書いてDropboxにアップしていました。

今回はビルドまでの手順はやりましたが、 実際にはGo言語の手動リリースはやっていません。

今回リリースを初めて行ったのですが、 JARのときと同じ手順でやっていたこうなっていただろう、という想定で書いています。

お手製ビルド

まずベタな方法としては、下記のようなシェルスクリプトを書いて複数の実行ファイルを 生成することだと思います。 最初、僕は下記の方法でやろうとしていました。

#!/bin/bash
# -*- coding: utf-8 -*-

set -eux

mainsrc=./md4pt.go
dirname=./dist

if [ -e $dirname ]; then
  : $dirname is exist
else
  mkdir $dirname
fi

GOOS=linux GOARCH=amd64 go build -o $dirname/md4pt_linux $mainsrc
GOOS=darwin GOARCH=amd64 go build -o $dirname/md4pt_mac $mainsrc
GOOS=windows GOARCH=amd64 go build -o $dirname/md4pt_win.exe $mainsrc

ls $dirname
: build completed

Dropboxにリリース

手動ビルドした後は、実行ファイルをzipかtar.gzで圧縮して公開します。 今回のようなクロスコンパイルの場合でしたら、下記のようなシェルスクリプトになると 思います。

前提として、環境にDropboxディレクトリを同期して置く必要が有ります。 すると、Dropboxディレクトリに配置したものが、Web上のDropboxにも適用されるように なります。

#!/bin/bash
# -*- coding: utf-8 -*-

set -eux

bins=`ls -d dist/*`
for b in $bins; do
  gzfile="${b}.tar.gz"
  tar czf $gzfile $b README.md
  mv $gzfile ~/Dropbox/tools/
done

全体の自動化

手動ビルドの節で使用したスクリプトをbuild.sh 手動リリースの節で使用したスクリプトをrelease.sh とすると、ソースの編集がおわって一気にビルドしてリリースするなら下記のようなスク リプトを実行します。

#!/bin/bash
# -*- coding: utf-8 -*-

set -eux

./build.sh
./release.sh

一応、リリース作業自体は自動化できました。 でもバージョン管理などの観点からあまり良くないと思います。

よって、GitHubにリリースする方法に移行します。

GoReleaseを使ってGitHubにリリース

Gitにリポジトリを作成

中身はすっからかんでいいのでリポジトリを作成。

今回はmd4pt というリポジトリを作成して、実際にリリースしました。

GoReleaseのインストール

go get github.com/goreleaser/goreleaser

GoReleaseの設定ファイルの作成(.goreleaser.yml)

Goのリポジトリのルートディレクトリに.goreleaser.ymlを作成します。 内容は下記。

builds:
  - binary: md4pt
    goos:
      - windows
      - darwin
      - linux
    goarch:
      - amd64
      - 386
archive:
  format: tar.gz
  replacements:
    amd64: 64-bit
    darwin: mac
    linux: linux
  name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}"
  files:
    - README.md

リリース用のスクリプトの作成

.gitignoreに下記の内容を記述

token.txt
/dist/

名前は何でも良いですが、release.shという名前で 下記の内容のシェルスクリプトを作成。

#!/bin/bash
# -*- coding: utf-8 -*-

set -eux
: $1

git tag $1
GITHUB_TOKEN=`cat token.txt` goreleaser --rm-dist

token.txtというのは、 GitHubのSettings -> Personal access tokensの項目で作成するキーのみを書いたテキ ストファイルです。

https://github.com/settings/tokens

tokenは他の人に知られてはいけないので、シェルスクリプト本体に含めないようにする 必要がありました。

しかし、毎回コマンドラインから入力するのも面倒だし、履歴からたどるのも面倒だったので、 .gitignoreにtoken.txtを書いておいて、catして埋め込むようにしました。

git push

gitに最新のデータをpushします。

git remote add origin $URL
git add .
git commit -m "init commit"
git push origin master

リリースの実行

コマンドラインから以下のコマンドを実行します。
./release.sh v0.0.1

これで、GitHubの指定のリポジトリのリリースにv0.0.1タグでリリースされています。

まとめ

Go言語のクロスコンパイルとリリース作業の自動化を行いました。

Go言語は、Pythonでのpip, Rubyでのgemと同様の、サードパーティ製のライブラリやツー ルを容易に導入できる機能を標準でサポートしています。

このことにより、容易に成果物をWebに公開できました。 今後はこの方法でリリース作業を行っていこうと思います。