Skip to content

Instantly share code, notes, and snippets.

@Yudai-Imai
Last active December 5, 2022 09:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Yudai-Imai/c31d98d9196fef7725a1e00fbe0c6cd8 to your computer and use it in GitHub Desktop.
Save Yudai-Imai/c31d98d9196fef7725a1e00fbe0c6cd8 to your computer and use it in GitHub Desktop.
【GAS】【改良版】FormのレスポンスをGitLabにCommitしてMergeRequestを発行する
function main(e) {
// メイン関数
// Google formに回答があった時とスケジュールで動作する
//
// 回答があった場合:
// 回答内容を集計しているスプレッドシートに接続し、歴代の回答内容からGitLabにあるterraform.tfvarsの内容を作成する
//
// スケジュールの場合(現在は稼働していない):
// 回答内容が変わっていないか(継続するが継続しないに変わっているか)を確認する
// 変わっていた場合はプロジェクトは削除される
// スクリプトプロパティの取得
var prop = PropertiesService.getScriptProperties();
var GITLAB_ACCESS_TOKEN = prop.getProperty("GITLAB_ACCESS_TOKEN");
var GITLAB_PROJECT_ID = prop.getProperty("GITLAB_PROJECT_ID");
var BILLING_ACCOUNT_ID_NIC_TRAINING = prop.getProperty("BILLING_ACCOUNT_ID_NIC_TRAINING");
// Google formの回答内容と回答日時の取得
const itemResponses = e.response.getItemResponses();
var pj_name = itemResponses[5].getResponse();
console.log(pj_name);
const responseTimestamp = e.response.getTimestamp().toJSON();
const responseAddress = e.response.getRespondentEmail();
// プロジェクト名と回答日時からハッシュ値(MD5)の作成
var pj_name_and_time = pj_name + responseTimestamp;
var branchName = convertToHMmacMD5(pj_name_and_time,GITLAB_PROJECT_ID);
// 回答を集計しているスプレッドシートから累計の回答内容を取得
// 最新の回答内容が反映されるタイミングを調整するため10秒待機
Utilities.sleep(10000);
var spreadsheet = SpreadsheetApp.openById("Google SheetsのID").getActiveSheet();
var lastRowNum = spreadsheet.getLastRow() - 1;
var project_name_array = spreadsheet.getRange(2,8,lastRowNum).getValues().flat();
var project_id_array = spreadsheet.getRange(2,9,lastRowNum).getValues().flat();
var folder_name_array = spreadsheet.getRange(2,6,lastRowNum).getValues().flat();
var billing_account_array = spreadsheet.getRange(2,13,lastRowNum).getValues().flat();
var owner_account_array = spreadsheet.getRange(2,11,lastRowNum).getValues().flat();
var keizoku_array = spreadsheet.getRange(2,14,lastRowNum).getValues().flat();
// GitLabにプッシュするコンテンツを作成する
var content = "gcp_projects = [\n"
for(let i=0; i<project_name_array.length; i++){
console.log(i);
// プロジェクト名の取得
var pj_name = project_name_array[i];
console.log(pj_name);
// プロジェクトIDの取得
// プロジェクトIDが指定されていない(空白)場合はプロジェクト名を小文字にして流用
if (project_id_array[i] === ""){
console.log('pj_id undefined');
var pj_id = project_name_array[i].toLowerCase();
console.log(pj_id);
}else{
var pj_id = project_id_array[i];
console.log(pj_id);
};
// プロジェクトの用途によりフォルダー分けを行う
if (folder_name_array[i] === "PJ(案件)での検証利用"){
var folder = "folder/AAAAAA";
var folder_category = "PJ(案件)での検証利用";
console.log(folder);
}else if (folder_name_array[i] === "個人での検証利用"){
var folder = "folder/BBBBBB";
var folder_category = "個人での検証利用";
console.log(folder);
}else if (folder_name_array[i] === "施策での利用"){
var folder = "folder/CCCCCC";
var folder_category = "施策での利用";
console.log(folder);
}else if (folder_name_array[i] === "学習クラウドでの利用"){
var folder = "folder/DDDDDD";
var folder_category = "学習クラウドでの利用";
console.log(folder);
};
// オーナーアカウントを配列として取得
// 基本的に「admin@admin」は管理アカウントのため必須
var owner_account_str = owner_account_array[i];
if(owner_account_str.match(/,/) || owner_account_str.match(/、/)){
var owner_account_str = owner_account_str.replace(/ | /g, '');
var owner_account_list = owner_account_str.split(/,|、/);
owner_account_list.push("admin@admin");
console.log(owner_account_list);
}else{
var owner_account_list = [owner_account_str,"admin@admin"];
console.log(owner_account_list);
};
// ビリングアカウントが「test-billing」の場合はビリングアカウントIDを指定
// ビリングアカウントが「test-billing」ではない場合はnullを明示的に指定
if (billing_account_array[i] === "test-billing"){
var billing_account = BILLING_ACCOUNT_ID_NIC_TRAINING;
console.log(billing_account);
var concatText = ' {\n project_name = "' + pj_name + '"\n project_id = "' + pj_id + '"\n folder_category = "' + folder_category + '"\n folder_name = "' + folder + '"\n billing_account = "' + billing_account + '"\n owner_account = ["user:' + owner_account_list.join('","user:') + '"]\n },\n';
}else {
console.log('billing_account not nic-training or undefined');
var billing_account = "null";
var concatText = ' {\n project_name = "' + pj_name + '"\n project_id = "' + pj_id + '"\n folder_category = "' + folder_category + '"\n folder_name = "' + folder + '"\n billing_account = ' + billing_account + '\n owner_account = ["user:' + owner_account_list.join('","user:') + '"]\n },\n';
console.log(billing_account);
};
console.log(concatText);
var content = content + concatText;
}
// GitLabにプッシュするコンテンツの作成完了
var content = content + ']';
console.log(content);
// GitLabの認証系
var headers = {
'Authorization':'Bearer ' + GITLAB_ACCESS_TOKEN,
'contentType': 'application/json'
};
// GitLabにコミットをプッシュするときのURLとオプション
var commitURL = 'https://gitlab.com/api/v4/projects/' + GITLAB_PROJECT_ID + '/repository/files/environments%2Ftemplate%2Fterraform%2Etfvars';
var commitData = {
'id': GITLAB_PROJECT_ID,
'branch': branchName,
'start_branch': 'main',
'commit_message': 'update terraform.tfvars',
'content': content
};
var commitOptions = {
'method' : 'PUT',
'headers': headers,
'payload' : commitData
};
// GitLabにマージリクエストするときのURLとオプション
var mrURL = 'https://gitlab.com/api/v4/projects/' + GITLAB_PROJECT_ID + '/merge_requests';
var mrData = {
'id': GITLAB_PROJECT_ID,
'source_branch': branchName,
'target_branch': 'main',
'title': pj_name + 'の作成申請',
'description': responseAddress + 'がGCP社内プロジェクトの作成を申請しました。 \nこのマージリクエストよりも以前のマージリクエストがまだ存在する場合は、以前のマージリクエストがマージされるまで、マージを行わないでください。 \nレビュアー各位は申請された内容をご確認ください。',
'remove_source_branch': true
};
var mrOptions = {
'method' : 'POST',
'headers': headers,
'payload' : mrData
};
try {
// GitLabにコミットをプッシュし、その内容をマージリクエストする
var commitResponse = UrlFetchApp.fetch(commitURL, commitOptions);
console.log(JSON.parse(commitResponse));
// Utilities.sleep(10000);
var mrResponse = UrlFetchApp.fetch(mrURL, mrOptions);
console.log(JSON.parse(mrResponse));
} catch(e) {
// 例外エラー処理
console.log('Error:');
console.log(e);
};
}
function convertToHMmacMD5(text, key) {
// ハッシュ値を文字列として返却する関数
const rowHash = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_MD5, text, key);
let txtHash = '';
for (i = 0; i < rowHash.length; i++) {
let hashVal = rowHash[i];
if (hashVal < 0) {
hashVal += 256;
}
if (hashVal.toString(16).length == 1) {
txtHash += '0';
}
txtHash += hashVal.toString(16);
}
return txtHash;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment