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

ツール等でGithubのレポジトリに直接ファイルをアップロードしたいなー
っておもっていろんな記事をみてたらGitHubAPIでできるっぽいので
どうせなら汎用的にしておいたほうが個人的にもよさげだったので
phpで関数化しておきました
GitHubAPIはV3です

エラーチェックなど一切してないのでそのあたりはみなさんのほうでなんとかしてください💦
逆にこういう問題おこったよってのもぜひコメントにお寄せください！

あと、実際に利用する際は壊れてもいいリポジトリで試してからにしてください。
（これを開発中、Tree作成するときにbase_treeを指定しなかったために、まっさらになること連発しましたので・・もちろん履歴は追えるのはGitのいいところなのでもとに戻せます。。が、、）

流れ的には
　ローカルファイルからBlob作成
　最新Treeを取得
　最新TreeのRootにBlob化したファイルを追加しTreeを作成
　作成したTreeをCommit
　CommitをHEADに反映する
という一連の流れにしています。

元来、パス指定したところのTreeにBlob追加したほうが良さそうですが
めんどくさがりましたｗ


ちなみに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を利用することになります。



```php

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



```