Skip to content

Commit 066b4fa

Browse files
authored
Merge pull request #140 from V-Sekai/justfile
Elixir build script to export releases.
2 parents e10fc50 + 2811b3f commit 066b4fa

30 files changed

+1804
-450
lines changed

.github/workflows/release.yaml

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*.*.*'
7+
branches:
8+
- main
9+
- master
10+
pull_request:
11+
12+
jobs:
13+
build:
14+
runs-on: windows-latest
15+
16+
steps:
17+
- name: Checkout repository
18+
uses: actions/checkout@v4
19+
20+
- name: Install unzip
21+
run: choco install unzip
22+
23+
- name: Set up Elixir
24+
uses: erlef/setup-beam@v1
25+
with:
26+
elixir-version: '1.12'
27+
otp-version: '24.0'
28+
29+
- name: Run build script
30+
run: |
31+
elixir --sname build -r buildscript.iex -e "BuildScript.all"
32+
33+
- name: Archive artifacts
34+
uses: actions/upload-artifact@v4
35+
with:
36+
name: build-artifacts
37+
path: export/export_*

.gitignore

+12
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,15 @@ data_*/
1414
.DS_Store
1515

1616
export/
17+
18+
addons/vsk_version/build_constants.gd.uid
19+
20+
addons/vsk_version/build_constants.gd
21+
22+
addons/vsk_version/vsk_version.gd.uid
23+
24+
commandlinetools-linux-8092744_latest.zip
25+
26+
jdk/
27+
28+
cmdline-tools/
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://bjpqewbtgif6n

addons/GPUTrail-main/plugin.gd.uid

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://dtvbu6i7jdfpp
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://nqhuvjyl5bf4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://b35htbko4hv85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://bhvqwircniboq
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://dioc7tw6snepa
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://b7vj4bp81hjsh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://18xcph2o0pci
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://bhgqer41udrla
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://c6ouln8g13834
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://cubfh2dm1g350
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://dheiq8csvlle8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://c46ssct7fj6pj
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://b2cjphncghsi8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://dl6f33628oxnt
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://beag45eu5igqb
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://bcc178k783hmw
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://cqeyvdcoi37qr
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://c351cyh3u2n31

addons/vsk_version/build_constants.gd

-10
This file was deleted.

addons/vsk_version/vsk_version.gd

+19-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,24 @@
66
@tool
77
extends Node
88

9-
const build_constants_const = preload("build_constants.gd")
9+
var build_constants = null
1010

11+
func _ready():
12+
if ResourceLoader.exists("build_constants.gd"):
13+
build_constants = preload("build_constants.gd")
14+
else:
15+
print("build_constants.gd does not exist")
1116

12-
static func get_build_label() -> String:
13-
return build_constants_const.BUILD_DATE_STR + "\n" + build_constants_const.BUILD_LABEL
17+
func get_build_label() -> String:
18+
var build_label = "DEVELOPER_BUILD"
19+
var build_date_str = "Build Date"
20+
var build_unix_time = -1
21+
22+
if build_constants and build_constants.has("BUILD_LABEL"):
23+
build_label = build_constants.BUILD_LABEL
24+
if build_constants and build_constants.has("BUILD_DATE_STR"):
25+
build_date_str = build_constants.BUILD_DATE_STR
26+
if build_constants and build_constants.has("BUILD_UNIX_TIME"):
27+
build_unix_time = build_constants.BUILD_UNIX_TIME
28+
29+
return build_date_str + "\n" + build_label

buildscript.iex

