.envファイルとGitHub Secretの同期

環境変数を記述した.envファイルの内容とGitHUbのSecretを同期する。

GitHub APIでSecretsを操作する

  • REST API v3 Secrets

  • 一覧取得 GET /repos/:owner/:repo/actions/secrets

  • Secret取得 GET /repos/:owner/:repo/actions/secrets/:secret_name

  • Secret更新 PUT /repos/:owner/:repo/actions/secrets/:secret_name

Name Type Description
encrypted_value string Value for your secret, encrypted with LibSodium using the public key retrieved from the Get a repository public key endpoint.
key_id string ID of the key you used to encrypt the secret.

暗号化した値を作成する必要がある。

Pythonの例は以下だが、GET /repos/:owner/:repo/actions/secrets/public-keyからpublic-keyを取得する必要がある。

1
2
3
4
5
6
7
8
9
from base64 import b64encode
from nacl import encoding, public

def encrypt(public_key: str, secret_value: str) -> str:
"""Encrypt a Unicode string using the public key."""
public_key = public.PublicKey(public_key.encode("utf-8"), encoding.Base64Encoder())
sealed_box = public.SealedBox(public_key)
encrypted = sealed_box.encrypt(secret_value.encode("utf-8"))
return b64encode(encrypted).decode("utf-8")

登録/削除

シークレットの登録~削除の流れは以下。secret_value.pyは前述のスクリプトをコマンドライン引数を受けて実行するようにしたもの。

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
PUBLIC_KEY=$(curl --silent -H "Authorization: token ${GITHUB_TOKEN}" "https://api.github.com/repos/${GITHUB_USER}/${REPO_NAME}/actions/secrets/public-key" | jq '.key')
PUBLIC_KEYID=$(curl --silent -H "Authorization: token ${GITHUB_TOKEN}" "https://api.github.com/repos/${GITHUB_USER}/${REPO_NAME}/actions/secrets/public-key" | jq '.key_id')
ENCRYPTED_VALUE=$(python secret_value.py ${PUBLIC_KEY} ${SECRET_VALUE})

$ curl -H "Authorization: token ${GITHUB_TOKEN}" -X PUT -d "{ \"encrypted_value\": \"${ENCRYPTED_VALUE}\", \"key_id\": \"${PUBLIC_KEYID}\" }" -i "https://api.github.com/repos/${GITHUB_USER}/${REPO_NAME}/actions/secrets/testkey"
HTTP/1.1 201 Created
…略…

$ curl -H "Authorization: token ${GITHUB_TOKEN}" -i "https://api.github.com/repos/${GITHUB_USER}/${REPO_NAME}/actions/secrets"
HTTP/1.1 200 OK
…略…

{
"total_count": 1,
"secrets": [
{
"name": "testkey",
"created_at": "2020-05-21T03:30:27Z",
"updated_at": "2020-05-21T03:30:27Z"
}
]
}

$ curl -H "Authorization: token ${GITHUB_TOKEN}" -i "https://api.github.com/repos/${GITHUB_USER}/${REPO_NAME}/actions/secrets/testkey"
HTTP/1.1 200 OK
…略…
{
"name": "testkey",
"created_at": "2020-05-21T03:30:27Z",
"updated_at": "2020-05-21T03:30:27Z"
}

$ curl -H "Authorization: token ${GITHUB_TOKEN}" -X DELETE -i "https://api.github.com/repos/${GITHUB_USER}/${REPO_NAME}/actions/secrets/testkey"
HTTP/1.1 204 No Content
…略…

$ curl -H "Authorization: token ${GITHUB_TOKEN}" -i "https://api.github.com/repos/${GITHUB_USER}/${REPO_NAME}/actions/secrets/testkey"
HTTP/1.1 404 Not Found
…略…
{
"message": "Not Found",
"documentation_url": "https://developer.github.com/v3/actions/secrets/#get-a-secret"
}

$ curl -H "Authorization: token ${GITHUB_TOKEN}" -i "https://api.github.com/repos/${GITHUB_USER}/${REPO_NAME}/actions/secrets"
HTTP/1.1 200 OK
…略…
{
"total_count": 0,
"secrets": [

]
}