From 5207c762d9c975fec66081528f2cd86c8b3d18ed Mon Sep 17 00:00:00 2001 From: bubkoo Date: Wed, 23 Nov 2022 10:31:36 +0800 Subject: [PATCH] feat: export app name to env or save to secret --- action.yml | 27 ++++++++++++++++----------- package.json | 10 +++++----- src/action.ts | 35 +++++++++++++++++++++-------------- src/util.ts | 48 +++++++++++++++++++++--------------------------- yarn.lock | 32 ++++++++++++++++---------------- 5 files changed, 79 insertions(+), 73 deletions(-) diff --git a/action.yml b/action.yml index aaa4443..8039df5 100644 --- a/action.yml +++ b/action.yml @@ -11,23 +11,28 @@ inputs: fallback: description: The fallback token when bot token generate failed. required: false - variable_name: - description: The name of generated token in exported environment variable. + app_login_name: + description: The app login name exported to `env` or saved to `secrets`. required: false - env_name: - description: The name of generated token in exported environment variable. + default: BOT_NAME + app_token_name: + description: The app token name exported to `env` or saved to `secrets`. required: false - secret_name: - description: The secret name created on current repository. - required: false - clean_secret: - description: Should clean the secret or not when this action run completed. + default: BOT_TOKEN + secret: + description: Specify true to save app token and app login name into the secrets of current repository. required: false default: false + clean: + description: Specify true to clean saved secrets when workflow run completed. + required: false + default: true outputs: - token: - description: The token for the GitHub App on the current repository. + bot_name: + description: The name of the GitHub App on the current repository. + bot_token: + description: The token of the GitHub App on the current repository. runs: using: node16 diff --git a/package.json b/package.json index 4a80341..d8e5ad4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "use-app-token", - "version": "1.2.0", + "version": "2.0.0", "description": "Run GitHub Actions as a GitHub App by using the app's authentication token", "main": "dist/index.js", "files": [ @@ -43,15 +43,15 @@ "@bubkoo/tsconfig": "^1.0.0", "@types/is-base64": "^1.1.0", "@types/libsodium-wrappers": "^0.7.10", - "@types/node": "^18.11.7", + "@types/node": "^18.11.9", "@vercel/ncc": "^0.34.0", - "eslint": "^8.26.0", - "husky": "^8.0.1", + "eslint": "^8.28.0", + "husky": "^8.0.2", "is-ci": "^3.0.1", "npm-run-all": "^4.1.5", "prettier": "^2.7.1", "pretty-quick": "^3.1.3", "rimraf": "^3.0.2", - "typescript": "^4.8.4" + "typescript": "^4.9.3" } } diff --git a/src/action.ts b/src/action.ts index 7815c67..d2ec197 100644 --- a/src/action.ts +++ b/src/action.ts @@ -4,21 +4,23 @@ import * as util from './util' export async function run() { try { const token = await util.getAppToken() - core.info('Token generated!') + const loginName = util.getAppLoginName() + const tokenName = util.getAppTokenName() - const secretName = core.getInput('secret_name') - if (secretName) { - await util.saveTokenToSecret(secretName, token) - core.info(`Save token in secret "${secretName}"`) + const saveToSecret = core.getBooleanInput('secret') + if (saveToSecret) { + await util.createSecret(token, loginName, token) + await util.createSecret(token, tokenName, token) + core.info(`Secrets "${loginName}" and "${tokenName}" was created`) } core.setSecret(token) - core.setOutput('token', token) - const envName = core.getInput('env_name') || core.getInput('variable_name') - if (envName) { - core.exportVariable(envName, token) - } + core.setOutput('bot_name', token) + core.setOutput('bot_token', token) + + core.exportVariable(loginName, token) + core.exportVariable(tokenName, token) } catch (e) { core.error(e) core.setFailed(e.message) @@ -27,10 +29,15 @@ export async function run() { export async function cleanup() { try { - const secretName = core.getInput('secret_name') - if (secretName) { - await util.removeTokenFromSecret(secretName) - core.info(`Token in secret "${secretName}" was cleaned`) + const clean = core.getBooleanInput('clean') + const saveToSecret = core.getBooleanInput('secret') + if (saveToSecret && clean) { + const token = await util.getAppToken() + const loginName = util.getAppLoginName() + const tokenName = util.getAppTokenName() + await util.deleteSecret(token, loginName) + await util.deleteSecret(token, tokenName) + core.info(`Secrets "${loginName}" and "${tokenName}" was removed`) } } catch (e) { core.error(e) diff --git a/src/util.ts b/src/util.ts index f5aaa07..47c7539 100644 --- a/src/util.ts +++ b/src/util.ts @@ -5,6 +5,14 @@ import sodium from 'libsodium-wrappers' import { Octokit } from '@octokit/core' import { createAppAuth } from '@octokit/auth-app' +export function getAppLoginName() { + return core.getInput('app_login_name') || 'BOT_NAME' +} + +export function getAppTokenName() { + return core.getInput('app_token_name') || 'BOT_TOKEN' +} + export async function getAppToken() { const fallback = core.getInput('fallback') const required = fallback == null @@ -29,22 +37,23 @@ export async function getAppToken() { // 2. Get installationId of the app const octokit = github.getOctokit(jwt) - const { - data: { id: installationId }, - } = await octokit.rest.apps.getRepoInstallation({ + const install = await octokit.rest.apps.getRepoInstallation({ ...github.context.repo, }) // 3. Retrieve installation access token const { token } = await auth({ - installationId, type: 'installation', + installationId: install.data.id, }) + // eslint-disable-next-line no-console + console.log(install.data) + return token } -async function createSecret(octokit: Octokit, value: string) { +async function makeSecret(octokit: Octokit, value: string) { const { repo } = github.context const res = await octokit.request( 'GET /repos/:owner/:repo/actions/secrets/public-key', @@ -72,45 +81,30 @@ async function createSecret(octokit: Octokit, value: string) { } } -async function createOrUpdateRepoSecret( +export async function createSecret( token: string, - name: string, - value: string, + secretName: string, + secretValue: string, ) { const octokit = new Octokit({ auth: token }) - const secret = await createSecret(octokit, value) + const secret = await makeSecret(octokit, secretValue) await octokit.request( 'PUT /repos/:owner/:repo/actions/secrets/:secret_name', { ...github.context.repo, - secret_name: name, + secret_name: secretName, data: secret, }, ) } -async function deleteSecret(token: string, name: string) { +export async function deleteSecret(token: string, secretName: string) { const octokit = new Octokit({ auth: token }) await octokit.request( 'DELETE /repos/:owner/:repo/actions/secrets/:secret_name', { ...github.context.repo, - secret_name: name, + secret_name: secretName, }, ) } - -export async function saveTokenToSecret(secretName: string, token: string) { - if (secretName) { - return createOrUpdateRepoSecret(token, secretName, token) - } - return null -} - -export async function removeTokenFromSecret(secretName: string) { - if (secretName) { - const token = await getAppToken() - return deleteSecret(token, secretName) - } - return null -} diff --git a/yarn.lock b/yarn.lock index 4a33b28..05353ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -719,10 +719,10 @@ resolved "https://registry.npmjs.org/@types/node/-/node-16.9.2.tgz" integrity sha512-ZHty/hKoOLZvSz6BtP1g7tc7nUeJhoCf3flLjh8ZEv1vFKBWHXcnMbJMyN/pftSljNyy0kNW/UqI3DccnBnZ8w== -"@types/node@^18.11.7": - version "18.11.7" - resolved "https://registry.npmmirror.com/@types/node/-/node-18.11.7.tgz#8ccef136f240770c1379d50100796a6952f01f94" - integrity sha512-LhFTglglr63mNXUSRYD8A+ZAIu5sFqNJ4Y2fPuY7UlrySJH87rRRlhtVmMHplmfk5WkoJGmDjE9oiTfyX94CpQ== +"@types/node@^18.11.9": + version "18.11.9" + resolved "https://registry.npmmirror.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" + integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -1508,10 +1508,10 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@^8.26.0: - version "8.26.0" - resolved "https://registry.npmmirror.com/eslint/-/eslint-8.26.0.tgz#2bcc8836e6c424c4ac26a5674a70d44d84f2181d" - integrity sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg== +eslint@^8.28.0: + version "8.28.0" + resolved "https://registry.npmmirror.com/eslint/-/eslint-8.28.0.tgz#81a680732634677cc890134bcdd9fdfea8e63d6e" + integrity sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ== dependencies: "@eslint/eslintrc" "^1.3.3" "@humanwhocodes/config-array" "^0.11.6" @@ -1876,10 +1876,10 @@ human-signals@^1.1.1: resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== -husky@^8.0.1: - version "8.0.1" - resolved "https://registry.npmmirror.com/husky/-/husky-8.0.1.tgz#511cb3e57de3e3190514ae49ed50f6bc3f50b3e9" - integrity sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw== +husky@^8.0.2: + version "8.0.2" + resolved "https://registry.npmmirror.com/husky/-/husky-8.0.2.tgz#5816a60db02650f1f22c8b69b928fd6bcd77a236" + integrity sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg== ignore@^5.0.5, ignore@^5.1.4: version "5.1.8" @@ -3147,10 +3147,10 @@ type-fest@^0.8.1: resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -typescript@^4.8.4: - version "4.8.4" - resolved "https://registry.npmmirror.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" - integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== +typescript@^4.9.3: + version "4.9.3" + resolved "https://registry.npmmirror.com/typescript/-/typescript-4.9.3.tgz#3aea307c1746b8c384435d8ac36b8a2e580d85db" + integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA== unbox-primitive@^1.0.1: version "1.0.1"