はじめに

以前の記事で、CLIツールをPharファイルで作成する手順を簡単に紹介しました。
今回はPharファイルの作成と配布までをCircleCIで自動化する手順を紹介したいと思います。

まずは、Pharファイルを生成処理をbuildコマンド、GitHubへのリリース処理をreleaseコマンドとして、Composerのscriptsを利用して実装したいと思います。
最後にそれらをCircleCIから呼び出すような設定ファイル(.circleci/config.yml)を作成したいと思います。

buildコマンドの実装

Pharファイルを生成する処理を、buildコマンドとしてまとめます。

composer.json

Boxを利用してPharファイルの作成をcomposer-scriptsbuildコマンドとして作成します。

"scripts": {

    "build": [
       "rm -rf ./dist",
       "mkdir -p ./dist",
       "php -d phar.readonly=0 ./bin/box.phar build"
    ],

box.json

上記のbuildコマンドは、distディレクトリにPharファイルが作成されることを期待した内容になっていますので、以前のブログ記事で作成したbox.jsonの内容を以下のように修正します。

 {
     "alias": "hello.phar",
     "chmod": "0755",
     "compactors": [],
     "directories": ["src", "vendor"],
     "main": "main.php",
-    "output": "hello.phar",
+    "output": "dist/hello.phar",
     "stub": true
 }

releaseコマンドの実装

PharファイルをGitHubリリースページへアップロードする処理を、releaseコマンドとしてまとめます。

composer.json

リリースの前には、buildコマンドが実行されるように設定し、必ずPharファイルが作成してある状態になるようにしてあります。
その後、ghrというツールを使って、ビルドしたPharファイルをGitHubのリリースページにアップロードしています。

"scripts": {

    "release": [
        "@build",
        "./bin/ghr -u qcmnagai v$(./dist/hello.phar --version | cut -d \" \" -f 2) ./dist"
    ]

ghr

簡単にGitHubへリリースするためのGolang製CLIツールです。
タグとバイナリファイルが含まれるディレクトリを指定するだけで、GitHubへリリースをしてくれます。
今回は構成を簡単にする為にbin/ghrにバイナリ配置し、Gitリポジトリにも含めています。

タグについて

hello.phar --version でバージョン番号を表示させて、cutコマンドでバージョン番号部分だけ抜き出して、GitHubのタグとしてghrに渡すようにしています。
これにより、PHPのソースコードを修正するだけで、タグの追加からリリースページの作成まで、自動的に行なってくれるようになります。

ちなみにghrはデフォルトで、既に存在するタグに対する更新はエラーになりますので、一度リリースされたバージョンが上書きされるようなことはありません。
これでバージョン番号を更新し忘れても、安心ですね。

CircleCIの設定ファイル

今回は、qcmnagai/hello-phpというリポジトリで作成しましたので、以下のようになりました。

.circleci/config.yml

version: 2
jobs:
  build:
    docker:
      - image: circleci/php:7.0-node-browsers
    working_directory: ~/hello-php
    steps:
      - checkout
      - restore_cache:
          key: composer-v1-{{ checksum "composer.json" }}
      - run: composer install --no-interaction --prefer-dist --dev
      - save_cache:
          key: composer-v1-{{ checksum "composer.json" }}
          paths:
            - bin
            - vendor
      - run: composer test
  release:
    docker:
      - image: circleci/php:7.0-node-browsers
    working_directory: ~/hello-php
    steps:
      - checkout
      - restore_cache:
          key: composer-v1-{{ checksum "composer.json" }}
      - run: composer install --no-interaction --prefer-dist --no-dev
      - run: composer release

workflows:
  version: 2
  test_and_release:
    jobs:
      - build
      - release:
          requires:
            - build
          filters:
            branches:
              only: master

masterブランチへプッシュされた時だけ、releaseジョブが走るようになっています。
リリース処理をcomposer releaseコマンドでまとめたのでスッキリしていますね。

おわりに

このようにしておけば、GitHubのmasterブランチへマージしたタイミングで、ビルドからGitHubのリリースページへのアップロードをCircleCIが自動でやってくれます。
利用する際には、GitHubのリリースページからPharファイルダウンロードしてそのまま実行することが出来るようになり、とても便利でオススメです。