Created
April 14, 2020 18:37
-
-
Save wshayes/9a8fa6e928c00f15da6f26b9688c7092 to your computer and use it in GitHub Desktop.
[Github Actions Secrets Mgmt] Update github secrets for all repos in a github org
This file contains hidden or 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
token: <Github Personal Access token with github actions/secrets scopes> | |
username: <github username> | |
globals: | |
- name: <secret_name> | |
value: <value> | |
description: <description> |
This file contains hidden or 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
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
import yaml | |
from typing import List | |
import httpx | |
import base64 | |
import nacl.public | |
import nacl.encoding | |
SECRETS_FN = "/Users/william/.config/github/biodati_secrets.yaml" | |
GITHUB_ROOT = "https://api.github.com" | |
ORG = "biodati" | |
with open(SECRETS_FN, "r") as f: | |
SECRETS = yaml.load(f, Loader=yaml.SafeLoader) | |
client = httpx.Client(auth=(SECRETS["username"], SECRETS["token"])) | |
def get_repos(org: str) -> List[str]: | |
"""Get repositories for org""" | |
r = client.get(f"{GITHUB_ROOT}/orgs/{org}/repos") | |
results = r.json() | |
repos = [repo["name"] for repo in results] | |
return repos | |
def get_public_key(org: str, repo: str) -> str: | |
"""Get Public key needed to encrypt secrets""" | |
r = client.get(f"{GITHUB_ROOT}/repos/{org}/{repo}/actions/secrets/public-key") | |
results = r.json() | |
return {"key": results["key"], "id": results["key_id"]} | |
def encrypt(public_key: str, secret_value: str) -> str: | |
"""Encrypt a Unicode string using the public key.""" | |
public_key = nacl.public.PublicKey(public_key.encode("utf-8"), nacl.encoding.Base64Encoder()) | |
sealed_box = nacl.public.SealedBox(public_key) | |
encrypted = sealed_box.encrypt(secret_value.encode("utf-8")) | |
return base64.b64encode(encrypted).decode("utf-8") | |
def update_globals(org): | |
repos = get_repos(org) | |
public_keys = {} | |
for repo in repos: | |
public_keys[repo] = get_public_key(org, repo) | |
for repo in repos: | |
public_key = public_keys[repo]["key"] | |
public_key_id = public_keys[repo]["id"] | |
for secret in SECRETS["globals"]: | |
name = secret["name"] | |
encrypted = encrypt(public_key, secret["value"]) | |
payload = {"encrypted_value": encrypted, "key_id": public_key_id} | |
r = client.put(f"{GITHUB_ROOT}/repos/{org}/{repo}/actions/secrets/{name}", json=payload) | |
print(f"Status: {r.status_code} Repo: {repo} Name: {name}") | |
if r.status_code != 200: | |
print(r.text) | |
def main(): | |
update_globals(ORG) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment