Add GEMINI.md file for adding new BCR module (#6063)
- Those are summarized by Gemini after me guiding it through.
- Also improved `tools/setup_presubmit_repos.py` to avoid using
out-dated BCR content after modification.
diff --git a/GEMINI.md b/GEMINI.md
new file mode 100644
index 0000000..f88f0a3
--- /dev/null
+++ b/GEMINI.md
@@ -0,0 +1,33 @@
+# Gemini's Guide to Adding a Module to the Bazel Central Registry
+
+This document summarizes the key learnings from adding a new module version to the Bazel Central Registry (BCR).
+
+## 1. Initial Scaffolding
+
+1. **Create the version directory**:
+ ```sh
+ mkdir -p modules/<module_name>/<version>
+ ```
+2. **Create the `MODULE.bazel` file**: Copy from a previous version if possible and update the version number. If the module has dependencies, ensure they are correctly listed.
+3. **Create the `source.json` file**: Copy from a previous version if possible and update the version number. This file contains the URL of the source archive, its integrity hash, and the `strip_prefix`. If the source archive doesn't contain a `MODULE.bazel` or `BUILD.bazel` file, you'll need to provide them in an `overlay`.
+4. **Create `overlay` and `patches` directories**: If the module requires any overlays or patches, copy these directories from a previous version if they exist.
+5. **Create `presubmit.yml`**: The validation script will fail if `modules/<module_name>/<version>/presubmit.yml` does not exist. You can usually copy this file from a previous version.
+6. **Update `metadata.json`**: The validation script will fail if the new version is not added to the `versions` list in `modules/<module_name>/metadata.json`.
+
+## 2. Validation and Iteration
+
+* **Validation is your best friend**: The `tools/bcr_validation.py` script is the most important tool for this process. Run it early and often. Use the `--check` flag to specify the module and version you are working on: `bazel run //tools:bcr_validation -- --check <module_name>@<version>`.
+* **Use the `update_integrity` tool**: The `bazel run //tools:update_integrity -- <module name> --version=<version>` command is the correct way to update the integrity hashes in `source.json`.
+* **`overlay` vs. `patches`**:
+ * `overlay`: Use this to add or overwrite files in the downloaded source archive. The files to be overlaid should be placed in an `overlay` subdirectory within the version directory.
+ * `patches`: Use this to apply changes to existing files in the source archive. Patch files should be placed in a `patches` subdirectory.
+* **`MODULE.bazel` Duplication**: The `MODULE.bazel` file must exist in two places:
+ 1. At the root of the version directory (`modules/<module_name>/<version>/MODULE.bazel`).
+ 2. Inside the `overlay` directory (`modules/<module_name>/<version>/overlay/MODULE.bazel`). The file in the `overlay` directory should be a symlink to the one at the root.
+* **`bazel_compatibility`**: When using `overlay`, the `MODULE.bazel` file must specify the `bazel_compatibility` attribute.
+
+## 3. Build Verification
+
+* **Use the presubmit setup tool**: The `bazel run //tools:setup_presubmit_repos -- --module <module_name>@<version>` command sets up a local test environment.
+* **Run the local build**: The output of the presubmit setup tool provides the exact `bazel build` command to run for local testing.
+* **Clear the caches**: If you are having trouble with changes not being picked up, run `bazel clean --expunge` to clear the caches.
diff --git a/tools/bcr_validation.py b/tools/bcr_validation.py
old mode 100644
new mode 100755
diff --git a/tools/setup_presubmit_repos.py b/tools/setup_presubmit_repos.py
index 0f4129e..660c302 100644
--- a/tools/setup_presubmit_repos.py
+++ b/tools/setup_presubmit_repos.py
@@ -43,6 +43,15 @@
return "linux"
+def appendFlagsToBazelrc(repo_root):
+ # Refactor startup flags and common build/test flags into a .bazelrc file
+ with open(os.path.join(repo_root, ".bazelrc"), "a") as f:
+ f.write("common --announce_rc\n")
+ f.write("common --repository_cache=\n") # Disable repo cache to prevent it from caching BCR
+ f.write("common --lockfile_mode=off\n") # Disable lockfile to prevent it from caching BCR
+ f.write("build --verbose_failures\n")
+
+
def print_build_instruction(module_name, module_version, repo_root, task_configs):
build_targets = test_targets = bazel_version = None
@@ -82,19 +91,16 @@
print(f" export USE_BAZEL_VERSION={bazel_version}")
print(f" cd {repo_root}")
+ print(f" bazel clean --expunge")
- startup_flags = ["--nosystem_rc", "--nohome_rc"]
if build_targets:
- build_flags += ["--announce_rc", "--verbose_failures"]
bazel_build_command = (
- f"bazel {' '.join(startup_flags)} build {' '.join(build_flags)} -- {' '.join(build_targets)}"
+ f"bazel --nosystem_rc --nohome_rc build {' '.join(build_flags)} -- {' '.join(build_targets)}"
)
print(f" {bazel_build_command}")
if test_targets:
- test_flags += ["--announce_rc", "--verbose_failures"]
- bazel_test_command = f"bazel {' '.join(startup_flags)} test {' '.join(test_flags)} -- {' '.join(test_targets)}"
+ bazel_test_command = f"bazel --nosystem_rc --nohome_rc test {' '.join(test_flags)} -- {' '.join(test_targets)}"
print(f" {bazel_test_command}")
-
print(f"\nMake sure to check {presubmit_yml} for additional build and test configurations.")
print()
@@ -140,6 +146,7 @@
anonymous_module_root.mkdir(exist_ok=True, parents=True)
bcr_presubmit.create_anonymous_repo(module_name, module_version, anonymous_module_root)
logging.info("Anonymous module repo ready at: %s", anonymous_module_root)
+ appendFlagsToBazelrc(anonymous_module_root)
print_build_instruction(module_name, module_version, anonymous_module_root, anonymous_module_task_config)
except Exception as e:
logging.error("Failed to create anonymous module repo: %s", e)
@@ -157,6 +164,7 @@
module_name, module_version, overwrite_bazel_version=None, root=test_module_root, suppress_log=True
)
logging.info("Test module repo ready at: %s", test_module_root)
+ appendFlagsToBazelrc(test_module_root)
print_build_instruction(module_name, module_version, test_module_root, test_module_task_config)
except Exception as e:
logging.error("Failed to create test module repo: %s", e)