日記(日記とは言っていない)

https://zenn.dev/23prime に移行しました。

Stackage にパッケージを公開するまで

作ったパッケージを Stackage に公開したので,そのメモ.

作ったもの

整数列に関するデータベース Online Encyclopedia of Integer SequencesHaskell からアクセスするためのライブラリ(パッケージ)です.

github.com

経緯とか

実は oeis という既存のパッケージがあったのですが,次のような問題がありました.

  • ハッシュマップのキーの型が Eq 型クラスのインスタンスになっていない.
  • 戻り値が間違っている場合がある.
  • せっかく JSON を提供してくれてるのにテキストベースで処理している.
  • イマドキ HTTPS に非対応.
  • 検索結果を最初の1件しか受け取れない.
  • 多くの検索 Prefix を提供してくれてるのに,id:seq: しか使えない.
  • ↑ しかも Prefix ごとに関数が別になっているので,増やすとダルい.
    • 私の実装では,Prefix はデータコンストラクタで区別しています.

最初の2つに関しては論外なのでプルリクを送ってみた(master にマージはされた)のですが,Hackage には反映されないし GitHub の Build Status は一生 failing でやる気を感じないので,作りなおしました.

私の実装では,上の7点全てを解消しています.

テストを行っておく

公開するならテストくらいそれっぽくやっておきたいところです.

テストコードを書く

test/Spec.hs に色々書いたりしますが,省略.

Travis CI で自動テスト

テストには Travis CI を使います.

travis-ci.org

Haskell で利用するため,ここを参考にし,こんな感じに書きました.

GHC 7.8 以降でのテストを行っています.

各バージョンでのビルドを行い,ビルドに成功したらテストコードを実行します.
初回はクソ時間がかかるのですが,キャッシュさせてるので2回目以降はある程度早く終わります.

README に Build Status を載せる

README.md に次を追記します.

[![Build Status](https://travis-ci.org/id/package-name.svg?branch=master)](https://travis-ci.org//id/package-name)

すると ↓ こんな感じのボタンが出現します.

Build Status

Hackage に公開する

まずは Hackage に公開します.

Hackage のアカウントを取得する

ここから

  • 名前
  • ログイン名(ID)
  • メールアドレス

を入力し,Request Account を押すとメールが来るので,リンクを踏めば終わりです.

Package uploaders に入れてもらう

登録したではパッケージの公開はできず,Package uploaders (or uploader group) に入れてもらう必要があります.

多分先ほどの登録時に届いたメールに宛先 trustees@hackage.haskell.org が書かれているので,ここに「私を uploader group に入れてください!」という旨のメールを送ります.

メールに書いておくこと

メールのテンプレとかは特になさそうですが,

  • ログイン名(login username)
  • アップロードしたいパッケージの GitHub リポジトリへのリンク

くらいは書いておくべきでしょう.
前者は「書いてくれ」と書いてあり,後者はどうせ後で聞かれます.

翌日(向こうの時間だと多分朝)には「追加したよ!」というメールが返ってきました.

ちなみに追加されるとここに載ります.

依存パッケージの境界について

追加のメールには同時に,「依存パッケージの境界(上下界)がきちんと書かれてないよ」という指摘を受けました.

Haskell Package Versioning Policy あたりをきちんと読んでおくべきでした.

When publishing a Cabal package, you SHALL ensure that your dependencies in the build-depends field are accurate. This means specifying not only lower bounds, but also upper bounds on every dependency.

だそうです.

Haddock の作成

Haddockというドキュメントを作ります.
Hackage でよく見るアレです.

詳しい書き方はここが参考になります.

ローカルで作成するには,次のように打ちます.

$ stack haddock --haddock-arguments --odir=haddock

するとプロジェクトのルートに haddock/ が作成され,haddock/index.html を Web ブラウザ等で確認できます.

Cabal ファイルの確認

Hackage 上の Version や Author 等のデータは package-name.cabal の中身を元に生成されるので,公開する名前やメールアドレス等を確認しておきます.

最近の Stack では package.yaml をイジればおkです.

公開する

やっと公開できます.

Stack では,次のコマンド一発です.

$ stack upload .

Hackage のログイン名とパスワードを聞かれるので入力します.
最後に「秘密鍵がありません」とか言われるのですが,とりあえず無視しておいて大丈夫です.

Stackage に公開する

Nightly snapshot に追加する

やっと本題です.

debug-ito.hatenablog.com

こちらを参考にしました.

やり方はここに書いてあります.

条件を満たしていれば Stackagebuild-constraints.yaml に次を追記し,プルリクを送るだけです.

    "Name <email@mail.com> @GitHubID":
        - package-name

コミットメッセージは Add package-name 等で良いようです.

また,プルリクのテンプレがあるので,これを使うと良いです.

テストを通過すればマージされ,次のスナップショットから反映されます.

LTS snapshot に追加する

次の LTS のマイナーバージョンアップで自動的に追加される風なことが書かれていたのですが,反映されてないのでドキュメントを読み直してみたら,Adding a package to an LTS snapshot という箇所がありました.

どうやら次のメジャーアップデートのタイミングで Nightly から勝手に反映してくれる風なのですが,既存のメジャーバージョンの LTS に追加するには lts-haskell に issue を送る必要があるみたいです.
リンクを踏むと issue のテンプレが既に用意されているので,Nightly のときと同じような感じで送ります.

すると,問題なければ次のマイナーバージョンリリースのタイミングで LTS に追加されます.

ついでに

どこかにリリースノートを書いておきたいので,GitHub のリリース機能を活用します.

コミットにタグ付けしてプッシュする

例えば,

$ git tag -a -m "Release version 0.1.0" v0.1.0 <commit> 

のようにすると,コミットにタグが付与されます.
対象のコミットを指定しなければ,最新のコミットに付与されます(つまり <commit> は省略可能).

プッシュするときは,

$ git push origin v0.1.0

もしくは

$ git push origin --tags

と打ちます. 後者は全てのタグをプッシュします.

GitHub で Release を作る

リポジトリ/releases に行くと Draft a new release があるので,そこから発行します.

f:id:prime23:20190306132050p:plain

先ほどプッシュしたタグを指定し,Release title は適当に決めます.

Describe の書き方については諸説あるのですが,私は

# Added
- hoge
- fuga

# Changed
- foo
- bar

みたくしています.

書けたら Publish release を押しておしまい.