python/hooks/post_gen_project.py
2023-05-24 12:33:11 +02:00

189 lines
6.1 KiB
Python

import subprocess
import http.client
import json
import os
from base64 import b64encode
REMOVE_PATHS = [
{% if cookiecutter.open_source_license == "Proprietary" %} "LICENSE", {% endif %}
{% if cookiecutter.configure_ci == "False" %} ".woodpecker.yml", {% endif %}
]
for path in REMOVE_PATHS:
if path and os.path.exists(path):
if os.path.isdir(path):
os.rmdir(path)
else:
os.unlink(path)
subprocess.call(["poetry", "lock"])
subprocess.call(["git", "init"])
subprocess.call(["git", "checkout", "-b", "main"])
subprocess.call(["git", "add", "*"])
subprocess.call(["git", "commit", "-m", "Initial commit"])
subprocess.call(["git", "config", "user.name", "{{ cookiecutter.git_user }}"])
subprocess.call(["git", "config", "user.email", "{{ cookiecutter.email }}"])
# subprocess.call(["python", "-m", "venv", "venv"])
def get_secret(secret_name: str):
try:
import secretstorage
connection = secretstorage.dbus_init()
collection = secretstorage.get_default_collection(connection)
collection.unlock()
secret = collection.search_items({"Title": secret_name}).__next__()
secret.unlock()
return secret.get_secret().decode("utf-8")
except (ModuleNotFoundError, StopIteration):
import getpass
return getpass.getpass(
f"Secret service or secret {'Title': 'secret_name'} not available,"
"please enter you gitea api token:"
)
def get_new_gitea_token(
connection: http.client.HTTPSConnection, new_token_name: str, user: str, token: str
) -> str:
auth = b64encode(f"{user}:{token}".encode("utf-8")).decode("ascii")
connection.request(
"POST",
f"/api/v1/users/{user}/tokens",
json.dumps(
{
"name": new_token_name,
}
),
{
"Authorization": f"Basic {auth}",
"content-type": "application/json",
},
)
response = connection.getresponse()
status = response.status
if status != 201:
print(
f"\033[38;2;255;0;0mInvalid response from gitea while creating a new token: {status} ({response.reason})\033[0m"
)
print(response.read())
exit(1)
data = json.load(response)
return data["sha1"]
def push_woodpecker_secret(
connection: http.client.HTTPSConnection,
repo: str,
secret_name: str,
secret: str,
woodpecker_token: str,
images: list[str] | None = None
):
if images is None: images = []
connection.request(
"POST",
f"/api/repos/{repo}/secrets",
json.dumps(
{
"name": secret_name,
"value": secret,
"image": images,
"event": ["push", "tag"],
}
),
{
"Authorization": f"Bearer {woodpecker_token}",
"content-type": "application/json",
},
)
response = connection.getresponse()
status = response.status
if status != 200:
print(
f"\033[38;2;255;0;0mInvalid response from woodpecker when sending a new secret: {status} ({response.reason})\033[0m"
)
print(response.read())
exit(1)
response.read()
if {{cookiecutter.generate_gitea_project}}:
try:
import giteapy
except ModuleNotFoundError:
print("module `giteapy` is not availabled, repository not created")
exit()
GITEA_API_KEY = get_secret("Gitea Token")
configuration = giteapy.Configuration()
configuration.api_key["access_token"] = GITEA_API_KEY
client = giteapy.ApiClient(configuration)
client.configuration.host = "{{ cookiecutter.gitea_url }}/api/v1"
api_instance = giteapy.UserApi(client)
repo = giteapy.CreateRepoOption(
name="{{ cookiecutter.project_slug }}", private=True
)
api_instance.create_current_user_repo(body=repo)
if {{cookiecutter.generate_gitea_project}} and {{cookiecutter.configure_ci}}:
api_instance = giteapy.RepositoryApi(client)
options = giteapy.AddCollaboratorOption("read")
api_instance.repo_add_collaborator(
"{{ cookiecutter.git_user }}",
"{{ cookiecutter.project_slug }}",
"{{ cookiecutter.woodpecker_gitea_user }}",
body=options,
)
connection_gitea = http.client.HTTPSConnection("git.pains-perdus.fr")
GITEA_API_KEY = get_new_gitea_token(connection_gitea, "CI {{ cookiecutter.git_user }}/{{ cookiecutter.project_slug }}", "{{ cookiecutter.git_user }}", GITEA_API_KEY)
WOODPECKER_API_KEY = get_secret("Woodpecker Token")
WOODPECKER_SERVER = "{{ cookiecutter.woodpecker_server }}".removeprefix("https://")
origin = "{{ cookiecutter.git_origin }}"
repo = "/".join(origin.removesuffix(".git").split(":")[-1].split("/")[-2:])
connection = http.client.HTTPSConnection(WOODPECKER_SERVER)
connection.request(
"GET",
"/api/user/repos?all=true&flush=true",
headers={"Authorization": f"Bearer {WOODPECKER_API_KEY}"},
)
response = connection.getresponse()
status = response.status
response.read()
if status != 200:
print(
f"\033[38;2;255;0;0mInvalid response from woodpecker while loading repos: {status} ({response.reason})\033[0m"
)
exit(1)
connection.request(
"POST",
f"/api/repos/{repo}",
headers={
"Authorization": f"Bearer {WOODPECKER_API_KEY}",
"referer": f"https://{WOODPECKER_SERVER}/repo/add",
},
)
response = connection.getresponse()
status = response.status
if status != 200:
print(
f"\033[38;2;255;0;0mInvalid response from woodpecker while linking repo: {status} ({response.reason})\033[0m"
)
print(response.read())
exit(1)
response.read()
push_woodpecker_secret(
connection,
repo,
"gitea_token",
GITEA_API_KEY,
WOODPECKER_API_KEY
)
if {{cookiecutter.generate_gitea_project}}:
subprocess.call(["git", "remote", "add", "origin", "{{ cookiecutter.git_origin }}"])
subprocess.call(["git", "push", "-u", "origin", "main"])