TECH BOX

Technology blog from Web Engineer

この記事は最終更新日から6年以上経過しているため正確ではないかもしれません

Gitリポジトリのバージョン別zipを作る

GitHubなどのサービスではタグや任意でその時のzipをダウンロードすることができます。
ただ、Backlogなどでバージョンごとのファイルをダウンロードすることができないサービスを使っている際に、バージョンごとにzipファイルを作って別のウェブサーバでリストを作ってダウンロードをさせるというシステムを作る時の手順。

前提条件

下記の条件を満たしている必要あり

  • Webサーバ側:SSHが利用できる
  • Webサーバ側:Gitコマンドが利用できる
  • Webサーバ側:公開ディレクトリ以外の参照が可能(公開ディレクトリが一階層下にあるなど)
  • リポジトリ側:WebHookが利用できる

Webサーバ:リポジトリのログイン情報を保存

Webサーバ側でリポジトリをクローンする前に、いちいちリポジトリアクセス時にIDなどを聞かれると面倒なので、ドキュメントルート(公開ディレクトリの一つ上)に.netrcファイルを作成します。

machine リポジトリ名(ex. hoge.backlog.jp)
login ユーザー名
password パスワード

Webサーバ:SSHでアクセスしリポジトリをクローン

ドキュメントルート(公開ディレクトリの一つ上)に何かしらディレクトリを作成し、リポジトリをクローン
(ex. root/git/hogeにクローン)

$ ssh -p (ポート名) sshユーザー名@ホスト名

$ mkdir -p git/hoge

$ cd git/hoge

$ git clone --mirror https://リポジトリURL/hogehoge.git

注意すべき点は--mirrorオプションをつけること。
このオプションをつけないと、Webサーバ環境でもコミットなどができてしまいリモートとコンフリクトを起こすことがあるため、mirrorオプションでオリジナルの複製を作成します。

.netrcの設定が間違っていなければユーザー名やパスワードなどは聞かれません。

Webサーバ:WebHookを受け取る

WebHookを動作させるためのファイルを作ります。

ディレクトリは下記を例にします。

root
  ├ /git/
  │    └ /hoge/
  │         └ /git/
  │             └ /hoge.git/ (clone)
  └ /www/ (公開ディレクトリ)
      ├ archive_avgthf45.php (WebHookを動作)
      └ /downloads/ (ダウンロードさせるページ)
          ├ index.html(or php)
          ├ version.txt
          └ /zip/ (zipファイル置き場)

※例としてPHPで作成
※動作させるファイル名は簡単に類推されないようにランダムな文字列のファイルにしておく

<?php
// archive_avgthf45.php

$root_dir = 'ドキュメントルート';

// Gitリポジトリ
$rep_name = 'リポジトリ名';
$git_dir = "{$rep_dir}/git/hoge/${rep_name}.git";

// zipファイル置き場
$html_dir = "{$root_dir}/www/downloads";
$zip_dir = "{$html_dir}/zip";


// バージョンリストを記載するファイル
$version_file = "{$html_dir}/version.txt";


// Gitコマンド
$git_cmd = '/usr/local/bin/git';    // サーバによって違うので要確認
$git_target_ref = 'refs/tags/';     // 取得したいブランチ(この場合タグを取得)


/* WebHookを受信 */
$payload = json_decode($_POST['payload']);

// 指定したブランチでなければ処理をしない
if(strpos($payload->ref, $git_target_ref) === false) die;


// バージョンを抜き出す
$v = str_replace($git_target_ref, '', $payload->ref);

// zipコマンド実行
exec("{$git_cmd} --git-dir={$git_dir} fetch");
exec("{$git_cmd} --git-dir={$git_dir} archive --format zip --prefix={$v}/ {$v} -o {$zip_dir}/{$v}.zip");

// バージョン情報を記入
file_put_contents($version_file, date('Y.m.d') . "::{$v},,", FILE_APPEND);

WebHookされたらfetchしてコマンドでzipにして指定ディレクトリに作成したらバージョン情報をテキストに記入するという処理になります。

version.txtには下記のように保存されていきます。

2016.07.14::1.0.0,,2016.07.19::1.0.1,,2016.07.19::1.0.2,,2016.07.20::1.0.3,,2016.07.29::1.0.4,,2016.07.29::1.0.5,,2016.07.29::1.0.6,,2016.08.03::1.0.7,,2016.08.03::1.0.8,,2016.08.09::1.1.0,,2016.08.23::1.2.0,,2016.10.31::1.2.1,,2016.11.04::1.2.2,,2016.11.29::1.2.3,,2016.11.29::1.2.4,,2016.11.30::1.2.5,,2016.12.01::1.3.0,,2016.12.05::1.4.0,,2016.12.20::1.4.1,,2016.12.20::1.4.2,,2017.03.24::1.4.3,,

フロントエンドで::,,をキーに日付とバージョン名の配列を作成することができます。

WebHook:動作させるファイルを指定

WebHookにhttp://hogehoge.jp/archive_avgthf45.phpを動作させるように設定すれば良い。
たいてい設定画面にURLを入力するだけのはず。

Webサーバ:ダウンロードページを作成する

PHPなりJSなりでversion.txtを読み込み、::,,を分解して配列にすれば良い。

<?php
$version = file_get_contents('version.txt');
$version_arr = explode(',,', $version_text);

$res = [];

foreach($version_arr as $v){
  if(empty($v)) continue;

  $arr = explode('::', $v);
  $res[] = [
    'date'=>$arr[0],
    'v'=>$arr[1]
  ];
}

// 逆順にする
$r = array_reverse($res);

あとはHTMLとCSSでダウンロードリストを作れば完成。