build.cake 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. #addin nuget:?package=Cake.FileHelpers&version=3.2.1
  2. #addin nuget:?package=SharpZipLib&version=1.2.0
  3. #addin nuget:?package=Cake.Compression&version=0.2.4
  4. #addin nuget:?package=Cake.Json&version=4.0.0
  5. #addin nuget:?package=Newtonsoft.Json&version=11.0.2
  6. var target = Argument("target", "Build");
  7. var isBleedingEdge = Argument("bleeding_edge", false);
  8. var buildId = Argument("build_id", 0);
  9. var lastBuildCommit = Argument("last_build_commit", "");
  10. var buildVersion = "";
  11. var currentCommit = RunGit("rev-parse HEAD");
  12. var currentCommitShort = RunGit("log -n 1 --pretty=\"format:%h\"").Trim();
  13. var currentBranch = RunGit("rev-parse --abbrev-ref HEAD");
  14. var latestTag = RunGit("describe --tags --abbrev=0");
  15. string RunGit(string command, string separator = "")
  16. {
  17. using(var process = StartAndReturnProcess("git", new ProcessSettings { Arguments = command, RedirectStandardOutput = true }))
  18. {
  19. process.WaitForExit();
  20. return string.Join(separator, process.GetStandardOutput());
  21. }
  22. }
  23. Task("Cleanup")
  24. .Does(() =>
  25. {
  26. Information("Removing old binaries");
  27. CreateDirectory("./bin");
  28. CleanDirectory("./bin");
  29. Information("Cleaning up old build objects");
  30. CleanDirectories(GetDirectories("./**/bin/"));
  31. CleanDirectories(GetDirectories("./**/obj/"));
  32. });
  33. Task("PullDependencies")
  34. .Does(() =>
  35. {
  36. Information("Updating git submodules");
  37. StartProcess("git", "submodule update --init --recursive");
  38. Information("Restoring NuGet packages");
  39. NuGetRestore("./BepInEx.sln");
  40. });
  41. Task("Build")
  42. .IsDependentOn("Cleanup")
  43. .IsDependentOn("PullDependencies")
  44. .Does(() =>
  45. {
  46. var bepinExProperties = Directory("./BepInEx.Shared");
  47. if(isBleedingEdge)
  48. {
  49. CopyFile(bepinExProperties + File("VersionInfo.cs"), bepinExProperties + File("VersionInfo.cs.bak"));
  50. CopyFile(bepinExProperties + File("AssemblyInfo.cs"), bepinExProperties + File("AssemblyInfo.cs.bak"));
  51. ReplaceRegexInFiles(bepinExProperties + File("VersionInfo.cs"), "([0-9]+\\.[0-9]+\\.[0-9]+\\.)[0-9]+", "${1}" + buildId);
  52. FileAppendText(bepinExProperties + File("AssemblyInfo.cs"),
  53. TransformText("\n[assembly: BuildInfo(\"BLEEDING EDGE Build #<%buildNumber%> from <%shortCommit%> at <%branchName%>\")]\n")
  54. .WithToken("buildNumber", buildId)
  55. .WithToken("shortCommit", currentCommit)
  56. .WithToken("branchName", currentBranch)
  57. .ToString());
  58. }
  59. buildVersion = FindRegexMatchInFile(bepinExProperties + File("VersionInfo.cs"), "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+", System.Text.RegularExpressions.RegexOptions.None);
  60. var buildSettings = new MSBuildSettings {
  61. Configuration = "Release",
  62. Restore = true
  63. };
  64. //buildSettings.Properties["TargetFrameworks"] = new []{ "net35" };
  65. MSBuild("./BepInEx.Unity/BepInEx.Unity.csproj", buildSettings);
  66. //buildSettings.Properties["TargetFrameworks"] = new []{ "net452" };
  67. MSBuild("./BepInEx.NetLauncher/BepInEx.NetLauncher.csproj", buildSettings);
  68. //buildSettings.Properties["TargetFrameworks"] = new []{ "net472" };
  69. MSBuild("./BepInEx.IL2CPP/BepInEx.IL2CPP.csproj", buildSettings);
  70. })
  71. .Finally(() =>
  72. {
  73. var bepinExProperties = Directory("./BepInEx.Shared");
  74. if(isBleedingEdge)
  75. {
  76. DeleteFile(bepinExProperties + File("AssemblyInfo.cs"));
  77. DeleteFile(bepinExProperties + File("VersionInfo.cs"));
  78. MoveFile(bepinExProperties + File("AssemblyInfo.cs.bak"), bepinExProperties + File("AssemblyInfo.cs"));
  79. MoveFile(bepinExProperties + File("VersionInfo.cs.bak"), bepinExProperties + File("VersionInfo.cs"));
  80. }
  81. });
  82. const string DOORSTOP_VER_WIN = "3.1.0.0";
  83. const string DOORSTOP_VER_UNIX = "1.3.0.0";
  84. const string MONO_VER = "2020.11.08";
  85. const string DOORSTOP_DLL = "winhttp.dll";
  86. Task("DownloadDependencies")
  87. .Does(() =>
  88. {
  89. Information("Downloading Doorstop");
  90. var doorstopPath = Directory("./bin/doorstop");
  91. var doorstopX64Path = doorstopPath + File("doorstop_x64.zip");
  92. var doorstopX86Path = doorstopPath + File("doorstop_x86.zip");
  93. var doorstopLinuxPath = doorstopPath + File("doorstop_linux.zip");
  94. var doorstopMacPath = doorstopPath + File("doorstop_macos.zip");
  95. CreateDirectory(doorstopPath);
  96. DownloadFile($"https://github.com/NeighTools/UnityDoorstop/releases/download/v{DOORSTOP_VER_WIN}/Doorstop_x64_{DOORSTOP_VER_WIN}.zip", doorstopX64Path);
  97. DownloadFile($"https://github.com/NeighTools/UnityDoorstop/releases/download/v{DOORSTOP_VER_WIN}/Doorstop_x86_{DOORSTOP_VER_WIN}.zip", doorstopX86Path);
  98. DownloadFile($"https://github.com/NeighTools/UnityDoorstop.Unix/releases/download/v{DOORSTOP_VER_UNIX}/doorstop_v{DOORSTOP_VER_UNIX}_linux.zip", doorstopLinuxPath);
  99. DownloadFile($"https://github.com/NeighTools/UnityDoorstop.Unix/releases/download/v{DOORSTOP_VER_UNIX}/doorstop_v{DOORSTOP_VER_UNIX}_macos.zip", doorstopMacPath);
  100. Information("Extracting Doorstop");
  101. ZipUncompress(doorstopX86Path, doorstopPath + Directory("x86"));
  102. ZipUncompress(doorstopX64Path, doorstopPath + Directory("x64"));
  103. ZipUncompress(doorstopLinuxPath, doorstopPath + Directory("unix"));
  104. ZipUncompress(doorstopMacPath, doorstopPath + Directory("unix"));
  105. Information("Downloading Mono");
  106. var monoPath = Directory("./bin/doorstop/mono");
  107. var monoX64Path = doorstopPath + File("mono_x64.zip");
  108. var monoX86Path = doorstopPath + File("mono_x86.zip");
  109. CreateDirectory(monoPath);
  110. DownloadFile($"https://github.com/BepInEx/mono/releases/download/{MONO_VER}/mono-x64.zip", monoX64Path);
  111. DownloadFile($"https://github.com/BepInEx/mono/releases/download/{MONO_VER}/mono-x86.zip", monoX86Path);
  112. Information("Extracting Mono");
  113. ZipUncompress(monoX64Path, monoPath + Directory("x64"));
  114. ZipUncompress(monoX86Path, monoPath + Directory("x86"));
  115. });
  116. Task("MakeDist")
  117. .IsDependentOn("Build")
  118. .IsDependentOn("DownloadDependencies")
  119. .Does(() =>
  120. {
  121. var distDir = Directory("./bin/dist");
  122. //var distPatcherDir = distDir + Directory("patcher");
  123. var doorstopPath = Directory("./bin/doorstop");
  124. CreateDirectory(distDir);
  125. //CreateDirectory(distPatcherDir);
  126. var changelog = TransformText("<%commit_count%> commits since <%last_tag%>\r\n\r\nChangelog (excluding merges):\r\n<%commit_log%>")
  127. .WithToken("commit_count", RunGit($"rev-list --count {latestTag}..HEAD"))
  128. .WithToken("last_tag", latestTag)
  129. .WithToken("commit_log", RunGit($"--no-pager log --no-merges --pretty=\"format:* (%h) [%an] %s\" {latestTag}..HEAD", "\r\n"))
  130. .ToString();
  131. void PackageBepin(string platform, string arch, string originDir, string doorstopConfigFile = null, bool copyMono = false)
  132. {
  133. string platformName = platform + (arch == null ? "" : "_" + arch);
  134. bool isUnix = arch == "unix";
  135. Information("Creating distributions for platform \"" + platformName + "\"...");
  136. string doorstopArchPath = null;
  137. if (arch != null)
  138. {
  139. doorstopArchPath = doorstopPath + Directory(arch)
  140. + File(isUnix ? "*.*" : DOORSTOP_DLL);
  141. }
  142. var distArchDir = distDir + Directory(platformName);
  143. var bepinDir = distArchDir + Directory("BepInEx");
  144. var doorstopDir = distArchDir;
  145. if (isUnix) doorstopDir += Directory("doorstop_libs");
  146. CreateDirectory(distArchDir);
  147. CreateDirectory(doorstopDir);
  148. CreateDirectory(bepinDir + Directory("core"));
  149. CreateDirectory(bepinDir + Directory("plugins"));
  150. CreateDirectory(bepinDir + Directory("patchers"));
  151. if (doorstopArchPath != null)
  152. {
  153. CopyFile("./doorstop/" + doorstopConfigFile, Directory(distArchDir) + File(isUnix ? "run_bepinex.sh" : "doorstop_config.ini"));
  154. CopyFiles(doorstopArchPath, doorstopDir);
  155. if (isUnix)
  156. {
  157. ReplaceTextInFiles($"{distArchDir}/run_bepinex.sh", "\r\n", "\n");
  158. }
  159. if (copyMono)
  160. {
  161. CopyDirectory("./bin/doorstop/mono/" + arch + "/mono", Directory(distArchDir) + Directory("mono"));
  162. }
  163. }
  164. CopyFiles("./bin/" + Directory(originDir) + "/*.*", Directory(bepinDir) + Directory("core"));
  165. FileWriteText(distArchDir + File("changelog.txt"), changelog);
  166. if (platform == "NetLauncher")
  167. {
  168. DeleteFile(Directory(bepinDir) + Directory("core") + File("BepInEx.NetLauncher.exe.config"));
  169. MoveFiles(Directory(bepinDir) + Directory("core") + File("BepInEx.NetLauncher.*"), Directory(distArchDir));
  170. }
  171. }
  172. PackageBepin("UnityMono", "x86", "Unity", "doorstop_config_mono.ini");
  173. PackageBepin("UnityMono", "x64", "Unity", "doorstop_config_mono.ini");
  174. PackageBepin("UnityMono", "unix", "Unity", "run_bepinex.sh");
  175. PackageBepin("UnityIL2CPP", "x86", "IL2CPP", "doorstop_config_il2cpp.ini", copyMono: true);
  176. PackageBepin("UnityIL2CPP", "x64", "IL2CPP", "doorstop_config_il2cpp.ini", copyMono: true);
  177. PackageBepin("NetLauncher", null, "NetLauncher");
  178. //CopyFileToDirectory(File("./bin/patcher/BepInEx.Patcher.exe"), distPatcherDir);
  179. });
  180. Task("Pack")
  181. .IsDependentOn("MakeDist")
  182. .Does(() =>
  183. {
  184. var distDir = Directory("./bin/dist");
  185. var commitPrefix = isBleedingEdge ? $"_{currentCommitShort}_" : "_";
  186. Information("Packing BepInEx");
  187. ZipCompress(distDir + Directory("UnityMono_x86"), distDir + File($"BepInEx_UnityMono_x86{commitPrefix}{buildVersion}.zip"));
  188. ZipCompress(distDir + Directory("UnityMono_x64"), distDir + File($"BepInEx_UnityMono_x64{commitPrefix}{buildVersion}.zip"));
  189. ZipCompress(distDir + Directory("UnityMono_unix"), distDir + File($"BepInEx_UnityMono_unix{commitPrefix}{buildVersion}.zip"));
  190. ZipCompress(distDir + Directory("UnityIL2CPP_x86"), distDir + File($"BepInEx_UnityIL2CPP_x86{commitPrefix}{buildVersion}.zip"));
  191. ZipCompress(distDir + Directory("UnityIL2CPP_x64"), distDir + File($"BepInEx_UnityIL2CPP_x64{commitPrefix}{buildVersion}.zip"));
  192. ZipCompress(distDir + Directory("NetLauncher"), distDir + File($"BepInEx_NetLauncher{commitPrefix}{buildVersion}.zip"));
  193. // Information("Packing BepInEx.Patcher");
  194. // ZipCompress(distDir + Directory("patcher"), distDir + File($"BepInEx_Patcher{commitPrefix}{buildVersion}.zip"));
  195. if(isBleedingEdge)
  196. {
  197. var changelog = "";
  198. if(!string.IsNullOrEmpty(lastBuildCommit)) {
  199. changelog = TransformText("<ul><%changelog%></ul>")
  200. .WithToken("changelog", RunGit($"--no-pager log --no-merges --pretty=\"format:<li>(<code>%h</code>) [%an] %s</li>\" {lastBuildCommit}..HEAD"))
  201. .ToString();
  202. }
  203. FileWriteText(distDir + File("info.json"),
  204. SerializeJsonPretty(new Dictionary<string, object>{
  205. ["id"] = buildId.ToString(),
  206. ["date"] = DateTime.Now.ToString("o"),
  207. ["changelog"] = changelog,
  208. ["hash"] = currentCommit,
  209. ["artifacts"] = new Dictionary<string, object>[] {
  210. new Dictionary<string, object> {
  211. ["file"] = $"BepInEx_UnityMono_x64{commitPrefix}{buildVersion}.zip",
  212. ["description"] = "BepInEx Unity Mono for Windows x64 machines"
  213. },
  214. new Dictionary<string, object> {
  215. ["file"] = $"BepInEx_UnityMono_x86{commitPrefix}{buildVersion}.zip",
  216. ["description"] = "BepInEx Unity Mono for Windows x86 machines"
  217. },
  218. new Dictionary<string, object> {
  219. ["file"] = $"BepInEx_unix{commitPrefix}{buildVersion}.zip",
  220. ["description"] = "BepInEx Unity Mono for Unix machines with GCC (Linux, MacOS)"
  221. },
  222. new Dictionary<string, object> {
  223. ["file"] = $"BepInEx_UnityIL2CPP_x64{commitPrefix}{buildVersion}.zip",
  224. ["description"] = "BepInEx Unity IL2CPP for Windows x64 machines"
  225. },
  226. new Dictionary<string, object> {
  227. ["file"] = $"BepInEx_UnityIL2CPP_x86{commitPrefix}{buildVersion}.zip",
  228. ["description"] = "BepInEx Unity IL2CPP for Windows x86 machines"
  229. },
  230. new Dictionary<string, object> {
  231. ["file"] = $"BepInEx_NetLauncher{commitPrefix}{buildVersion}.zip",
  232. ["description"] = "BepInEx .NET Launcher for .NET Framework/XNA games"
  233. },
  234. // new Dictionary<string, object> {
  235. // ["file"] = $"BepInEx_Patcher{commitPrefix}{buildVersion}.zip",
  236. // ["description"] = "Hardpatcher for BepInEx. IMPORTANT: USE ONLY IF DOORSTOP DOES NOT WORK FOR SOME REASON!"
  237. // }
  238. }
  239. }));
  240. }
  241. });
  242. RunTarget(target);