Skip to content

Commit 2d18b52

Browse files
[CLOUDP-361632] Add functionality to upload release info to GitHub release assets (#624)
1 parent 5312080 commit 2d18b52

File tree

9 files changed

+665
-128
lines changed

9 files changed

+665
-128
lines changed

.evergreen-functions.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,20 @@ functions:
778778
GH_TOKEN: ${GH_TOKEN}
779779
binary: scripts/dev/run_python.sh scripts/release/create_chart_release_pr.py --chart_version ${OPERATOR_VERSION|*triggered_by_git_tag}
780780

781+
add_releaseinfo_to_github_assets:
782+
- command: github.generate_token
783+
params:
784+
expansion_name: GH_TOKEN
785+
- command: subprocess.exec
786+
type: setup
787+
params:
788+
working_dir: src/github.com/mongodb/mongodb-kubernetes
789+
include_expansions_in_env:
790+
- OPERATOR_VERSION
791+
env:
792+
GH_TOKEN: ${GH_TOKEN}
793+
binary: scripts/dev/run_python.sh scripts/release/release_info.py --version ${OPERATOR_VERSION|*triggered_by_git_tag}
794+
781795
release_kubectl_mongodb_plugin:
782796
- command: github.generate_token
783797
params:

.evergreen-release.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ tasks:
115115
- func: install_macos_notarization_service
116116
- func: release_kubectl_mongodb_plugin
117117

118+
- name: add_releaseinfo_to_github_assets
119+
commands:
120+
- func: clone
121+
- func: python_venv
122+
- func: add_releaseinfo_to_github_assets
123+
118124
- name: create_chart_release_pr
119125
tags: [ "helm_chart_release_pr" ]
120126
commands:
@@ -151,6 +157,18 @@ buildvariants:
151157
- name: release_readiness_probe
152158
- name: release_version_upgrade_hook
153159

160+
- name: add_releaseinfo_to_github_assets
161+
display_name: add_releaseinfo_to_github_assets
162+
tags: ["release"]
163+
run_on:
164+
- ubuntu2404-small
165+
allowed_requesters: ["patch", "github_tag"]
166+
depends_on:
167+
- name: "*"
168+
variant: release_images
169+
tasks:
170+
- name: add_releaseinfo_to_github_assets
171+
154172
- name: preflight_release_images
155173
display_name: preflight_release_images
156174
tags: [ "release" ]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
kind: other
3+
date: 2025-12-09
4+
---
5+
6+
* Future releases will include a new asset, release_info_<version>.json, which provides detailed information about each MongoDB Controllers for Kubernetes release, including a clear list of all container images. This will help customers, especially those running in air-gapped environments, easily identify all required images for a given release.

scripts/release/build/image_build_process.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import base64
22
import subprocess
3-
from typing import Dict
3+
from typing import Dict, Optional
44

55
import boto3
66
import docker
@@ -22,6 +22,12 @@ def build_image(self, tags: list[str],
2222
args: Dict[str, str],
2323
platforms: list[str]): pass
2424

25+
# check_if_image_exists could easily be used to get the digest of manfiest list but
26+
# the python package that we use somehow doesn't return the digest of manifest list
27+
# even though the respective docker CLI returns the digest. That's why we had to introduce
28+
# this function.
29+
def get_manfiest_list_digest(self, image: str) -> Optional[str]: pass
30+
2531

2632
DEFAULT_BUILDER_NAME = "multiarch" # Default buildx builder name
2733

@@ -109,6 +115,26 @@ def check_if_image_exists(self, image_tag: str) -> bool:
109115
else:
110116
return True
111117

118+
def get_manfiest_list_digest(self, image) -> Optional[str]:
119+
SKOPEO_IMAGE = "quay.io/skopeo/stable"
120+
121+
skopeo_inspect_command = ["inspect", f"docker://{image}", "--format", "{{.Digest}}"]
122+
docker_run_skopeo = ["docker", "run", "--rm", SKOPEO_IMAGE]
123+
docker_run_skopeo.extend(skopeo_inspect_command)
124+
125+
try:
126+
result = subprocess.run(
127+
docker_run_skopeo,
128+
capture_output=True,
129+
text=True,
130+
check=True
131+
)
132+
return result.stdout.strip()
133+
except subprocess.CalledProcessError as e:
134+
raise Exception(f"Failed to run skopeo inspect using 'docker run' for image {image}. Error: {e.stderr.strip()}") from e
135+
except FileNotFoundError:
136+
raise Exception("docker is not installed on the system.")
137+
112138
def build_image(self, tags: list[str],
113139
dockerfile: str,
114140
path: str,
@@ -167,6 +193,9 @@ def check_if_image_exists(self, image_tag: str) -> bool:
167193
f"PodmanImageBuilder does not support checking if image exists remotely. Skipping check for {image_tag}.")
168194
return False
169195

196+
def get_manfiest_list_digest(self, image) -> Optional[str]:
197+
raise Exception("PodmanImageBuilder does not support getting digest for manifest list, use docker image builder instead.")
198+
170199
def build_image(self, tags: list[str],
171200
dockerfile: str,
172201
path: str,

scripts/release/kubectl_mongodb/promote_kubectl_plugin.py

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from pathlib import Path
77

88
from botocore.exceptions import ClientError
9-
from github import Github, GithubException
109

1110
from lib.base_logger import logger
1211
from scripts.release.build.build_info import (
@@ -19,16 +18,14 @@
1918
)
2019
from scripts.release.kubectl_mongodb.utils import (
2120
CHECKSUMS_PATH,
22-
GITHUB_REPO,
2321
LOCAL_ARTIFACTS_DIR,
2422
create_s3_client,
2523
kubectl_plugin_name,
2624
parse_platform,
2725
s3_path,
26+
upload_assets_to_github_release,
2827
)
2928

30-
GITHUB_TOKEN = os.environ.get("GH_TOKEN")
31-
3229

3330
def main():
3431
release_version = os.environ.get("OPERATOR_VERSION")
@@ -270,49 +267,5 @@ def create_tarballs():
270267
return created_archives
271268

272269

273-
# upload_assets_to_github_release uploads the release artifacts (downloaded notarized/signed staging artifacts) to
274-
# the GitHub release as assets.
275-
def upload_assets_to_github_release(asset_paths: list[str], release_version: str):
276-
if not GITHUB_TOKEN:
277-
logger.info("ERROR: GITHUB_TOKEN environment variable not set.")
278-
sys.exit(1)
279-
280-
try:
281-
g = Github(GITHUB_TOKEN)
282-
repo = g.get_repo(GITHUB_REPO)
283-
except GithubException as e:
284-
logger.info(f"ERROR: Could not connect to GitHub or find repository '{GITHUB_REPO}', Error {e}.")
285-
sys.exit(1)
286-
287-
try:
288-
gh_release = None
289-
# list all the releases (including draft ones), and get the one corresponding to the passed release_version
290-
for r in repo.get_releases():
291-
if r.tag_name == release_version:
292-
gh_release = r
293-
break
294-
295-
if gh_release is None:
296-
logger.error(
297-
f"Could not find release (published or draft) with tag '{release_version}'. Please ensure the release exists."
298-
)
299-
sys.exit(2)
300-
except GithubException as e:
301-
logger.debug(f"Failed to retrieve releases from the repository {GITHUB_REPO}. Error: {e}")
302-
sys.exit(2)
303-
304-
for asset_path in asset_paths:
305-
asset_name = os.path.basename(asset_path)
306-
logger.info(f"Uploading artifact '{asset_name}' to github release as asset")
307-
try:
308-
gh_release.upload_asset(path=asset_path, name=asset_name, content_type="application/gzip")
309-
except GithubException as e:
310-
logger.debug(f"ERROR: Failed to upload asset {asset_name}. Error: {e}")
311-
sys.exit(2)
312-
except Exception as e:
313-
logger.debug(f"An unexpected error occurred during upload of {asset_name}: {e}")
314-
sys.exit(2)
315-
316-
317270
if __name__ == "__main__":
318271
main()

scripts/release/kubectl_mongodb/utils.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1+
import os
2+
import sys
3+
14
import boto3
25
from botocore.exceptions import NoCredentialsError, PartialCredentialsError
6+
from github import Github, GithubException
37

8+
from lib.base_logger import logger
49
from scripts.release.build.build_info import KUBECTL_PLUGIN_BINARY
510

611
AWS_REGION = "eu-north-1"
712

813
GITHUB_REPO = "mongodb/mongodb-kubernetes"
14+
GITHUB_TOKEN = os.environ.get("GH_TOKEN")
915

1016
LOCAL_ARTIFACTS_DIR = "artifacts"
1117
CHECKSUMS_PATH = f"{LOCAL_ARTIFACTS_DIR}/checksums.txt"
@@ -34,3 +40,41 @@ def kubectl_plugin_name(os_name: str, arch_name: str) -> str:
3440
# The `version` string has the correct version (either patch id or commit sha), based on the BuildScenario.
3541
def s3_path(filename: str, version: str) -> str:
3642
return f"{KUBECTL_PLUGIN_BINARY}/{version}/{filename}"
43+
44+
45+
# upload_assets_to_github_release uploads the release artifacts (downloaded notarized/signed staging artifacts) to
46+
# the GitHub release as assets.
47+
def upload_assets_to_github_release(asset_paths: list[str], release_version: str):
48+
if not GITHUB_TOKEN:
49+
raise Exception("ERROR: GITHUB_TOKEN environment variable not set.")
50+
51+
try:
52+
g = Github(GITHUB_TOKEN)
53+
repo = g.get_repo(GITHUB_REPO)
54+
except GithubException as e:
55+
raise Exception(f"ERROR: Could not connect to GitHub or find repository {GITHUB_REPO}") from e
56+
57+
try:
58+
gh_release = None
59+
# list all the releases (including draft ones), and get the one corresponding to the passed release_version
60+
for r in repo.get_releases():
61+
if r.tag_name == release_version:
62+
gh_release = r
63+
break
64+
65+
if gh_release is None:
66+
raise Exception(
67+
f"Could not find release (published or draft) with tag '{release_version}'. Please ensure the release exists."
68+
)
69+
except GithubException as e:
70+
raise Exception(f"Failed to retrieve releases from the repository {GITHUB_REPO}") from e
71+
72+
for asset_path in asset_paths:
73+
asset_name = os.path.basename(asset_path)
74+
logger.info(f"Uploading artifact '{asset_name}' to github release as asset")
75+
try:
76+
gh_release.upload_asset(path=asset_path, name=asset_name, content_type="application/gzip")
77+
except GithubException as e:
78+
raise Exception(f"ERROR: Failed to upload asset {asset_name}") from e
79+
except Exception as e:
80+
raise Exception(f"An unexpected error occurred during upload of {asset_name}") from e

0 commit comments

Comments
 (0)