build/github_repository: allow storing submodule_info as attr

Currently we are doing too many requests to the REST API as our CI is
invalidating the cache too often. This is a workaround until we can
store said data inside MODUEL.bazel.lock.

Change-Id: Iac9be2a4ed3d3fb5f301ac63545d07d807cc2f8e
Reviewed-on: https://review.monogon.dev/c/monogon/+/4156
Tested-by: Jenkins CI
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/build/github_repository/def.bzl b/build/github_repository/def.bzl
index 81a7268..9186c25 100644
--- a/build/github_repository/def.bzl
+++ b/build/github_repository/def.bzl
@@ -41,24 +41,31 @@
     )
 
     for submodule, integrity in ctx.attr.submodules.items():
-        url = build_submodule_info_url(
-            owner = ctx.attr.owner,
-            repo = ctx.attr.repo,
-            ref = ctx.attr.ref,
-            submodule = submodule,
-        )
+        if submodule not in ctx.attr.submodule_info:
+            url = build_submodule_info_url(
+                owner = ctx.attr.owner,
+                repo = ctx.attr.repo,
+                ref = ctx.attr.ref,
+                submodule = submodule,
+            )
 
-        submodule_info_path = submodule + ".submodule_info"
-        ctx.download(
-            url = url,
-            headers = {
-                "Accept": "application/vnd.github+json",
-                "X-GitHub-Api-Version": "2022-11-28",
-            },
-            output = submodule_info_path,
-        )
+            submodule_info_path = submodule + ".submodule_info"
+            ctx.download(
+                url = url,
+                headers = {
+                    "Accept": "application/vnd.github+json",
+                    "X-GitHub-Api-Version": "2022-11-28",
+                },
+                output = submodule_info_path,
+            )
 
-        submodule_info = json.decode(ctx.read(submodule_info_path))
+            submodule_info = json.decode(ctx.read(submodule_info_path))
+
+            # buildifier: disable=print
+            print("Missing submodule_info for submodule %s. Consider adding it: \n%s" % (submodule, submodule_info))
+        else:
+            submodule_info = json.decode(ctx.attr.submodule_info[submodule])
+
         if submodule_info["type"] != "submodule":
             fail("provided submodule path is not a submodule")
 
@@ -81,7 +88,7 @@
         )
         if integrity == "":
             # buildifier: disable=print
-            print("Missing integrity for submodule \"{submodule}\": \"{integrity}\". Consider adding it.".format(
+            print("Missing integrity for submodule {submodule}. Consider adding it:\n\"{submodule}\": \"{integrity}\".".format(
                 submodule = submodule,
                 integrity = download_info.integrity,
             ))
@@ -106,6 +113,13 @@
         default = {},
         doc = "The list of submodules with their integrity as value",
     ),
+    "submodule_info": attr.string_dict(
+        mandatory = False,
+        default = {},
+        doc = """The list of submodules with their GitHub API response as value.
+        This is a workaround until https://github.com/bazelbuild/bazel/issues/24777
+        is implemented to prevent hitting GitHub API limits.""",
+    ),
     "ref": attr.string(
         default = "",
         doc =