Julia で自作パッケージを公式に登録する（2020年3月）

# はじめに

Julia のパッケージを作成していて、依存関係を持つパッケージが公式リポジトリに登録されていないと不便なので、登録してみることにした。
いろいろと躓いたところがあるので、注意点を記録しておきたい。

登録したパッケージ
https://github.com/Lirimy/ImageContainers.jl

# 下準備

## git の設定

`user.name` と `user.email` を設定しておく。
パッケージ作成時にデフォルト値として使われる。
https://git-scm.com/book/ja/v2/%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%82%8B-%E6%9C%80%E5%88%9D%E3%81%AEGit%E3%81%AE%E6%A7%8B%E6%88%90

GitHub でダミーのメールアドレスを使用する
https://qiita.com/sta/items/982ab68e8220a81d485c

## SSH 公開鍵の登録

公開鍵の作成
https://git-scm.com/book/ja/v2/Git%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-SSH-%E5%85%AC%E9%96%8B%E9%8D%B5%E3%81%AE%E4%BD%9C%E6%88%90

GitHub に登録
https://help.github.com/en/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account

# パッケージの作成

## 流れ

Julia でのパッケージの作り方
https://qiita.com/cometscome_phys/items/989389db3540ebd9e026

こちらの記事が詳しいので、 Travis CI や Coverall の設定まで従ってほしい。
なお、現在は PkgTemplates.jl がバッジを自動作成してくれるようになっている。

## 注意点

### CI を初めから入れておく

CI 関係の設定を削除するのは簡単だが、後から追加するのは面倒である[^ciadd]。使う可能性のあるプラグインは最初から入れておこう。
https://invenia.github.io/PkgTemplates.jl/stable/#Usage-1

自分の設定（とりあえず全部入り）
https://gist.github.com/Lirimy/dfc13aa430adf399efe35076db1e436e

[^ciadd]: 結局 PkgTemplates.jl から作り直した

### PkgTemplates.jl の CI のデフォルト設定

| CI Vendor | Target OS  |
| --------- | ---------- |
| Travis CI | Linux, OSX |
| AppVeyor  | Windows    |
| Cirrus CI | FreeBSD    |

（なぜ CI をいくつも使うのか疑問に思っていた。）

### Travis CI のアドレス

PkgTemplates.jl の設定が travis-ci.com なのに、 travis-ci.org にアクセスしていて混乱した[^oldsettings]。 travis-ci.com に移行したが、アドレスをよく確認しよう。

[^oldsettings]: 古い設定が残っていた


### Cirrus CI のビルド

Cirrus CI は、アカウントを設定してもビルドが走らなくて原因がわからなかったが、 .cirrus.yml に適当に空行を入れてコミットしたら動いた。 PkgTemplates.jl によってあらかじめ設定ファイルが組み込まれていて、改めて Push する必要がなかったためだろう。

# バージョン関係の設定

## パッケージのバージョン番号

パッケージのバージョン番号に相当する設定は２ヶ所ある。

(A) Project.toml 内の `version`
(B) Git/GitHub のタグ

パッケージの登録には (A) が参照される。登録時のコードをタグ付けしてリリースを作成し、 (A) と (B) の整合性を保つ作業を自動でやってくれるのが TagBot で、利用が推奨されている。

タグ（やリリース）は TagBot にすべて任せて、まったく触らないのが無難だと思う。
登録前に（手動で）タグをつけて管理したいならば、 v0.1.0 での登録を念頭において v0.0.1 から始めるとよい。

## TagBot のインストール

https://github.com/JuliaRegistries/TagBot#setup

に従う。

インストール後は GitHub レポジトリ内に `.github/workflows/TagBot.yml` というファイルが生成されるので確認しておこう。

https://github.com/Lirimy/ImageContainers.jl/blob/master/.github/workflows/TagBot.yml （例）

なお、 PkgTemplates.jl を用いてパッケージを作った場合は既にインストールされているかもしれない。

## Compat entry

https://github.com/JuliaRegistries/General#automatic-merging-of-pull-requests

初めに登録作業をしたときに、次のようなメッセージが現れた。

> Your new package pull request does not meet the following guidelines for auto-merging:
> 
> - The following dependencies do not have a compat entry that has an upper bound: PACKAGE_NAME. You may find CompatHelper helpful for keeping your compat entries up-to-date.Note: If your package works for the current version x.y.z of a dependency foo, then a compat entry foo = x.y.z implies a compatibility upper bound for packages following semver. You can additionally include earlier versions your package is compatible with. See https://julialang.github.io/Pkg.jl/v1/compatibility/ for details.

要するに、 Project.toml の [compat] に、依存するパッケージのバージョン（の上界）を指定しろ、ということである。

Project.toml の改善例
https://github.com/Lirimy/ImageContainers.jl/blob/master/Project.toml

```toml
[compat]
FileIO = "1.2"
ImageMagick = "0.7, 1.1"
QuartzImageIO = "0.7"
julia = "1.0, 1.5"
```

- julia 自体にも必要（だが PkgTemplates.jl が生成してくれる）
- stdlib に含まれるパッケージには不要（ここでは Base64 が当たる）
- 多くの場合はマイナーバージョンまでの指定で十分

依存するパッケージのバージョンアップに追従して compat entry を更新してくれるのが CompatHelper である。こだわりがなければ入れておくべきだろう。とりあえず自動で PR を出してくれるのは確認できた。
https://github.com/bcbi/CompatHelper.jl

## Documenter との共存

Documenter については以下の記事が詳しい。

PkgTemplates による Julia パッケージの作り方（後半）
https://qiita.com/SatoshiTerasaki/items/f43a7730bcf57f4b9572

最後の方でタグをつけて stable のドキュメント生成をするという節がある。もしも登録前に試したい場合は、 TagBot を邪魔しないように、`v0.0.1` あたりのタグを使うのがよいだろう（Project.toml のバージョン設定が `0.1.0` の場合）。もちろんバージョン番号以外のタグをつけてもかまわないはずだ。

# 公式リポジトリへの登録

## 新規登録時のチェックリスト

https://github.com/JuliaRegistries/General#automatic-merging-of-pull-requests

- バージョン番号が `0.0.1`, `0.1.0`, `1.0.0` のどれか（`0.1.0` が多い）
- Compat entry を設定する（前述）
- パッケージ名はアルファベット５文字以上、大文字で始まる
- レポジトリ URL が `$PackageName.jl.git` で終わる

## 登録作業

公式レポジトリへの登録は、 JuliaRegistries /
General への PR として行われる。
https://github.com/JuliaRegistries/General

その作業を自動で行ってくれるのが Registrator.jl である。
https://github.com/JuliaRegistries/Registrator.jl

Registrator.jl をインストールして、登録したいパッケージで issue を立てて、 `@JuliaRegistrator register` とコメントすると、登録作業が行われる。

例（一回失敗したため、もう一度コメントしている）
https://github.com/Lirimy/ImageContainers.jl/issues/8

新規登録の場合、テストにパスすれば、１度目のコメントから（？）３日間経つと自動的に登録される。