👨‍👩‍👧‍👦

GitHubにgoogledriveのコンテンツをGASでpushする

2023/01/31に公開

概要

これは何

この記事では、google drive上のテキストファイルをGithubのリポジトリにcommit,pushするGASのスクリプトを紹介します。

使ったもの

実装

リポジトリ

https://github.com/mirito333/gas-github-drive

使い方

commitDriveGitHubに次のパラメータを渡してあげると、対象filderId内のファイルをbranchのmasterにpushします。リポジトリではプロパティストアに格納しています。

やってること

  1. GitHubから親コミットの取得
function getGithubParent(props){
  var response = UrlFetchApp.fetch(props.base_url+"refs/heads/master", {
    headers: {
      Authorization: 'token ' + props.token
    }
  });
  props.base_ref = JSON.parse(response).object.sha
  response = UrlFetchApp.fetch(props.base_url+"commits/"+props.base_ref, {
    headers: {
      Authorization: 'token ' + props.token
    }
  });
  props.base_tree = JSON.parse(response).tree.sha
  return props
}
  1. folderId内のファイル名とその内容を取得
function getDriveFiles(folderId,extensions){
  const folder = DriveApp.getFolderById(folderId);
  const files = folder.getFiles();
  const fileContents = []
  while(files.hasNext()){
    
    let file = files.next();

    let fileName =file.getName();
    let fileContent = ""
    if (extensions.includes(getFileExtension(fileName))){
      fileContent = file.getBlob().getDataAsString("utf-8");
      fileContents.push({name: fileName,content: fileContent})
    }   
  }
  return fileContents
}
  1. 各ファイルについてblobの作成
function createGithubBlobs(props,files){
  let blobs = []
  files.forEach(function(file){
    let content = file.content
    let response = UrlFetchApp.fetch(props.base_url+"blobs", {
      'method' : 'POST',
      headers: {
        Authorization: 'token ' + props.token,
      },
      'payload' : JSON.stringify({
        "content": content,
        "encoding": "utf-8"
      })
    });
    blobs.push({fileName: file.name, sha: JSON.parse(response).sha})
  })
  return blobs
}
  1. blobをtreeにして、commitする
function createGithubTree(props,blobs){
  let post_data = {
    "base_tree": props.base_tree,
    "tree": []
  }
  blobs.forEach(function(blob){
    post_data.tree.push(
      {
        "path": blob.fileName,
        "mode": "100644",
        "type": "blob",
        "sha" : blob.sha
      }
    )
  })
  let response = UrlFetchApp.fetch(props.base_url+"trees", {
    'method' : 'POST',
    headers: {
      Authorization: 'token ' + props.token,
    },
    'payload' : JSON.stringify(post_data)
  });
  return JSON.parse(response).sha
}

参考

https://int128.hatenablog.com/entry/2017/09/05/161641

Discussion