ツール等でGithubのレポジトリに直接ファイルをアップロードしたいなー
っておもっていろんな記事をみてたらGitHubAPIでできるっぽいので
どうせなら汎用的にしておいたほうが個人的にもよさげだったので
phpで関数化しておきました
GitHubAPIはV3です
エラーチェックなど一切してないのでそのあたりはみなさんのほうでなんとかしてください💦
逆にこういう問題おこったよってのもぜひコメントにお寄せください!
あと、実際に利用する際は壊れてもいいリポジトリで試してからにしてください。
(これを開発中、Tree作成するときにbase_treeを指定しなかったために、まっさらになること連発しましたので・・もちろん履歴は追えるのはGitのいいところなのでもとに戻せます。。が、、)
流れ的には
ローカルファイルからBlob作成
最新Treeを取得
最新TreeのRootにBlob化したファイルを追加しTreeを作成
作成したTreeをCommit
CommitをHEADに反映する
という一連の流れにしています。
元来、パス指定したところのTreeにBlob追加したほうが良さそうですが
めんどくさがりましたw
ちなみにGitHub API access_tokenは
https://github.com/settings/applications/new
にアクセスしてアプリケーションを作成します。
callbackurlは存在しないURLでもOKです
Client IDが発行されるのでそのIDを以下のURLに付けてアクセス
https://github.com/login/oauth/authorize?scope=repo&client_id=XXXXXXXXX
してoauth認証をします
callbackURLにたどりつきますが、存在しないページにアクセスされるのですが
そのURLのcode引数を利用して以下のURLとしてアクセスします
アクセスすると
access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&scope=repo&token_type=bearer
てなデータが取得できます。
このaccess_tokenを利用することになります。
$authtoken="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; //GitHub API access_token
$projectname="hogehoge"; //
$repogitoryname="fugafuga"; //リポジトリ名 projectname/repogitorynameという形になります
$branch="master"; //ブランチ名 masterブランチ以外も指定できます
$realfilename="testtest.php"; //アップロードしたいファイル名
$gitfilepath="untarara/testtest.php"; //GitHub上でのファイル名 フルパスで。ただし先頭には/をつけないように!
$commitmessage="commit_".date("YmsHis"); //コミットメッセージ
//実行!
$ret = github_fileupload($projectname,$repogitoryname,$branch,$authtoken , $realfilename,$gitfilepath,$commitmessage);
print_r($ret);
function github_fileupload($projectname,$repogitoryname,$branch,$authtoken , $realfilename,$gitfilepath,$commitmessage)
{
if($branch=="")
{
$branch="master";
}
////////////////////
//BLOB create
$base64=base64_encode(file_get_contents($realfilename));
$apiurl="https://api.github.com/repos/".$projectname."/".$repogitoryname."/git/blobs";
$postdata=array("content"=>$base64,
"encoding"=>"base64"
);
$ret=github_apiaccess($apiurl,$authtoken,$postdata);
$retdata=json_decode($ret,true);
//print_r($retdata);
$sha_blob=$retdata["sha"];
////////////////////
//Get latest Tree sha (latest commit hash)
$apiurl="https://api.github.com/repos/".$projectname."/".$repogitoryname."/git/trees/".$branch;
$postdata=null;
$ret=github_apiaccess($apiurl,$authtoken,$postdata);
$retdata=json_decode($ret,true);
//print_r($retdata);
$sha_latestcommithash=$retdata["sha"];
//echo "*****sha_blob:".$sha_blob."\n";
//echo "*****sha_prevcommithash:".$sha_latestcommithash."\n";
////////////////////
//Create New tree(like git add file)
$apiurl="https://api.github.com/repos/".$projectname."/".$repogitoryname."/git/trees";
$postdata=array("base_tree"=>$sha_latestcommithash,
"tree"=>array(array("path"=>$gitfilepath,
"mode"=>"100644",
"type"=>"blob",
"sha"=>$sha_blob))
);
$ret=github_apiaccess($apiurl,$authtoken,$postdata);
$retdata=json_decode($ret,true);
//print_r($retdata);
$sha_newtree=$retdata["sha"];
//echo "*****sha_newtree:".$sha_newtree."\n";
////////////////////
//Commit
$apiurl="https://api.github.com/repos/".$projectname."/".$repogitoryname."/git/commits";
$postdata=array("message"=>$commitmessage,
"tree"=>$sha_newtree,
"parents"=>array($sha_latestcommithash)
);
$ret=github_apiaccess($apiurl,$authtoken,$postdata);
$retdata=json_decode($ret,true);
//print_r($retdata);
$sha_newcommithash=$retdata["sha"];
//echo "*****sha_newcommithash:".$sha_newcommithash."\n";
////////////////////
//reflect head
$apiurl="https://api.github.com/repos/".$projectname."/".$repogitoryname."/git/refs/heads/".$branch;
$postdata=array("force"=>false,
"sha"=>$sha_newcommithash
);
$ret=github_apiaccess($apiurl,$authtoken,$postdata);
$retdata=json_decode($ret,true);
return $retdata;
}
function github_apiaccess($apiurl,$authtoken,$postdata)
{
//echo $apiurl."\n";
$header[]="Accept: application/json";
$header[]="Content-Type: application/json";
$header[]="Authorization: bearer ".$authtoken;
$header[]="User-Agent: PHP_GITHUBAPI_FILEUPLOAD";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiurl);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
//curl_setopt($ch, CURLOPT_VERBOSE, true);
//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
//curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
//curl_setopt($ch, CURLOPT_AUTOREFERER, true);
if(is_array($postdata) && $postdata!=null)
{
curl_setopt($ch, CURLOPT_POST, true);
$postjson=json_encode($postdata, JSON_UNESCAPED_SLASHES);
//echo "POSTJSON:".$postjson."\n";
curl_setopt($ch, CURLOPT_POSTFIELDS, $postjson);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$ret = curl_exec($ch);
curl_close($ch);
return $ret;
}