From 71bb21f26ff9a1c7cff55267a7846e42118a4996 Mon Sep 17 00:00:00 2001 From: MoonlightSentinel Date: Wed, 5 May 2021 20:55:28 +0200 Subject: [PATCH] build_all.d: Use git ls-remote as a fallback in getDubTag GitHub's API sometimes rejects the request which fetches the available tags with a `HTTP 403`. This patch uses `git ls-remote` as a fallback when the current tag could not be retrieved from the API. --- create_dmd_release/build_all.d | 38 +++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/create_dmd_release/build_all.d b/create_dmd_release/build_all.d index be7e764c..051d1738 100644 --- a/create_dmd_release/build_all.d +++ b/create_dmd_release/build_all.d @@ -352,17 +352,49 @@ void runBuild(ref Box box, string ver, bool isBranch, bool skipDocs, string ldcV import std.regex; enum versionRE = regex(`^v(\d+)\.(\d+)\.(\d+)(-.*)?$`); +/// Determines the latest release tagged for the Dub repository string getDubTag(bool preRelease) { import std.net.curl : get; - import std.json : parseJSON; + import std.json : parseJSON, JSONValue; // github already sorts tags in descending semantic versioning order - foreach (tag; get("https://api.github.com/repos/dlang/dub/tags").parseJSON.array) + foreach (tag; get("https://api.github.com/repos/dlang/dub/tags").parseJSON.array.ifThrown(JSONValue[].init)) if (auto m = tag["name"].str.match(versionRE)) if (preRelease || m.captures[4].empty) return tag["name"].str; - throw new Exception("Failed to get dub tags"); + + // Fallback: Use git ls-remote to list all known tags and sort them appropriatly + auto re = regex(`v(\d+)\.(\d+)\.(\d+)(-[^\^]*)?$`); + auto tagList = runCapture("git ls-remote --tags https://github.com/dlang/dub.git") + .lineSplitter + .map!(t => t.match(re)) + .filter!(m => !m.empty && (preRelease || m.captures[4].empty)) + .array; + + enforce(!tagList.empty, "Failed to get dub tags"); + + // Order by version numbers as integers + alias lessVer(int idx) = (a, b) => a.captures[idx].to!int < b.captures[idx].to!int; + + // Order by suffix + alias lessSuf = (ca, cb) { + const a = ca.captures[4]; + const b = cb.captures[4]; + + // Preference: "beta" < "rc" < "" + if (a.length != b.length) + return a.length > b.length; + + // Lexical order to compare numbers "beta.1" vs "beta.2*" + return a < b; + }; + + // Sort entire list according to the predicates defined above + tagList.multiSort!(lessVer!1, lessVer!2, lessVer!3, lessSuf); + + // Maximum element denotes the most recent tag + return tagList[$-1].captures[0]; } void getCodesignCerts(string tgtDir)