0%

2023-01-07 使用 GitHub REST API 修改 GitHub Actions Secrets

2023-01-07 使用 GitHub REST API 修改 GitHub Actions Secrets

参考文档:https://docs.github.com/en/rest/actions/secrets

没代码没真相,直接上代码,后面再解释怎么回事。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { Octokit } from '@octokit/core'
import sodium from 'libsodium-wrappers'

// Octokit.js
// https://github.com/octokit/core.js#readme
const octokit = new Octokit({
auth: 'ghp_xxxxxxxxxxxxxxxxxx', // 替换为你的 GitHub token,参考 https://github.com/settings/tokens ,其中至少要有 repo 或 public_repo 权限才能修改 Actions Secrets
request: {
timeout: 10 * 1000, // 记得设置超时,不然会无限等待
},
})

type GetARepositoryPublicKeyRequest = {
owner: string
repo: string
}

/**
* 获取 存储库 公共密钥
文档:https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#get-a-repository-public-key
*/
async function getARepositoryPublicKey(data: GetARepositoryPublicKeyRequest) {
return (await octokit.request('GET /repos/{owner}/{repo}/actions/secrets/public-key', data)).data
}

type CreateOrUpdateARepositorySecretRequest = {
owner: string
repo: string
/**
* 要更改的 secret
*/
secret_name: string
/**
* 更改后的值
*/
secret_value: string
}
/**
* 创建或更新 Repository Secret
文档:https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#create-or-update-a-repository-secret
*/
async function createOrUpdateARepositorySecret(data: CreateOrUpdateARepositorySecretRequest) {
const { secret_value, owner, repo, ...other } = data
// Convert Secret & Base64 key to Uint8Array.
const { key, key_id } = await getARepositoryPublicKey({ owner, repo }) // 获取公钥

const binkey = sodium.from_base64(key, sodium.base64_variants.ORIGINAL)
const binsec = sodium.from_string(secret_value)

// Encrypt the secret using LibSodium
const encBytes = sodium.crypto_box_seal(binsec, binkey)

// Convert encrypted Uint8Array to Base64
const encrypted_value = sodium.to_base64(encBytes, sodium.base64_variants.ORIGINAL) // 根据公钥计算加密后的值

const newData = {
...other,
owner,
repo,
encrypted_value,
key_id,
}

return (await octokit.request('PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}', newData)).data
}

async function start() {
await createOrUpdateARepositorySecret({
owner: 'OWNER', // 你的 GitHub 用户名
repo: 'REPO', // 仓库的名称
secret_name: 'SECRET_NAME', // 要更改的 secret
secret_value: 'xxxxxxxxxxxxxx', // 这里是 secret 的原始值
})
}

start()

在更新 secret 前,需要先获取公钥,然后用公钥加密 secret,最后再 PUT

我之前搜索了一下这方面的内容,发现基本上没什么人提过这事,故特此记录一下。

本文作者:草梅友仁
本文地址: https://blog.cmyr.ltd/archives/2a25f753.html
版权声明:转载请注明出处!

坚持原创技术分享,您的支持将鼓励我继续创作!