シェルスクリプトでGo言語のツールをクロスコンパイルしてGithubにリリースする

[@motemen]()さんの“Wercker で Go のプロジェクトをクロスコンパイルし,GitHub にリリースする - 詩と創作・思索のひろば (Poetry, Writing and Contemplation)”を手元からやる.

Werckerからリリース良いと思うけど,自分はリリースは手元で管理したい.その辺は毎回同じスクリプトでやってるのでまとめておく.なお,コードは全てtcnksm/go-distribution-scriptsにある.

クロスコンパイル

基本はHashicorpのやり方を真似してる.

まず,クロスコンパイルはmitchellh/goxを使う.goxは複数プラットフォームの並列コンパイルと出力先の設定の自由度が気に入ってずっと使ってる.何よりシンプルで良い.以下のようなスクリプトを書いている.

# compile.sh
gox \
    -os="darwin linux windows" \
    -arch="386 amd64" \
    -output "pkg/{{.OS}}_{{.Arch}}/{{.Dir}}"

あとは,これらをzipでアーカイブする(package.sh).

Githubへのリリース

Github APIを使ってリリースの作成,ファイルのアップロードを行う.werkcerはこれらをstepとしてGithubに公開しているのでそれを簡略化して使っている.

まず,リリースの作成.以下のようなスクリプトを準備する.

# github-create-release.sh
INPUT="
{
    \"tag_name\": \"${VERSION}\",
    \"target_commitish\": \"master\",
    \"draft\": false,
    \"prerelease\": false
}"

RELEASE_RESPONSE=$(
    curl --fail -X POST https://api.github.com/repos/${OWNER}/${REPO}/releases \
        -H "Accept: application/vnd.github.v3+json" \
        -H  "Authorization: token ${GITHUB_TOKEN}" \
        -H "Content-Type: application/json" \
        -d "${INPUT}")

$OWNERはGithubのユーザ名,$REPOはレポジトリ名,$GITHUB_TOKENはGithub APIのAPI Token(ここから取得できる)を指定する.

これで$VERSIONのリリースが作られる.

バイナリのアップロードを行う際にリリースのIDが必要になる.これはリリースを作成した際のレスポンスから得られる.

echo $RELEASE_RESPONSE | jq ".id" 

あとは,作成したリリースにファイルをぶっ込んでいく.

# github-upload-asset.sh
ARCHIVE_NAME=$(basename ${ARCHIVE})
CONTENT_TYPE=$(file --mime-type -b ${ARCHIVE})

curl --fail -X POST https://uploads.github.com/repos/${OWNER}/${REPO}/releases/${RELEASE_ID}/assets?name=${ARCHIVE_NAME} \
    -H "Accept: application/vnd.github.v3+json" \
    -H "Authorization: token ${GITHUB_TOKEN}" \
    -H "Content-Type: ${CONTENT_TYPE}" \
    --data-binary @"${ARCHIVE}"

$ARCHIVEはアップロードしたいファイルのパスを指定する.for文でリリースしたいファイルを回せばよい.