Skip to content

Commit de98585

Browse files
authored
Merge pull request #2082 from ccellado/release-binaries
Release bundled binaries for MacOS, Windows, Linux | x64, aarch64
2 parents 3209fa3 + 85c8824 commit de98585

File tree

3 files changed

+254
-0
lines changed

3 files changed

+254
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Publish release-binaries
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
env:
8+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
9+
10+
jobs:
11+
release-binaries:
12+
name: Publish release binaries
13+
runs-on: macos-latest
14+
env:
15+
ERGO_RELEASE_PLATFORM: macos-x64
16+
ERGO_RELEASE_TAG: ${{ github.event.release.tag_name }}
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: actions/setup-python@v4
20+
- name: Download ergo node jar
21+
run: |
22+
echo $GITHUB_REF
23+
gh release download $ERGO_RELEASE_TAG -p "ergo*"
24+
- name: Create release binary files
25+
run: python ci/release-binaries.py
26+
- name: Put binary files into release
27+
run: gh release upload $ERGO_RELEASE_TAG $(echo $(find release -name "ergo-node-*"))

ci/ergo.icns

234 KB
Binary file not shown.

ci/release-binaries.py

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
import os
2+
import tarfile
3+
import urllib.request
4+
import zipfile
5+
import shutil
6+
import logging
7+
import subprocess
8+
from multiprocessing.pool import ThreadPool
9+
from itertools import repeat
10+
11+
MICROSOFT_URL = "https://aka.ms/download-jdk/microsoft-jdk-21.0.1-"
12+
JRE_SUBFOLDER = "jdk-21.0.1+12"
13+
JDKS = {
14+
"windows-x64": "windows-x64.zip",
15+
"linux-x64": "linux-x64.tar.gz",
16+
"macos-x64": "macos-x64.tar.gz",
17+
"windows-aarch64": "windows-aarch64.zip",
18+
"linux-aarch64": "linux-aarch64.tar.gz",
19+
"macos-aarch64": "macos-aarch64.tar.gz",
20+
}
21+
22+
# Specific to ergo-node .jap, collected with jdeps
23+
JLINK_MODULES = "java.base,java.compiler,java.desktop,java.management,java.naming,java.rmi,java.sql,jdk.unsupported"
24+
25+
MAIN_JRE = os.environ.get("ERGO_RELEASE_PLATFORM")
26+
VERSION = os.environ.get("ERGO_RELEASE_TAG")
27+
28+
JAR_FILENAME = f"ergo-{VERSION}.jar"
29+
SCRIPT_LOGO = f"""
30+
31+
.-*%@#+-.
32+
.-+#@@%*=-=*%@@#+-.
33+
+@@#+- :=*@@+
34+
-@@: ......... :@@-
35+
.@@- #@@@@@@@% -@@: .@@@@@@@-:@@@@@%*. .+%@@@%+. .+%@@@%+.
36+
%@+ .*@@*. =@@. :@@:.... :@@:..+@@ =@@=. .=*= -@@=. .=@@=
37+
#@# .%@@= *@% :@@%%%%%.:@@+++%@# @@= .+++++ %@+ =@@
38+
=@@. .*@@= .@@= :@@-:::: :@@+#@@- #@# .==*@@.#@# *@%
39+
*@% =@@@*+++= %@* :@@*****::@@. =@@: .#@@*+*%@% *@@*+*%@#.
40+
#@# +#######* *@% =======..== :== .-=++-. .-=+=-.
41+
%@*. .+@@.
42+
.#@@@#+-. .-+#@@%*: Node version: {VERSION}
43+
.-+#@@@#%@@#+-.
44+
45+
46+
"""
47+
def download_jdk(url):
48+
final_url = MICROSOFT_URL + url
49+
logging.warning(f"Downloading {final_url}")
50+
urllib.request.urlretrieve(final_url, url)
51+
52+
def unarchive_jdk(filename, directory):
53+
logging.warning(f"Extracting {filename} into {directory}")
54+
if filename.endswith("tar.gz"):
55+
tar = tarfile.open(filename, "r:gz")
56+
tar.extractall(directory)
57+
tar.close()
58+
elif filename.endswith("zip"):
59+
with zipfile.ZipFile(filename, 'r') as zip_ref:
60+
zip_ref.extractall(directory)
61+
62+
def create_jre(jlink, target_jre_dir, out_jre_dir):
63+
subprocess.run([
64+
jlink,
65+
"--module-path",
66+
os.path.join(target_jre_dir, "jmods"),
67+
"--add-modules",
68+
JLINK_MODULES,
69+
"--strip-debug",
70+
"--compress", "2",
71+
"--no-header-files",
72+
"--no-man-pages",
73+
"--output",
74+
out_jre_dir
75+
], check=True)
76+
77+
def make_windows(target):
78+
app_dir = f"{target}/ergo-node"
79+
os.makedirs(app_dir, exist_ok=True)
80+
app_script = f"""
81+
Write-Host @"
82+
83+
{SCRIPT_LOGO}
84+
85+
"@ -ForegroundColor Red
86+
jre/bin/java -jar -Xmx4G {JAR_FILENAME} --mainnet -c ergo.conf
87+
"""
88+
with open(f"{app_dir}/ergo-node.ps1", "w") as f:
89+
f.write(app_script)
90+
91+
shutil.copytree(f"{target}/jre", f"{app_dir}/jre")
92+
shutil.copyfile(JAR_FILENAME, f"{app_dir}/{JAR_FILENAME}")
93+
shutil.copyfile("ergo.conf", f"{app_dir}/ergo.conf")
94+
shutil.make_archive(f"release/ergo-node-{VERSION}-{target}", 'zip', app_dir)
95+
96+
def make_linux(target):
97+
app_dir = f"{target}/ergo-node"
98+
os.makedirs(app_dir, exist_ok=True)
99+
100+
app_script = f"""#!/bin/env sh
101+
echo '\033[0;31m'
102+
cat << EOF
103+
104+
{SCRIPT_LOGO}
105+
106+
EOF
107+
echo '\033[0m'
108+
./jre/bin/java -jar -Xmx4G {JAR_FILENAME} --mainnet -c ergo.conf
109+
exit
110+
"""
111+
with open(f"{app_dir}/ergo-node.sh", "w") as f:
112+
f.write(app_script)
113+
os.chmod(f"{app_dir}/ergo-node.sh", 0o755)
114+
115+
shutil.copytree(f"{target}/jre", f"{app_dir}/jre")
116+
shutil.copyfile(JAR_FILENAME, f"{app_dir}/{JAR_FILENAME}")
117+
shutil.copyfile("ergo.conf", f"{app_dir}/ergo.conf")
118+
with tarfile.open(f"release/ergo-node-{VERSION}-{target}.tar.gz", "w:gz") as tar:
119+
tar.add(app_dir)
120+
121+
def make_macos(target):
122+
app_dir = f"{target}/ErgoNode.app"
123+
os.makedirs(app_dir, exist_ok=True)
124+
os.makedirs(f"{app_dir}/Contents/MacOS", exist_ok=True)
125+
os.makedirs(f"{app_dir}/Contents/Resources", exist_ok=True)
126+
127+
info_plist = f"""<?xml version="1.0" encoding="UTF-8"?>
128+
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
129+
<plist version="1.0">
130+
<dict>
131+
<key>CFBundleExecutable</key>
132+
<string>start.command</string>
133+
<key>CFBundleIdentifier</key>
134+
<string>org.ergoplatform.ergo-node</string>
135+
<key>CFBundleName</key>
136+
<string>Ergo Node</string>
137+
<key>CFBundleIconFile</key>
138+
<string>ergo.icns</string>
139+
<key>CFBundleVersion</key>
140+
<string>{VERSION}</string>
141+
</dict>
142+
</plist>
143+
"""
144+
with open(f"{app_dir}/Contents/info.plist", "w") as f:
145+
f.write(info_plist)
146+
147+
app_script = f"""#!/bin/zsh
148+
SRC=$(cd "$(dirname "$0")"; pwd -P)
149+
echo '\033[0;31m'
150+
cat << EOF
151+
152+
{SCRIPT_LOGO}
153+
154+
EOF
155+
echo '\033[0m'
156+
$SRC/jre/bin/java -jar -Xmx4G $SRC/{JAR_FILENAME} --mainnet -c $SRC/ergo.conf
157+
158+
exit
159+
"""
160+
app_script_file = "ergo-node.sh"
161+
with open(f"{app_dir}/Contents/MacOS/{app_script_file}", "w") as f:
162+
f.write(app_script)
163+
164+
# Require nested script for macos Terminal app to open
165+
start_command = f"""#!/bin/zsh
166+
MY_PATH=$(cd "$(dirname "$0")"; pwd -P)
167+
open -a Terminal $MY_PATH/{app_script_file}
168+
"""
169+
start_command_file = "start.command"
170+
with open(f"{app_dir}/Contents/MacOS/{start_command_file}", "w") as f:
171+
f.write(start_command)
172+
os.chmod(f"{app_dir}/Contents/MacOS/{app_script_file}", 0o755)
173+
os.chmod(f"{app_dir}/Contents/MacOS/{start_command_file}", 0o755)
174+
175+
shutil.copytree(f"{target}/jre", f"{app_dir}/Contents/MacOS/jre")
176+
shutil.copyfile(JAR_FILENAME, f"{app_dir}/Contents/MacOS/{JAR_FILENAME}")
177+
shutil.copyfile("ergo.conf", f"{app_dir}/Contents/MacOS/ergo.conf")
178+
shutil.copyfile("ci/ergo.icns", f"{app_dir}/Contents/Resources/ergo.icns")
179+
180+
with tarfile.open(f"release/ergo-node-{VERSION}-{target}.tar.gz", "w:gz") as tar:
181+
tar.add(app_dir)
182+
183+
def process_download(entry):
184+
(os_type, filename) = entry
185+
download_jdk(filename)
186+
unarchive_jdk(filename, os_type)
187+
188+
def process_jres(os_type, main_jre):
189+
logging.warning(f"Creating jre for {os_type}")
190+
if (os_type.startswith("macos")):
191+
create_jre(main_jre, os.path.join(os_type, JRE_SUBFOLDER, "Contents", "Home"), os_type + "/jre")
192+
make_macos(os_type)
193+
if (os_type.startswith("linux")):
194+
create_jre(main_jre, os.path.join(os_type, JRE_SUBFOLDER), os_type + "/jre")
195+
make_linux(os_type)
196+
if (os_type.startswith("windows")):
197+
create_jre(main_jre, os.path.join(os_type, JRE_SUBFOLDER), os_type + "/jre")
198+
make_windows(os_type)
199+
200+
def get_main_jre(jre, subfolder) -> str:
201+
if (jre.startswith("windows")):
202+
return os.path.join(jre, subfolder, "bin", "jlink.exe")
203+
elif (jre.startswith("macos")):
204+
return os.path.join(jre, subfolder, "Contents", "Home", "bin", "jlink")
205+
else: #linux
206+
return os.path.join(jre, subfolder, "bin", "jlink")
207+
208+
logging.warning(f"Starting release binaries for ergo-node")
209+
210+
main_jre = get_main_jre(MAIN_JRE, JRE_SUBFOLDER)
211+
os.makedirs("release", exist_ok=True)
212+
213+
ergo_conf = """
214+
ergo {
215+
node {
216+
mining = false
217+
}
218+
}
219+
"""
220+
with open("ergo.conf", "w") as f:
221+
f.write(ergo_conf)
222+
223+
with ThreadPool(JDKS.__len__()) as pool:
224+
pool.map(process_download, JDKS.items())
225+
226+
with ThreadPool(JDKS.__len__()) as pool:
227+
pool.starmap(process_jres, zip(JDKS.keys(), repeat(main_jre)))

0 commit comments

Comments
 (0)