-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
92 additions
and
73 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import * as core from '@actions/core' | ||
import * as github from '@actions/github' | ||
import { App } from '@octokit/app' | ||
import isBase64 from 'is-base64' | ||
import { Util } from './util' | ||
|
||
export namespace Action { | ||
export async function start() { | ||
try { | ||
const id = Number(core.getInput('APP_ID', { required: true })) | ||
const privateKeyInput = core.getInput('PRIVATE_KEY', { required: true }) | ||
const privateKey = isBase64(privateKeyInput) | ||
? Buffer.from(privateKeyInput, 'base64').toString('utf8') | ||
: privateKeyInput | ||
const app = new App({ id, privateKey }) | ||
const jwt = app.getSignedJsonWebToken() | ||
const octokit = github.getOctokit(jwt) | ||
const { | ||
data: { id: installationId }, | ||
} = await octokit.apps.getRepoInstallation(github.context.repo) | ||
const token = await app.getInstallationAccessToken({ | ||
installationId, | ||
}) | ||
|
||
const secretName = core.getInput('SECRET_NAME') | ||
if (secretName) { | ||
await Util.createOrUpdateRepoSecret(octokit, secretName, token) | ||
} | ||
|
||
core.setSecret(token) | ||
core.setOutput('token', token) | ||
core.info('Token generated successfully!') | ||
} catch (e) { | ||
core.error(e) | ||
core.setFailed(e.message) | ||
} | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,3 @@ | ||
import * as core from '@actions/core' | ||
import * as github from '@actions/github' | ||
import { App } from '@octokit/app' | ||
import isBase64 from 'is-base64' | ||
import sodium from 'tweetsodium' | ||
import { Action } from './action' | ||
|
||
async function run() { | ||
try { | ||
const id = Number(core.getInput('APP_ID', { required: true })) | ||
const privateKeyInput = core.getInput('PRIVATE_KEY', { required: true }) | ||
const privateKey = isBase64(privateKeyInput) | ||
? Buffer.from(privateKeyInput, 'base64').toString('utf8') | ||
: privateKeyInput | ||
const app = new App({ id, privateKey }) | ||
const jwt = app.getSignedJsonWebToken() | ||
const octokit = github.getOctokit(jwt) | ||
const { | ||
data: { id: installationId }, | ||
} = await octokit.apps.getRepoInstallation(github.context.repo) | ||
const token = await app.getInstallationAccessToken({ | ||
installationId, | ||
}) | ||
|
||
await createOrUpdateTokenInSecret(octokit, token) | ||
core.setSecret(token) | ||
core.setOutput('token', token) | ||
core.info('Token generated successfully!') | ||
} catch (e) { | ||
core.error(e) | ||
core.setFailed(e.message) | ||
} | ||
} | ||
|
||
async function encryptSecret( | ||
octokit: ReturnType<typeof github.getOctokit>, | ||
value: string, | ||
) { | ||
// Get publick key | ||
const res = await octokit.actions.getRepoPublicKey({ ...github.context.repo }) | ||
const key = res.data.key | ||
|
||
// Convert the message and key to Uint8Array's (Buffer implements that interface) | ||
const messageBytes = Buffer.from(value) | ||
const publicKey = Buffer.from(key, 'base64') | ||
|
||
// Encrypt using LibSodium. | ||
const encryptedBytes = sodium.seal(messageBytes, publicKey) | ||
|
||
// Base64 the encrypted secret | ||
return Buffer.from(encryptedBytes).toString('base64') | ||
} | ||
|
||
async function createOrUpdateTokenInSecret( | ||
octokit: ReturnType<typeof github.getOctokit>, | ||
token: string, | ||
) { | ||
try { | ||
const name = core.getInput('SECRET_NAME') | ||
if (name) { | ||
const encryptedToken = await encryptSecret(octokit, token) | ||
core.info(`Encrypted Token: ${encryptedToken}`) | ||
return octokit.actions.createOrUpdateRepoSecret({ | ||
...github.context.repo, | ||
secret_name: name, | ||
encrypted_value: encryptedToken, | ||
}) | ||
} | ||
} catch (error) { | ||
core.error(error) | ||
core.setFailed(error) | ||
} | ||
} | ||
|
||
void run() | ||
Action.start() |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import * as core from '@actions/core' | ||
import * as github from '@actions/github' | ||
import sodium from 'tweetsodium' | ||
|
||
export namespace Util { | ||
export function getOctokit() { | ||
const token = core.getInput('GITHUB_TOKEN', { required: true }) | ||
return github.getOctokit(token) | ||
} | ||
|
||
export async function createSecret( | ||
octokit: ReturnType<typeof getOctokit>, | ||
value: string, | ||
) { | ||
// Get publick key | ||
const res = await octokit.actions.getRepoPublicKey({ | ||
...github.context.repo, | ||
}) | ||
const key = res.data.key | ||
|
||
// Convert the message and key to Uint8Array's | ||
const messageBytes = Buffer.from(value) | ||
const keyBytes = Buffer.from(key, 'base64') | ||
|
||
// Encrypt using LibSodium. | ||
const encryptedBytes = sodium.seal(messageBytes, keyBytes) | ||
|
||
return { | ||
key_id: res.data.key_id, | ||
// Base64 the encrypted secret | ||
encrypted_value: Buffer.from(encryptedBytes).toString('base64'), | ||
} | ||
} | ||
|
||
export async function createOrUpdateRepoSecret( | ||
octokit: ReturnType<typeof github.getOctokit>, | ||
name: string, | ||
value: string, | ||
) { | ||
try { | ||
const secret = await createSecret(octokit, value) | ||
return octokit.actions.createOrUpdateRepoSecret({ | ||
...github.context.repo, | ||
...secret, | ||
secret_name: name, | ||
}) | ||
} catch (error) { | ||
core.error(error) | ||
core.setFailed(error) | ||
} | ||
} | ||
} |