+255
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
defmodule BuildScript do
2+
@url "https://github.com/V-Sekai/world-editor/releases/download/latest.v-sekai-editor-187/v-sekai-world.zip"
3+
@output "v-sekai-world.zip"
4+
@extract_dir "export"
5+
@extract_dir_extracted "#{@extract_dir}/temp"
6+
@os_family :os.type()
7+
@project_name "xr_grid"
8+
@expected_hash "F7AB549A676C52DD47F9D74C9308EBBE447ABFA1513C7E563B3C15809C0CE3E3"
9+
10+
def all do
11+
pending_files_to_delete = editor_download()
12+
editor_sign()
13+
export_stage()
14+
cleanup_pending_files(pending_files_to_delete)
15+
end
16+
def editor_download do
17+
case verify_hash() do
18+
{:ok, _hash, _message} ->
19+
IO.puts("File hash matches, skipping download.")
20+
{:error, _hash, _message} ->
21+
download()
22+
case verify_hash() do
23+
{:ok, _hash, _message} ->
24+
IO.puts("Download complete and hash verified.")
25+
{:error, _hash, _message} ->
26+
IO.puts("Hash verification failed after download.")
27+
exit(:normal)
28+
end
29+
end
30+
pending_files_to_delete = extract()
31+
create_gdignore()
32+
pending_files_to_delete
33+
end
34+
35+
defp cleanup_pending_files(files) do
36+
IO.inspect(files, label: "Pending files to delete")
37+
end
38+
39+
def editor_sign do
40+
make_executable()
41+
sign_app()
42+
end
43+
44+
def download do
45+
File.mkdir_p!(@extract_dir)
46+
System.cmd("curl", ["-L", @url, "-o", "#{@extract_dir}/#{@output}"])
47+
end
48+
49+
def verify_hash do
50+
case File.read("#{@extract_dir}/#{@output}") do
51+
{:ok, content} ->
52+
hash = :crypto.hash(:sha256, content) |> Base.encode16()
53+
IO.puts("Computed hash: #{hash}")
54+
if hash == @expected_hash do
55+
{:ok, hash, "Hash matches"}
56+
else
57+
{:error, hash, "Hash does not match"}
58+
end
59+
_ ->
60+
{:error, nil, "File not found"}
61+
end
62+
end
63+
64+
def extract do
65+
File.mkdir_p!(@extract_dir_extracted)
66+
case System.cmd("tar", ["-xvf", "#{@extract_dir}/#{@output}", "-C", "#{@extract_dir_extracted}", "--strip-components=1"]) do
67+
{output, 0} ->
68+
IO.puts("Extraction output:\n#{output}")
69+
extracted_files = Path.wildcard("#{@extract_dir_extracted}/**/*")
70+
extracted_files
71+
{output, _} ->
72+
IO.puts("Failed to extract file. Output:\n#{output}")
73+
exit(:normal)
74+
end
75+
end
76+
77+
def create_gdignore do
78+
File.touch("#{@extract_dir}/.gdignore")
79+
end
80+
81+
def make_executable do
82+
case @os_family do
83+
{:win32, :nt} ->
84+
# Windows specific commands
85+
:ok
86+
{:unix, _} ->
87+
File.chmod("#{@extract_dir_extracted}/godot.macos.editor.double.arm64", 0o755)
88+
File.chmod("#{@extract_dir_extracted}/godot.macos.template_debug.double.arm64", 0o755)
89+
File.chmod("#{@extract_dir_extracted}/godot.macos.template_release.double.arm64", 0o755)
90+
File.chmod("#{@extract_dir_extracted}/godot_macos_editor_double.app/Contents/MacOS/Godot", 0o755)
91+
end
92+
end
93+
94+
def sign_app do
95+
case @os_family do
96+
{:win32, :nt} ->
97+
# Windows specific commands
98+
:ok
99+
{:unix, :darwin} ->
100+
System.cmd("codesign", ["--deep", "--force", "--sign", "-", "#{@extract_dir_extracted}/godot.macos.editor.double.arm64"])
101+
System.cmd("codesign", ["--deep", "--force", "--sign", "-", "#{@extract_dir_extracted}/godot.macos.template_debug.double.arm64"])
102+
System.cmd("codesign", ["--deep", "--force", "--sign", "-", "#{@extract_dir_extracted}/godot.macos.template_release.double.arm64"])
103+
System.cmd("codesign", ["--deep", "--force", "--sign", "-", "#{@extract_dir_extracted}/godot_macos_editor_double.app/Contents/MacOS/Godot"])
104+
:ok
105+
_ ->
106+
:ok
107+
end
108+
end
109+
110+
def export_stage do
111+
editor_path = case @os_family do
112+
{:win32, :nt} ->
113+
"#{@extract_dir_extracted}/godot.windows.editor.double.x86_64.llvm.exe"
114+
{:unix, :darwin} ->
115+
"#{@extract_dir_extracted}/godot.macos.editor.double.arm64"
116+
{:unix, _} ->
117+
"#{@extract_dir_extracted}/godot.linux.editor.double.x86_64"
118+
end
119+
120+
if File.exists?(editor_path) do
121+
File.chmod(editor_path, 0o755)
122+
version = System.cmd(editor_path, ["--version"]) |> elem(0) |> String.trim()
123+
platforms = [
124+
{"windows", "x86_64"},
125+
{"linuxbsd", "x86_64"},
126+
{"macos", "arm64"},
127+
{"web", "wasm32"},
128+
]
129+
for {target_platform, target_arch} <- platforms do
130+
export_template(platform_name(@os_family), platform_arch(@os_family), target_platform, target_arch, version)
131+
export_platform(platform_name(@os_family), platform_arch(@os_family), target_platform, target_arch)
132+
end
133+
else
134+
IO.puts("Editor path not found: #{editor_path}")
135+
end
136+
end
137+
138+
defp platform_name({:win32, :nt}), do: "windows"
139+
defp platform_name({:unix, :darwin}), do: "macos"
140+
defp platform_name({:unix, _}), do: "linux"
141+
142+
defp platform_arch({:win32, :nt}), do: "x86_64"
143+
defp platform_arch({:unix, :darwin}), do: "arm64"
144+
defp platform_arch({:unix, _}), do: "x86_64"
145+
146+
def create_version_file(version) do
147+
content = """
148+
## AUTOGENERATED BY BUILD
149+
const BUILD_LABEL = "#{version}"
150+
const BUILD_DATE_STR = "#{:os.system_time(:seconds) |> DateTime.from_unix!() |> DateTime.to_iso8601()}"
151+
const BUILD_UNIX_TIME = #{:os.system_time(:seconds)}
152+
"""
153+
File.mkdir_p!("addons/vsk_version")
154+
File.write!("addons/vsk_version/build_constants.gd", content)
155+
end
156+
157+
def export_template(_from_platform, _from_arch, target_platform, target_arch, version) do
158+
version = String.replace(version, ".custom_build", "")
159+
create_version_file(version)
160+
161+
templatedir = case @os_family do
162+
{:win32, :nt} ->
163+
"#{System.get_env("USERPROFILE")}/AppData/Roaming/Godot/export_templates/#{version}/"
164+
{:unix, :darwin} ->
165+
"#{System.get_env("HOME")}/Library/Application Support/Godot/export_templates/#{version}/"
166+
{:unix, _} ->
167+
"#{System.get_env("HOME")}/.local/share/godot/export_templates/#{version}/"
168+
end
169+
File.mkdir_p!(templatedir)
170+
171+
debug_file = case target_platform do
172+
"linuxbsd" -> "#{@extract_dir_extracted}/godot.linuxbsd.template_debug.double.#{target_arch}"
173+
"windows" -> "#{@extract_dir_extracted}/godot.windows.template_debug.double.#{target_arch}.llvm.exe"
174+
"web" -> "#{@extract_dir_extracted}/godot.web.template_debug.double.wasm32.dlink.zip"
175+
"macos" -> "#{@extract_dir_extracted}/godot_macos_double.zip"
176+
"android" -> "#{@extract_dir_extracted}/android_debug.apk"
177+
_ -> raise "Unsupported platform: #{target_platform}"
178+
end
179+
180+
release_file = case target_platform do
181+
"linuxbsd" -> "#{@extract_dir_extracted}/godot.linuxbsd.template_release.double.#{target_arch}"
182+
"windows" -> "#{@extract_dir_extracted}/godot.windows.template_release.double.#{target_arch}.llvm.exe"
183+
"web" -> "#{@extract_dir_extracted}/godot.web.template_release.double.wasm32.dlink.zip"
184+
"macos" -> "#{@extract_dir_extracted}/godot_macos_double.zip"
185+
"android" -> "#{@extract_dir_extracted}/android_release.apk"
186+
_ -> raise "Unsupported platform: #{target_platform}"
187+
end
188+
189+
debug_file_name = case target_platform do
190+
"linuxbsd" -> "linux_debug.#{target_arch}"
191+
"windows" -> "windows_debug_#{target_arch}.exe"
192+
"web" -> "web_dlink_nothreads_debug.zip"
193+
"macos" -> "macos_debug_#{target_arch}"
194+
"android" -> "android_debug.apk"
195+
_ -> "#{target_platform}_debug_#{target_arch}"
196+
end
197+
198+
release_file_name = case target_platform do
199+
"linuxbsd" -> "linux_release.#{target_arch}"
200+
"windows" -> "windows_release_#{target_arch}.exe"
201+
"web" -> "web_dlink_nothreads_release.zip"
202+
"macos" -> "macos_release_#{target_arch}"
203+
"android" -> "android_release.apk"
204+
_ -> "#{target_platform}_release_#{target_arch}"
205+
end
206+
207+
File.cp!(debug_file, "#{templatedir}/#{debug_file_name}", force: true)
208+
File.cp!(release_file, "#{templatedir}/#{release_file_name}", force: true)
209+
end
210+
211+
def export_platform(from_platform, from_arch, target_platform, target_arch) do
212+
File.rm_rf!("#{@extract_dir}/export_#{target_platform}_#{target_arch}")
213+
File.mkdir_p!("#{@extract_dir}/export_#{target_platform}_#{target_arch}")
214+
215+
editor_file = if from_platform == "windows" and File.exists?("#{@extract_dir_extracted}/godot.#{from_platform}.editor.double.#{from_arch}.llvm.exe") do
216+
"#{@extract_dir_extracted}/godot.#{from_platform}.editor.double.#{from_arch}.llvm.exe"
217+
else
218+
"#{@extract_dir_extracted}/godot.#{from_platform}.editor.double.#{from_arch}"
219+
end
220+
env = [{"ANDROID_SDK_ROOT", "#{File.cwd!()}/android_sdk"}, {"JAVA_HOME", "#{File.cwd!()}/jdk"}]
221+
arguments = ["--headless", "--path", ".", "--import"]
222+
System.cmd(editor_file, arguments, env: env)
223+
224+
output_file = "#{@extract_dir}/export_#{target_platform}_#{target_arch}/#{@project_name}"
225+
output_file = if target_platform == "windows", do: output_file <> ".exe", else: output_file
226+
227+
arguments = ["--headless", "--path", ".", "--export-release", target_platform, output_file]
228+
System.cmd(editor_file, arguments, env: env)
229+
IO.puts(Enum.join(arguments, " "))
230+
231+
case target_platform do
232+
"windows" ->
233+
System.cmd("strip", [output_file])
234+
pdb_file = "#{@extract_dir_extracted}/godot.#{target_platform}.template_release.double.#{from_arch}.llvm.pdb"
235+
if File.exists?(pdb_file) do
236+
File.cp!(pdb_file, "#{@extract_dir}/export_#{target_platform}_#{target_arch}/#{Path.basename(pdb_file)}")
237+
else
238+
IO.puts("PDB file not found: #{pdb_file}")
239+
end
240+
_ -> :ok
241+
end
242+
end
243+
244+
def upload_stage do
245+
upload_artifacts("windows", "x86_64")
246+
upload_artifacts("linux", "x86_64")
247+
end
248+
249+
def upload_artifacts(platform, arch) do
250+
File.mkdir_p!("#{@extract_dir}/game")
251+
File.mkdir_p!("#{@extract_dir}/editor")
252+
File.cp_r!("#{@extract_dir_extracted}/export_#{platform}_#{arch}", "#{@extract_dir}/game")
253+
File.cp_r!("#{@extract_dir_extracted}/export_#{platform}_#{arch}/xr_grid_#{platform}_#{arch}", "#{@extract_dir}/editor/xr_grid_#{platform}_#{arch}_editor")
254+
end
255+
end

0 commit comments

Comments
 (0)