-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgit_handler.py
More file actions
108 lines (90 loc) · 3.52 KB
/
Copy pathgit_handler.py
File metadata and controls
108 lines (90 loc) · 3.52 KB
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
from git import Repo, GitCommandError
import os
from github import Auth, GithubIntegration
import traceback
def tag_exists(repo, tag_name):
"""Check if a tag already exists in the repository."""
return tag_name in [tag.name for tag in repo.tags]
repos = {
"data-8": [
"materials-fds-private",
"materials-fds",
"materials-fds-colab",
"materials-fds-binder",
"materials-fds-jupyterlite",
"materials-fds-no-footprint",
"materials-fds-colab-no-footprint",
"materials-fds-binder-no-footprint",
"materials-fds-jupyterlite-no-footprint"
],
"ds-modules": [
"materials-fds-assets"
]
}
PR_COMMIT_MESSAGE = "Otter 6.1.3 Configured"
TAG_NAME = 'otter-6.1.3'
TAG_MESSAGE = 'otter-6.1.3'
ROOT_PATH = os.path.dirname(os.getcwd())
# --- GitHub App auth (per org): no personal PAT and no fork ---
_KEY_DIR = os.path.dirname(os.path.abspath(__file__))
APP_CONFIG = {
"ds-modules": {
"app_id": 4288757,
"private_key_path": os.path.join(_KEY_DIR, "ds-modules-app-private-key.pem"),
},
"data-8": {
"app_id": 4289218,
"private_key_path": os.path.join(_KEY_DIR, "data-8-app-private-key.pem"),
},
}
def get_app_installation_token(org):
"""Mint a short-lived (~1h) installation token for `org` via its GitHub App."""
cfg = APP_CONFIG[org]
with open(cfg["private_key_path"]) as f:
private_key = f.read()
gi = GithubIntegration(auth=Auth.AppAuth(cfg["app_id"], private_key))
installation = gi.get_org_installation(org)
return gi.get_access_token(installation.id).token
def handle_repo_app(org, r, commit_msg):
"""Publish `r` to `org` using the GitHub App.
Commits locally and pushes generated content straight to the org repo's
`main` branch with an installation token. No personal fork and no PR, since
an org-owned App cannot push to a user's fork.
"""
repo_path = f"{ROOT_PATH}/{r}"
print(f"{r} - start (app) =========")
try:
token = get_app_installation_token(org)
push_url = f"https://x-access-token:{token}@github.com/{org}/{r}.git"
local_repo = Repo(repo_path)
if local_repo.bare:
print(f"Local Repository at {repo_path} is bare.")
return
local_repo.git.add(A=True)
if local_repo.is_dirty():
local_repo.index.commit(commit_msg)
# Push generated content straight to the org repo's main branch.
local_repo.git.push(push_url, "HEAD:main", "--force")
# Refresh the release tag on the org repo.
try:
local_repo.git.push(push_url, f":refs/tags/{TAG_NAME}")
except GitCommandError:
pass # remote tag didn't exist yet
if tag_exists(local_repo, TAG_NAME):
local_repo.delete_tag(local_repo.tags[TAG_NAME])
local_repo.create_tag(TAG_NAME, message=TAG_MESSAGE)
local_repo.git.push(push_url, f"refs/tags/{TAG_NAME}")
except GitCommandError as e:
print(f"Git error handling repo: {e}")
except Exception as e:
print(traceback.format_exc())
print(f"Unexpected error: {e}")
print(f"{r} - done (app) =========")
def main(repo):
for org, list_repos in repos.items():
for r in list_repos:
if not repo or r == repo:
handle_repo_app(org, r, PR_COMMIT_MESSAGE)
if __name__ == "__main__":
main(None) # Pass None to handle all repositories
print("Changes pulled, committed, and pushed successfully.")