Skip to content

Commit

Permalink
fix: 🐛 set secret
Browse files Browse the repository at this point in the history
  • Loading branch information
bubkoo committed Sep 25, 2020
1 parent 18164f9 commit a560364
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 73 deletions.
38 changes: 38 additions & 0 deletions src/action.ts
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)
}
}
}
75 changes: 2 additions & 73 deletions src/index.ts
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()
52 changes: 52 additions & 0 deletions src/util.ts
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)
}
}
}

0 comments on commit a560364

Please sign in to comment.