Skip to content

Commit 67fe13f

Browse files
[CLOUDP-350567] Automate PR creation to release helm chart using gh helm repo (#514)
# Summary Per current process when we try to release a version of the helm chart we create a PR to the `mongodb/helm-charts` repo. Since this is manual task, it's time consuming and error prone. This PR tries to automate that manual task. ## Proof of Work The successful run [here](https://spruce.mongodb.com/task/mongodb_kubernetes_create_chart_release_pr_create_chart_release_pr_patch_41049c8e970234d39de24bbfffeb6ac99e5c254f_68e8d76ce4a3ad00073c1ed3_25_10_10_09_52_45/logs?execution=0) created [the PR](mongodb/helm-charts#516) on helm chart repo successfully. ``` [2025/10/10 11:56:53.577] INFO 2025-10-10 09:56:53,577 [create_chart_release_pr] Command succeeded [2025/10/10 11:56:53.577] INFO 2025-10-10 09:56:53,577 [create_chart_release_pr] Running command: git push -u origin mck-release-x.y.z in directory /data/mci/7faac8b315a48c50db2b095e7185d1ea/tmp/tmp0nfkyg_w/helm-charts [2025/10/10 11:56:54.444] INFO 2025-10-10 09:56:54,443 [create_chart_release_pr] Command succeeded [2025/10/10 11:56:54.444] INFO 2025-10-10 09:56:54,444 [create_chart_release_pr] Creating the pull request in the helm-charts repo. [2025/10/10 11:56:55.762] INFO 2025-10-10 09:56:55,762 [create_chart_release_pr] Successfully created Pull Request mongodb/helm-charts#516 [2025/10/10 11:56:55.801] Finished command 'subprocess.exec' in function 'create_chart_release_pr' (step 3.2 of 3) in 2.73136881s. ``` ## Checklist - [x] Have you linked a jira ticket and/or is the ticket in the title? - [x] Have you checked whether your jira ticket required DOCSP changes? - [x] Have you added changelog file? - use `skip-changelog` label if not needed - refer to [Changelog files and Release Notes](https://github.com/mongodb/mongodb-kubernetes/blob/master/CONTRIBUTING.md#changelog-files-and-release-notes) section in CONTRIBUTING.md for more details
1 parent e26dc91 commit 67fe13f

File tree

4 files changed

+157
-0
lines changed

4 files changed

+157
-0
lines changed

.evergreen-functions.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,23 @@ functions:
850850
unzip -u macos-notary.zip
851851
chmod 755 ./linux_amd64/macnotary
852852
853+
create_chart_release_pr:
854+
- command: github.generate_token
855+
params:
856+
repo: helm-charts
857+
expansion_name: GH_TOKEN
858+
- command: subprocess.exec
859+
type: setup
860+
params:
861+
working_dir: src/github.com/mongodb/mongodb-kubernetes
862+
include_expansions_in_env:
863+
- GH_TOKEN
864+
- workdir
865+
- OPERATOR_VERSION
866+
env:
867+
GH_TOKEN: ${GH_TOKEN}
868+
binary: scripts/dev/run_python.sh scripts/release/create_chart_release_pr.py --chart_version ${OPERATOR_VERSION|*triggered_by_git_tag}
869+
853870
release_kubectl_mongodb_plugin:
854871
- command: github.generate_token
855872
params:

.evergreen-release.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,13 @@ tasks:
122122
- func: install_goreleaser
123123
- func: install_macos_notarization_service
124124
- func: release_kubectl_mongodb_plugin
125+
126+
- name: create_chart_release_pr
127+
tags: [ "helm_chart_release_pr" ]
128+
commands:
129+
- func: clone
130+
- func: python_venv
131+
- func: create_chart_release_pr
125132

126133
### Release build variants
127134
buildvariants:
@@ -239,3 +246,12 @@ buildvariants:
239246
allowed_requesters: [ "patch", "github_tag" ]
240247
tasks:
241248
- name: release_kubectl_mongodb_plugin
249+
250+
- name: create_chart_release_pr
251+
display_name: create_chart_release_pr
252+
tags: [ "release" ]
253+
run_on:
254+
- release-ubuntu2404-small # This is required for CISA attestation https://jira.mongodb.org/browse/DEVPROD-17780
255+
allowed_requesters: [ "patch", "github_tag" ]
256+
tasks:
257+
- name: create_chart_release_pr

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ python-frontmatter==1.1.0
3737
python-on-whales==0.78.0
3838
yamale==6.0.0
3939
yamllint==1.37.1
40+
PyGithub==2.7.0
4041

4142
# from kubeobject
4243
freezegun==1.5.5
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import argparse
2+
import os
3+
import shutil
4+
import subprocess
5+
import sys
6+
import tempfile
7+
from pathlib import Path
8+
from typing import List, Optional
9+
10+
from github import Github, GithubException
11+
12+
from lib.base_logger import logger
13+
14+
REPO_URL = "https://github.com/mongodb/helm-charts.git"
15+
REPO_NAME = "mongodb/helm-charts"
16+
TARGET_CHART_SUBDIR = "charts/mongodb-kubernetes"
17+
BASE_BRANCH = "main"
18+
19+
20+
# run_command runs the command `command` from dir cwd
21+
def run_command(command: List[str], cwd: Optional[str] = None):
22+
logger.debug(f"Running command: {' '.join(command)} in directory {cwd}")
23+
result = subprocess.run(command, capture_output=True, text=True, cwd=cwd)
24+
if result.returncode != 0:
25+
raise RuntimeError(f"Command {' '.join(command)} failed. Stdout: {result.stdout}, stderr: {result.stderr}")
26+
logger.debug("Command succeeded")
27+
return result.stdout
28+
29+
30+
# create_pull_request creates the pull request to the helm-charts repo
31+
def create_pull_request(branch_name, chart_version, github_token):
32+
logger.info("Creating the pull request in the helm-charts repo.")
33+
34+
try:
35+
g = Github(github_token)
36+
repo = g.get_repo(REPO_NAME)
37+
pr_title = f"Release MCK {chart_version}"
38+
body = f"This PR publishes the MCK chart version {chart_version}."
39+
40+
pr = repo.create_pull(
41+
title=pr_title,
42+
body=body,
43+
head=branch_name,
44+
base=BASE_BRANCH,
45+
)
46+
logger.info(f"Successfully created Pull Request {pr.html_url}")
47+
except Exception as e:
48+
pr_url = f"https://github.com/{REPO_NAME}/pull/new/{branch_name}"
49+
raise Exception(
50+
f"An unexpected error occurred while creating the PR: {e}. Please create the PR manually by following this link {pr_url}"
51+
)
52+
53+
54+
def commit_and_push_chart(chart_version):
55+
branch_name = f"mck-release-{chart_version}"
56+
57+
mck_dir = Path(".").resolve()
58+
# source_chart_path is local helm chart in MCK repo
59+
source_chart_path = os.path.join(mck_dir, "helm_chart")
60+
61+
if not os.path.isdir(source_chart_path):
62+
raise Exception(f"The source chart path '{source_chart_path}' is not a valid directory.")
63+
64+
github_token = os.environ.get("GH_TOKEN")
65+
if not github_token:
66+
raise Exception("github token not found, git push will fail.")
67+
68+
with tempfile.TemporaryDirectory() as temp_dir:
69+
helm_repo_path = os.path.join(temp_dir, "helm-charts")
70+
logger.debug(f"Working in a temporary directory: {temp_dir}")
71+
72+
try:
73+
run_command(["git", "clone", REPO_URL, helm_repo_path])
74+
run_command(["git", "checkout", "-b", branch_name], cwd=helm_repo_path)
75+
76+
target_dir = os.path.join(helm_repo_path, TARGET_CHART_SUBDIR)
77+
logger.debug(f"Clearing content from dir '{target_dir}'")
78+
if os.path.exists(target_dir):
79+
for item in os.listdir(target_dir):
80+
item_path = os.path.join(target_dir, item)
81+
if os.path.isdir(item_path):
82+
shutil.rmtree(item_path)
83+
else:
84+
os.remove(item_path)
85+
86+
logger.debug(f"Copying local MCK chart from '{source_chart_path}' to helm repo chart path {target_dir}")
87+
shutil.copytree(source_chart_path, target_dir, dirs_exist_ok=True)
88+
89+
commit_message = f"Release MCK {chart_version}"
90+
run_command(["git", "add", "."], cwd=helm_repo_path)
91+
run_command(["git", "commit", "-m", commit_message], cwd=helm_repo_path)
92+
93+
logger.debug("Configuring remote URL for authenticated push...")
94+
# Constructs a URL like https://x-access-token:YOUR_TOKEN@github.com/owner/repo.git
95+
authenticated_url = f"https://x-access-token:{github_token}@{REPO_URL.split('//')[1]}"
96+
run_command(["git", "remote", "set-url", "origin", authenticated_url], cwd=helm_repo_path)
97+
run_command(["git", "push", "-u", "origin", branch_name], cwd=helm_repo_path)
98+
99+
create_pull_request(branch_name, chart_version, github_token)
100+
101+
except Exception as e:
102+
raise Exception(f"An error occurred while performing git commit and push, error: {e}")
103+
104+
105+
def main():
106+
parser = argparse.ArgumentParser(
107+
description="Automate PR creation to release MCK helm chart to github helm chart repo."
108+
)
109+
parser.add_argument(
110+
"--chart_version", help="The version of the chart to be released (e.g., '1.3.0').", required=True
111+
)
112+
args = parser.parse_args()
113+
114+
chart_version = args.chart_version
115+
try:
116+
commit_and_push_chart(chart_version)
117+
except Exception as e:
118+
logger.error(f"Failed releasing helm chart, error: {e}")
119+
raise e
120+
121+
122+
if __name__ == "__main__":
123+
sys.exit(main())

0 commit comments

Comments
 (0)