build.cake 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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. const string DOORSTOP_VER_WIN = "3.0.2.2";
  7. const string DOORSTOP_VER_NIX = "1.3.0.0";
  8. const string DOORSTOP_DLL = "winhttp.dll";
  9. var target = Argument("target", "Build");
  10. var isBleedingEdge = Argument("bleeding_edge", false);
  11. var buildId = Argument("build_id", 0);
  12. var lastBuildCommit = Argument("last_build_commit", "");
  13. var buildVersion = "";
  14. var currentCommit = RunGit("rev-parse HEAD");
  15. var currentCommitShort = RunGit("log -n 1 --pretty=\"format:%h\"").Trim();
  16. var currentBranch = RunGit("rev-parse --abbrev-ref HEAD");
  17. var latestTag = RunGit("describe --tags --abbrev=0");
  18. string RunGit(string command, string separator = "")
  19. {
  20. using(var process = StartAndReturnProcess("git", new ProcessSettings { Arguments = command, RedirectStandardOutput = true }))
  21. {
  22. process.WaitForExit();
  23. return string.Join(separator, process.GetStandardOutput());
  24. }
  25. }
  26. Task("Cleanup")
  27. .Does(() =>
  28. {
  29. Information("Removing old binaries");
  30. CreateDirectory("./bin");
  31. CleanDirectory("./bin");
  32. Information("Cleaning up old build objects");
  33. CleanDirectories(GetDirectories("./**/bin/"));
  34. CleanDirectories(GetDirectories("./**/obj/"));
  35. });
  36. Task("PullDependencies")
  37. .Does(() =>
  38. {
  39. Information("Updating git submodules");
  40. StartProcess("git", "submodule update --init --recursive");
  41. Information("Restoring NuGet packages");
  42. NuGetRestore("./BepInEx.sln");
  43. });
  44. Task("Build")
  45. .IsDependentOn("Cleanup")
  46. .IsDependentOn("PullDependencies")
  47. .Does(() =>
  48. {
  49. var bepinExProperties = Directory("./BepInEx/Properties");
  50. if(isBleedingEdge)
  51. {
  52. CopyFile(bepinExProperties + File("AssemblyInfo.cs"), bepinExProperties + File("AssemblyInfo.cs.bak"));
  53. ReplaceRegexInFiles(bepinExProperties + File("AssemblyInfo.cs"), "([0-9]+\\.[0-9]+\\.[0-9]+\\.)[0-9]+", "${1}" + buildId);
  54. FileAppendText(bepinExProperties + File("AssemblyInfo.cs"),
  55. TransformText("\n[assembly: BuildInfo(\"BLEEDING EDGE Build #<%buildNumber%> from <%shortCommit%> at <%branchName%>\")]\n")
  56. .WithToken("buildNumber", buildId)
  57. .WithToken("shortCommit", currentCommit)
  58. .WithToken("branchName", currentBranch)
  59. .ToString());
  60. }
  61. buildVersion = FindRegexMatchInFile(bepinExProperties + File("AssemblyInfo.cs"), "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+", System.Text.RegularExpressions.RegexOptions.None);
  62. var buildSettings = new MSBuildSettings {
  63. Configuration = "Release",
  64. Restore = true
  65. };
  66. buildSettings.Properties["TargetFrameworks"] = new []{ "net35" };
  67. MSBuild("./BepInEx.sln", buildSettings);
  68. })
  69. .Finally(() =>
  70. {
  71. var bepinExProperties = Directory("./BepInEx/Properties");
  72. if(isBleedingEdge)
  73. {
  74. DeleteFile(bepinExProperties + File("AssemblyInfo.cs"));
  75. MoveFile(bepinExProperties + File("AssemblyInfo.cs.bak"), bepinExProperties + File("AssemblyInfo.cs"));
  76. }
  77. });
  78. Task("DownloadDoorstop")
  79. .Does(() =>
  80. {
  81. Information("Downloading Doorstop");
  82. var doorstopPath = Directory("./bin/doorstop");
  83. var doorstopX64Path = doorstopPath + File("doorstop_x64.zip");
  84. var doorstopX86Path = doorstopPath + File("doorstop_x86.zip");
  85. var doorstopLinuxPath = doorstopPath + File("doorstop_linux.zip");
  86. var doorstopMacPath = doorstopPath + File("doorstop_macos.zip");
  87. CreateDirectory(doorstopPath);
  88. DownloadFile($"https://github.com/NeighTools/UnityDoorstop/releases/download/v{DOORSTOP_VER_WIN}/Doorstop_x64_{DOORSTOP_VER_WIN}.zip", doorstopX64Path);
  89. DownloadFile($"https://github.com/NeighTools/UnityDoorstop/releases/download/v{DOORSTOP_VER_WIN}/Doorstop_x86_{DOORSTOP_VER_WIN}.zip", doorstopX86Path);
  90. DownloadFile($"https://github.com/NeighTools/UnityDoorstop.Unix/releases/download/v{DOORSTOP_VER_NIX}/doorstop_v{DOORSTOP_VER_NIX}_linux.zip", doorstopLinuxPath);
  91. DownloadFile($"https://github.com/NeighTools/UnityDoorstop.Unix/releases/download/v{DOORSTOP_VER_NIX}/doorstop_v{DOORSTOP_VER_NIX}_macos.zip", doorstopMacPath);
  92. Information("Extracting Doorstop");
  93. ZipUncompress(doorstopX86Path, doorstopPath + Directory("x86"));
  94. ZipUncompress(doorstopX64Path, doorstopPath + Directory("x64"));
  95. ZipUncompress(doorstopLinuxPath, doorstopPath + Directory("nix"));
  96. ZipUncompress(doorstopMacPath, doorstopPath + Directory("nix"));
  97. });
  98. Task("MakeDist")
  99. .IsDependentOn("Build")
  100. .IsDependentOn("DownloadDoorstop")
  101. .Does(() =>
  102. {
  103. var distDir = Directory("./bin/dist");
  104. var distPatcherDir = distDir + Directory("patcher");
  105. var doorstopPath = Directory("./bin/doorstop");
  106. CreateDirectory(distDir);
  107. CreateDirectory(distPatcherDir);
  108. var changelog = TransformText("<%commit_count%> commits since <%last_tag%>\r\n\r\nChangelog (excluding merges):\r\n<%commit_log%>")
  109. .WithToken("commit_count", RunGit($"rev-list --count {latestTag}..HEAD"))
  110. .WithToken("last_tag", latestTag)
  111. .WithToken("commit_log", RunGit($"--no-pager log --no-merges --pretty=\"format:* (%h) [%an] %s\" {latestTag}..HEAD", "\r\n"))
  112. .ToString();
  113. void PackageBepin(string arch, string copyPattern, string doorstopConfigPattern, string libDir = null, bool ensureLf = false)
  114. {
  115. var distArchDir = distDir + Directory(arch);
  116. var bepinDir = distArchDir + Directory("BepInEx");
  117. var doorstopTargetDir = distArchDir;
  118. if(libDir != null) doorstopTargetDir += Directory(libDir);
  119. var doorstopFiles = doorstopPath + Directory(arch) + File(copyPattern);
  120. CreateDirectory(distArchDir);
  121. CreateDirectory(doorstopTargetDir);
  122. CreateDirectory(bepinDir + Directory("core"));
  123. CreateDirectory(bepinDir + Directory("plugins"));
  124. CreateDirectory(bepinDir + Directory("patchers"));
  125. CopyFiles($"./doorstop/{doorstopConfigPattern}", distArchDir);
  126. if(ensureLf)
  127. ReplaceTextInFiles($"{distArchDir}/{doorstopConfigPattern}", "\r\n", "\n");
  128. CopyFiles("./bin/*.*", bepinDir + Directory("core"));
  129. CopyFiles(doorstopFiles, doorstopTargetDir);
  130. FileWriteText(distArchDir + File("changelog.txt"), changelog);
  131. }
  132. PackageBepin("x86", DOORSTOP_DLL, "doorstop_config.ini");
  133. PackageBepin("x64", DOORSTOP_DLL, "doorstop_config.ini");
  134. PackageBepin("nix", "*.*", "run_bepinex.sh", "doorstop_libs", true);
  135. CopyFileToDirectory(File("./bin/patcher/BepInEx.Patcher.exe"), distPatcherDir);
  136. });
  137. Task("Pack")
  138. .IsDependentOn("MakeDist")
  139. .Does(() =>
  140. {
  141. var distDir = Directory("./bin/dist");
  142. var commitPrefix = isBleedingEdge ? $"_{currentCommitShort}_" : "_";
  143. Information("Packing BepInEx");
  144. ZipCompress(distDir + Directory("x86"), distDir + File($"BepInEx_x86{commitPrefix}{buildVersion}.zip"));
  145. ZipCompress(distDir + Directory("x64"), distDir + File($"BepInEx_x64{commitPrefix}{buildVersion}.zip"));
  146. ZipCompress(distDir + Directory("nix"), distDir + File($"BepInEx_unix{commitPrefix}{buildVersion}.zip"));
  147. Information("Packing BepInEx.Patcher");
  148. ZipCompress(distDir + Directory("patcher"), distDir + File($"BepInEx_Patcher{commitPrefix}{buildVersion}.zip"));
  149. if(isBleedingEdge)
  150. {
  151. var changelog = "";
  152. if(!string.IsNullOrEmpty(lastBuildCommit)) {
  153. changelog = TransformText("<ul><%changelog%></ul>")
  154. .WithToken("changelog", RunGit($"--no-pager log --no-merges --pretty=\"format:<li>(<code>%h</code>) [%an] %s</li>\" {lastBuildCommit}..HEAD"))
  155. .ToString();
  156. }
  157. FileWriteText(distDir + File("info.json"),
  158. SerializeJsonPretty(new Dictionary<string, object>{
  159. ["id"] = buildId.ToString(),
  160. ["date"] = DateTime.Now.ToString("o"),
  161. ["changelog"] = changelog,
  162. ["hash"] = currentCommit,
  163. ["artifacts"] = new Dictionary<string, object>[] {
  164. new Dictionary<string, object> {
  165. ["file"] = $"BepInEx_x64{commitPrefix}{buildVersion}.zip",
  166. ["description"] = "BepInEx for x64 machines"
  167. },
  168. new Dictionary<string, object> {
  169. ["file"] = $"BepInEx_x86{commitPrefix}{buildVersion}.zip",
  170. ["description"] = "BepInEx for x86 machines"
  171. },
  172. new Dictionary<string, object> {
  173. ["file"] = $"BepInEx_unix{commitPrefix}{buildVersion}.zip",
  174. ["description"] = "BepInEx for Unix with GCC (Linux, MacOS)"
  175. },
  176. new Dictionary<string, object> {
  177. ["file"] = $"BepInEx_Patcher{commitPrefix}{buildVersion}.zip",
  178. ["description"] = "Hardpatcher for BepInEx. IMPORTANT: USE ONLY IF DOORSTOP DOES NOT WORK FOR SOME REASON!"
  179. }
  180. }
  181. }));
  182. }
  183. });
  184. RunTarget(target);