高速に自作パッケージをGithubにリリースするghrというツールをつくった

tcnksm/ghr・Github

ghrを使えば,1コマンドでGithubにリリースページの作成とそこへのパッケージのアップロードが可能になる.複数パッケージのアップロードは並列で実行される.

デモ

以下は簡単な動作例.

上のデモでは,v0.1.0タグでリリースを作成し,pkg/dist/v0.1.0以下の6つのファイルを並列でアップロードしている(ghrghrでリリースしている).1ファイルあたり,2.0M程度なのでまあま速いかと.アップロード結果は,ここで見られる.

背景

“Go言語のツールをクロスコンパイルしてGithubにリリースする”

上で書いたようにcurl使って頑張ってAPIを叩いていたが,やっぱシェルスクリプトは嫌だし,アップロードが遅い.

Githubへのリリースを行う専用ツールでaktau/github-releaseというのもあるが,オプションが多くて,curlを使うのと大差ない.Descriptionなどは後でページから編集した方がよい.

とういことで,シンプルなインターフェース,かつ高速にリリース可能なものをつくった.

使い方

事前準備としてGithubのAPI Tokenを環境変数にセットしておく.

$ export GITHUB_TOKEN="...."

あとは,プロジェクトのディレクトリで以下を実行するだけ.

$ ghr <tag> <package>

例えば,上のデモでは,以下を実行している.

$ ghr v0.1.0 pkg/dist/v0.1.0
--> Uploading: pkg/dist/v0.1.0/ghr_0.1.0_darwin_386.zip
--> Uploading: pkg/dist/v0.1.0/ghr_0.1.0_darwin_amd64.zip
--> Uploading: pkg/dist/v0.1.0/ghr_0.1.0_linux_386.zip
--> Uploading: pkg/dist/v0.1.0/ghr_0.1.0_linux_amd64.zip
--> Uploading: pkg/dist/v0.1.0/ghr_0.1.0_windows_386.zip
--> Uploading: pkg/dist/v0.1.0/ghr_0.1.0_windows_amd64.zip

ディレクトリを指定すれば,そのディレクトリ以下の全てのファイルが,ファイルを指定すれば,そのファイルのみがアップロードされる.

Go言語プロジェクトの場合は,mitchellh/goxで並列クロスコンパイルすれば,もっと幸せになる.

インストール

OSXの場合は,[Homebrew]()でインストールできる.

$ brew tap tcnksm/ghr
$ brew install ghr

他のプラットフォームの場合は,リリースページからパッケージをダウンロードして,$PATHの通ったところに配置する.

実装

Go言語で実装している.

並列アップロードはgoroutineを使って以下のように書いている.

var errorLock sync.Mutex
var wg sync.WaitGroup
errors := make([]string, 0)

for _, path := range files {
    wg.Add(1)
    go func(path string) {
        defer wg.Done()

        fmt.Printf("--> Uploading: %15s\n", path)
        if err := UploadAsset(info, path); err != nil {
            errorLock.Lock()
            defer errorLock.Unlock()
            errors = append(errors,
            fmt.Sprintf("%s error: %s", path, err))
        }
    }(path)
}
wg.Wait()

今後

シンプルなインターフェースを保ちつつ,オプションを追加していく予定.

まとめ

名前がmotemen/ghqみたいになってしまったのすいません(Github用のツール,かつCLIで使うことを考慮して短い名前にすると自然と…).

バグや意見は,GitHubのIssueもしくは,@deeeetまでお願いします.

参考