LoginSignup
29
32

More than 5 years have passed since last update.

GitHubのリリース作成&ファイル添付を自動化する

Last updated at Posted at 2016-02-18

こういうのを作ります。

image.png

自動化したいこと

GitHubのリリースタスクをgulpで自動化できるようにします。

  • GitHub上にバージョンに応じたリリースを作成する
  • 作成したリリースにmy-package-v0.1.0.zipのようなファイルを添付する

配布したいバイナリやzipがある場合、リポジトリに含めるのではなくリリースの添付アセットにしておくと、ダンロード数が計測できたり、https://github.com/<user>/<repo>/releases/latestというURLで最新リリースへと誘導できたりしてなにかと便利です。

ワークフロー

実際のワークフローは以下のようになると思いますが、この記事で扱うのは (4) と (5) です。

  1. package.jsonのversionを更新する
  2. ビルドして配布用のバイナリを生成する
  3. master(とタグ)をGitHubにプッシュする
  4. GitHubにリリースを作成する
  5. リリースにファイルを添付する

リリース用のGitタグは (3) の段階で付けておいてもいいですが、作らなかった場合でも (4) を実行すればリモートには自動的にタグが設定されます。

【追記】(1)〜(3)は、npm-versionを使えば自動化できます。
参考 : npm version, preversion, postversionの使い分け

サンプルコード

紹介する内容は、デモプロジェクトとしてGitHubに公開しています。
https://github.com/htanjo/github-release-demo

パッケージ情報の取得

リリースのバージョンや配布するファイル名は、package.jsonの値を使います。

package.json:

{
  "name": "my-package",
  "version": "0.1.0",
  ...
}

require('./package.json')だとキャッシュされることがあるため、fs.readFileSync()で取得します。

var fs = require('fs');
var pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));

GitHub APIの利用

GitHub APIを使うことで、リリースの作成やファイルのアップロードができます。
Node.js上でGitHub APIを扱うためにgithub4をインストールします。(オリジナルのgithubモジュールはメンテが止まっていました。)

$ npm install github4 --save-dev
var GitHubApi = require('github4');
var github = new GitHubApi();

github.authenticate({
  type: 'oauth',
  token: 'xxxxxxxxxxxxxxxx'
});

// リリースの作成
github.repos.createRelease(...);

// ファイルのアップロード
github.repos.uploadAsset(...);

APIへのアクセストークンはPersonal Access Tokensのページから生成することができます。トークンは作成直後に一度しか表示されないので注意!

実際のプロジェクトでは、.authenticate()に渡す値は環境変数やconfigモジュールを使い、認証情報がソースコードに残らないようにします。

リリースの作成

github4の.createRelease()メソッドを使います。
標準ではcallbackでレスポンスを返しますが、Promiseで扱った方がgulpタスクにしやすいため、pifyでラップしました。

$ npm install pify --save-dev
var pify = require('pify');

pify(github.repos.createRelease)({
    user: 'htanjo',
    repo: 'github-release-demo',
    tag_name: 'v' + pkg.version,
    body: 'Release v' + pkg.version   // リリースノート(Markdownに対応)
  })
  .then(function (res) {
    console.log(res);                 // APIからのレスポンス
    console.log(res.id);              // リリースID(ファイルアップロード時に必要になる)
  });

ファイルのアップロード

github4の.uploadAsset()を使います。
どのリリースに添付するかは、リリースIDでの指定が必要です。タグ名ではダメなようです。
ファイルの指定はfilePathオプションを使います。この例では"dist/my-package.zip"がすでに生成されているとします。

pify(github.repos.uploadAsset)({
    user: 'htanjo',
    repo: 'github-release-demo',
    id: id,                                         // .createRelease()のレスポンスで取得したID
    name: pkg.name + '-v' + pkg.version + '.zip',   // 配布時のファイル名
    filePath: 'dist/' + pkg.name + '.zip'           // アップロードするファイル
  })
  .then(function (res) {
    console.log(res);       // APIからのレスポンス
  });

gulpタスクの作成

以上をまとめてgulpタスクにします。
非同期処理がいくつもありますが、Promise化してあるのでそのままgulp.task()returnすればOKです。

npm install gulp gulp-util --save-dev

gulpfile.js:

var gulp = require('gulp');
var gutil = require('gulp-util');
var GitHubApi = require('github4');
var pify = require('pify');
var fs = require('fs');

var pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
var github = new GitHubApi();

github.authenticate({
  type: 'oauth',
  token: 'xxxxxxxxxxxxxxxx'
});

gulp.task('release', function () {
  return pify(github.repos.createRelease)({
      user: 'htanjo',
      repo: 'github-release-demo',
      tag_name: 'v' + pkg.version,
      body: 'Release v' + pkg.version
    })
    .then(function (res) {
      gutil.log('Release "' + res.tag_name + '" created');
      return res.id;
    })
    .then(function (id) {
      return pify(github.repos.uploadAsset)({
        user: 'htanjo',
        repo: 'github-release-demo',
        id: id,
        name: pkg.name + '-v' + pkg.version + '.zip',
        filePath: 'dist/' + pkg.name + '.zip'
      })
    })
    .then(function (res) {
      gutil.log('Asset "' + res.name + '" uploaded');
    });
});

リリース作成/ファイルアップロードを2つのタスクに分けておくと、後からファイル添付だけできるようになったり便利ですが、別途リリースIDを取得する必要があります。その場合は.getReleaseByTag()を使えばタグ名からIDが取得できます。

リリースしてみる

gulpタスクを実行!

$ gulp release
[18:01:42] Using gulpfile ~/lab/github-release-demo/gulpfile.js
[18:01:42] Starting 'release'...
[18:01:43] Release "v0.1.0" created
[18:01:44] Asset "my-package-v0.1.0.zip" uploaded
[18:01:44] Finished 'release' after 1.9 s

リリース完了、ファイルも添付されました!

release.png

デモプロジェクト
https://github.com/htanjo/github-release-demo

実際のリリースページ
https://github.com/htanjo/github-release-demo/releases

29
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
32