Created
February 25, 2025 07:05
-
-
Save Atsumi3/468f2bbfe3e62d25fbbe21e09899d0ad to your computer and use it in GitHub Desktop.
GithubのSecretsをスプシから更新するためのGAS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// 例: https://github.com/Atsumi3/AppManager | |
/// const _GITHUB_OWNER = "Atsumi3"; | |
/// const _GITHUB_REPOSITORY = "AppManager"; | |
const _GITHUB_OWNER = ""; | |
const _GITHUB_REPOSITORY = ""; | |
/// Permission: Read and Write -> actions variables and secrets | |
const _GITHUB_PAT = ""; | |
/// Secretsの値更新のために LibSodium 相当でハッシュ化出来る関数が必要 | |
/// このGASでは外のAPIで変換する | |
/// サーバ側のサンプル https://github.com/Atsumi3/nk-sodium-api | |
const _SODIUM_ENCRYPT_API_ENDPOINT = ""; | |
const _SHEET_NAME = "Secrets"; | |
const _SECRET_API_BASE = `https://api.github.com/repos/${_GITHUB_OWNER}/${_GITHUB_REPOSITORY}/actions/secrets`; | |
function updateGithubSecrets() { | |
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(_SHEET_NAME); | |
const data = sheet.getDataRange().getValues(); | |
const secrets = {}; | |
/// 2行目から | |
for (let i = 1; i < data.length; i++) { | |
/// 1列目 | |
const secretKey = data[i][0]; | |
/// 2列目 | |
const secretValue = data[i][1]; | |
if (secretKey && secretValue) { | |
secrets[secretKey] = secretValue; | |
} | |
} | |
const headerAuthValue = `token ${_GITHUB_PAT}`; | |
const options = { | |
method: "get", | |
headers: { | |
"Authorization": headerAuthValue, | |
"Accept": "application/vnd.github+json" | |
} | |
}; | |
const response = UrlFetchApp.fetch(`${_SECRET_API_BASE}/public-key`, options); | |
const publicKeyData = JSON.parse(response.getContentText()); | |
const keyId = publicKeyData.key_id; | |
const publicKey = publicKeyData.key; | |
for (const secretName in secrets) { | |
const plainValue = secrets[secretName]; | |
const payload = { | |
"encrypted_value": _encryptSecret(plainValue, publicKey), | |
"key_id": keyId | |
}; | |
const putOptions = { | |
method: "put", | |
headers: { | |
"Authorization": headerAuthValue, | |
"Accept": "application/vnd.github+json", | |
"Content-Type": "application/json" | |
}, | |
payload: JSON.stringify(payload), | |
muteHttpExceptions: true | |
}; | |
const putResponse = UrlFetchApp.fetch(`${_SECRET_API_BASE}/${secretName}`, putOptions); | |
Logger.log(`Secret ${secretName} 更新: HTTPステータス ${putResponse.getResponseCode()}`); | |
} | |
} | |
/** | |
* GitHubのSecret値を暗号化する関数 | |
* 外部で作成したLibSodium相当のAPI を呼び出します。 | |
* | |
* @param {string} plainText - 暗号化する平文(例:"123" や "あいうえお") | |
* @param {string} base64PublicKey - GitHubから取得した公開鍵(base64エンコード済み) | |
* @return {string} - 暗号化後の値(base64エンコード済みの文字列) | |
*/ | |
function _encryptSecret(plainText, base64PublicKey) { | |
var payload = { | |
text: plainText, | |
publicKey: base64PublicKey | |
}; | |
var options = { | |
method: 'post', | |
contentType: 'application/json', | |
payload: JSON.stringify(payload), | |
muteHttpExceptions: true | |
}; | |
var response = UrlFetchApp.fetch(_SODIUM_ENCRYPT_API_ENDPOINT, options); | |
if (response.getResponseCode() !== 200) { | |
throw new Error('Encryption API returned error: ' + response.getContentText()); | |
} | |
var result = JSON.parse(response.getContentText()); | |
return result.encrypted; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment