pub.dev に自分のパッケージを登録しよう

## はじめに

この記事は[Flutter Advent Calendar 2019](https://qiita.com/advent-calendar/2019/flutter) 7日目の記事です。

前日は @kikuchy さんの[自動コード生成を駆使してFlutter開発を楽にする](https://qiita.com/kikuchy/items/cdd95bb9a02c4edf8f12)でした。知らないことだらけだったので、勉強になりました。

どうも、[たくチャレ](https://twitter.com/takuchalle)です。

7日目は`pub.dev`に自分が作ったパッケージを登録する方法を紹介します。

ただ登録するだけだったら一瞬で終わってしまうので、

* 公式オススメのファイル構成の紹介
* パッケージの自動テスト・カバレッジ取得
* verified publisher のなり方

も合わせて紹介します。

私は先日非常にシンプルな[dot_pagination_swiper](https://pub.dev/packages/dot_pagination_swiper)を登録してみました。画面の下部にドットのページネーションを実現するだけのパッケージです。これを登録した時の流れを紹介します。

## pub.dev とは

https://pub.dev/

`Flutter`でアプリを作ってる人に説明は不要かと思いますが、[pub.dev](https://pub.dev/)は`Dart`の公式パッケージリポジトリです。`Flutter`や`Web`向けの`Dart`のパッケージを一覧・検索・登録を行うことができます。

`pub.dev`で面白いと思ったのは、パッケージが`Popularity`、`Helth`、`Maintenance`の3項目をもとにスコアリングされていることです。他の言語・プラットフォームのパッケージリポジトリは知らないのですが、こういう目安があるとユーザがパッケージを選ぶ基準になりますね。

## パッケージ登録の流れ

流れは以下の通りです。

1. パッケージ作成 (`flutter create --template=package hello`)
2. パブリッシュの dry run (`flutter publish --dry-run`)
3. エラーがなければパブリッシュ (`flutter publish`)

iOS/Android のネイティブの機能を使う必要がある場合は、`--template=plugin`を指定してください。パッケージの作成はAndroid Studio などGUIで行えますが、`publish`する方法は分かりません…

パッケージ登録の流れ自体は簡単ですが、1. のパッケージ作成が一番大変でしょうね…笑

初めてパブリッシュした時に以下のような文章が出てきます。`y`を入力して、表示してあるURLをブラウザにコピペして`Allow access`を押してください。Google アカウントに紐づいてパブリッシュされます。

```bash:console
Looks great! Are you ready to upload your package (y/n)? y

Pub needs your authorization to upload packages on your behalf.
In a web browser, go to https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&response_type=code&client_id=xxxxxxx.email
Then click "Allow access". 
```

現在のコマンドラインツールの仕様上、後述する`verified publisher`にいきなりパブリッシュすることはできず、一度自分の Google アカウントに紐づけてパブリッシュした後に`verified publisher`に移管する形になります。[こちらのNote](https://dart.dev/tools/pub/publishing#publishing)を参照してください。一度移管してしまえば、更新は直接行えます。

## ファイル構成

[公式ドキュメント](https://dart.dev/tools/pub/package-layout)からの引用ですが、以下は`enchilada`という名のパッケージのファイル構成例です。

```
enchilada/
  .dart_tool/ *
  .packages *
  pubspec.yaml
  pubspec.lock **
  LICENSE
  README.md
  CHANGELOG.md
  benchmark/
    make_lunch.dart
  bin/
    enchilada
  doc/
    api/ *
    getting_started.md
  example/
    main.dart
  lib/
    enchilada.dart
    tortilla.dart
    guacamole.css
    src/
      beans.dart
      queso.dart
  test/
    enchilada_test.dart
    tortilla_test.dart
  tool/
    generate_docs.dart
  web/
    index.html
    main.dart
    style.css
```

`*`がついているファイルは自動生成されるファイルなので、VCS には入れないでください。
`**`の`pubspec.lock`はアプリケーション以外では VCS に入れないでください。

上記ファイル全てが必要なわけではなく、`pubspec.yaml`、`LICENSE`、`README.md`、`CHANGELOG.md`、`lib/*`があればパッケージとして成立します。

それぞれを簡単に説明します。

### pubspec.yaml

パッケージの情報を記載するためのファイルです。
`flutter create`した後`description`、`author`、`homepage`を追加すれば OK です。

更に詳しい情報は[こちら](https://dart.dev/tools/pub/pubspec)を参照してください。

### LICENSE

ライセンスの定義をしましょう。`Flutter`本体が`BSD-3-Clause`を採用してるので、私もそうしてます。自身のポリシーに合わせてもらえれば良いと思います。

`flutter create`した直後は`LICENSE`に何も書かれていないのでちゃんと忘れずに書きましょう。私は忘れました。

### README.md

`GitHub`などでもトップページに表示される説明文ですね。`pub.dev`でもパッケージのトップページに表示されるので、いろんな人に使ってもらいたい場合しっかり書きましょう。

### CHANGELOG.md

`pub.dev`のパッケージの`Changelog`タブに表示されます。ユーザが変更点を簡潔に知るための手段なのでしっかり書きましょう。

### lib/*

パッケージのソースコード本体です。

## パッケージの自動テスト・カバレッジ取得

ちゃんとビルドできるか、どれくらいテストカバレッジがあるかもユーザがパッケージを選ぶ指標の一つになると思います。ステータスバッジあるとかっこいいですしね！

テストの書き方に関しては、3日目の @chooyan_eng さんが[Widget テストの「あれ、これどうやるんだろう？」集](https://qiita.com/chooyan_eng/items/6ffd5b07de07edafd304)を書いてくれていますので、みんな要チェックです！

ここでは`GitHub Actions`を使った自動テストとカバレッジ取得の方法を紹介します。

設定ファイルをバーンと書いてしまうと次のようになります。`flutter`コマンドの`version`と`channel`を指定することができます。カバレッジ自体は`flutter test --coverage`で取れますが、それでは見にくいので[CodeCov](https://codecov.io/)で可視化してあげます。

```yaml:.github/workflows/test.yml
name: Test

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - uses: takuyaohashi/setup-flutter@v1
      with:
        flutter-version: 'latest'
        channel: stable
    - name: install dependencies
      run: flutter pub get
    - name: analyze
      run: flutter analyze
    - name: test
      run: flutter test --coverage
    - uses: codecov/codecov-action@v1
      with:
        token: ${{ secrets.CODECOV_TOKEN }}
```

複数バージョンで行いたい場合以下のように記述できます。テスト部分以外は割愛。

```yaml:.github/workflows/test.yml
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        flutter: [ 'latest', 'v1.9.1+hotfix.6' ]
    steps:
    - uses: actions/checkout@v1
    - uses: takuyaohashi/setup-flutter@v1
      with: 
        flutter-version: ${{ matrix.flutter }}
        channel: 'stable'
    - name: test
      run: flutter test
```

詳しくは下記ブログに書いてあるので参照してください。

* [GitHub Actions で自動テストを行う方法](https://flutter.takuchalle.dev/posts/how-to-test-on-github-actions/)
* [GitHub Actions でテストカバレッジを取得する](https://flutter.takuchalle.dev/posts/how-to-test-coverage-on-github-actions/)

ちなみに`flutter`コマンドを使えるようにするアクション([takuyaohashi/setup-flutter](https://github.com/takuyaohashi/setup-flutter))は自作しました。ああしたい、こうしたいがあれば気軽に`issue/PR`をください。

## verified publisher のなり方

![cloud_firestore_badge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75330/8a2c3191-713a-31f9-c2b3-0580d0baef69.png)

`verified publisher`になるとcloud_firebase の右にあるようなバッジがつきます。なんかかっこいいですね！！

`verified publisher`になる前提として**自身が管理しているドメインを持っていること**が必須です。私の場合`takuchalle.dev`ですね。ドメインさえもっていれば、パッケージを一つも登録していなくても`verified publisher`になることができます。それでいいのかって感じですけど笑

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">まだ何もないけど、バッジをゲットした。 <a href="https://twitter.com/hashtag/flutter?src=hash&amp;ref_src=twsrc%5Etfw">#flutter</a> <a href="https://twitter.com/hashtag/pub?src=hash&amp;ref_src=twsrc%5Etfw">#pub</a> <a href="https://t.co/KuDfv3JCmi">pic.twitter.com/KuDfv3JCmi</a></p>&mdash; たくチャレ@めざせポケモンマスター (@takuchalle) <a href="https://twitter.com/takuchalle/status/1197297503667777536?ref_src=twsrc%5Etfw">November 20, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

手順としては簡単で、右上のアカウントのところの`Create publisher`からポチポチ押していけばOKです。[pub.dev で verified publisher になる方法](https://flutter.takuchalle.dev/posts/how-to-be-verified-publisher/)に詳しい手順が書いてあるので参照してください。

## まとめ

`pub.dev`に自分のパッケージを登録する方法とそれに付随する周辺情報を紹介しました。

人のソースコードを読むのが好きなので、いろんな人がどんどんパッケージ化してオープンにしてノウハウを広めていって欲しくてこんな記事を書きました。ソースコードを読むためだけだったら`GitHub`を覗きに行けばいいのですが、良いパッケージがあれば自分のアプリに組み込んで楽をしたいし笑

もっと`Flutter`の勉強して私も貢献できるように頑張ります。

`Flutter`はフレームワークの良さもさることながら、`pub.dev`などのエコシステムもちゃんとしてるのが良いですね。`Dart`も普段C言語をメインに使ってる私からすると機能豊富だし、文末もセミコロンも気になりません。

明日は @mjhd-devlion さんの`flutter web`に関する記事です。楽しみですね！