PHP
GitHub
GitHubAPI

phpでgithubにファイルをアップロードする関数をつくってみた

ツール等で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としてアクセスします

https://github.com/login/oauth/access_token?code=code引数&client_id=アプリケーション登録したとき作成されたClientID&client_secret=アプリケーション登録したとき作成されたClientSecret

アクセスすると

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;
}