Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions builders/binary/java_binary_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Copyright Contributors to the Mainframe Software Hub for Linux Project.
# SPDX-License-Identifier: Apache-2.0

import os
import subprocess
from monitoring.logger import Logger
from builders.plugins.plugin_interface import ArtifactBuilder

BUILD_SYSTEMS = {
"maven": {
"files": ["pom.xml"],
"command": ["mvn", "-DskipTests", "clean", "package"],
"build_dir": "target",
"docker_image": "maven:3.9-eclipse-temurin-17",
},
"gradle": {
"files": ["build.gradle", "build.gradle.kts"],
"command": ["gradle", "clean", "build", "-x", "test"],
"build_dir": os.path.join("build", "libs"),
"docker_image": "gradle:8.7-jdk17",
},
}

def detect_build_system(repo_path: str):
for system, config in BUILD_SYSTEMS.items():
for f in config["files"]:
if os.path.exists(os.path.join(repo_path, f)):
return system, config
return None, None

class JavaBinaryBuilder(ArtifactBuilder):
def __init__(self):
self.logger = Logger()

def build(self, repo_path: str, repo_gh_name: str, artifact: dict) -> str:
version = artifact.get("version", "1.0")
output_dir = os.path.join(repo_path, "build")
output_path = os.path.join(output_dir, f"{repo_gh_name}_{version}_s390x.jar")

os.makedirs(output_dir, exist_ok=True)

system, config = detect_build_system(repo_path)
if not system:
raise RuntimeError(
f"No supported Java build file found in {repo_path}. "
f"Expected one of: {', '.join(sum([v['files'] for v in BUILD_SYSTEMS.values()], []))}"
)

docker_image = artifact.get("docker_image", config["docker_image"])
cmd = config["command"]
build_dir = os.path.join(repo_path, config["build_dir"])

try:
self.logger.info(f"Building Java artifact using {system} for {repo_gh_name}")

subprocess.run(
[
"docker", "run", "--rm",
"-v", f"{repo_path}:{repo_path}",
"-v", f"{repo_path}:/app",
"-w", "/app",
docker_image,
] + cmd,
check=True
)

jars = [
os.path.join(build_dir, f)
for f in os.listdir(build_dir)
if f.endswith(".jar")
and not f.endswith("-sources.jar")
and not f.endswith("-javadoc.jar")
]

if not jars:
raise RuntimeError(f"No runnable JAR found in {build_dir}")

subprocess.run(["cp", jars[0], output_path], check=True)

self.logger.info(f"Built Java artifact at {output_path}")
return output_path

except subprocess.CalledProcessError as e:
self.logger.error(f"Failed to build Java artifact for {repo_gh_name}: {str(e)}")
raise

def publish(self, artifact_path: str, repo_gh_name: str, artifact: dict):
from lib.checksum import generate_checksum

checksum = generate_checksum(artifact_path)
version = artifact.get("version", "1.0")

self.logger.info(
f"Publishing {artifact_path} with checksum {checksum} for {repo_gh_name}"
)

try:
subprocess.run(
[
"gh", "release", "create",
f"v{version}",
"--title", f"Version {version}",
"--generate-notes",
artifact_path,
f"{artifact_path}.sha256",
],
cwd=os.path.dirname(artifact_path),
check=True
)
self.logger.info(f"Published {artifact_path} to GitHub Releases")

except subprocess.CalledProcessError as e:
self.logger.error(f"Failed to publish {artifact_path}: {str(e)}")
raise