diff --git a/bazel/README.md b/bazel/README.md index 97ee7308b365a..db0ab9aaf53a6 100644 --- a/bazel/README.md +++ b/bazel/README.md @@ -41,9 +41,20 @@ Given all required [Envoy dependencies](https://www.envoyproxy.io/docs/envoy/lat 1. `python3 tools/github/tools/github/write_current_source_version.py` from the repository root. 1. `bazel build -c opt envoy` from the repository root. -> Note: If the the `write_current_source_version.py` script is missing from the extracted source code directory, you can download it from [here](https://raw.githubusercontent.com/envoyproxy/envoy/tree/main/tools/github/write_current_source_version.py). +> **Note**: If the the `write_current_source_version.py` script is missing from the extracted source code directory, you can download it from [here](https://raw.githubusercontent.com/envoyproxy/envoy/main/tools/github/write_current_source_version.py). > This script is used to generate SOURCE_VERSION that is required by [`bazel/get_workspace_status`](./get_workspace_status) to "stamp" the binary in a non-git directory. +> **Note**: To avoid rate-limiting by GitHub API, you can provide [a valid GitHub token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-authentication-to-github#githubs-token-formats) to `GITHUB_TOKEN` environment variable. +> The environment variable name that holds the token can also be customized by setting `--github_api_token_env_name`. +> In a GitHub Actions workflow file, you can set this token from [`secrets.GITHUB_TOKEN`](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#about-the-github_token-secret). + +Examples: + +```console +GITHUB_TOKEN= python3 tools/github/write_current_source_version.py +MY_TOKEN= python3 tools/github/write_current_source_version.py --github_api_token_env_name=MY_TOKEN +``` + ## Quick start Bazel build for developers This section describes how to and what dependencies to install to get started building Envoy with Bazel. diff --git a/tools/github/write_current_source_version.py b/tools/github/write_current_source_version.py index f183e577d3a06..1b366504743bd 100644 --- a/tools/github/write_current_source_version.py +++ b/tools/github/write_current_source_version.py @@ -9,9 +9,12 @@ # tarball. import argparse +import http import json +import os import pathlib import sys +import urllib.error import urllib.request if __name__ == "__main__": @@ -21,6 +24,14 @@ dest="skip_error_in_git", help="Skip returning error on exit when the current directory is a git repository.", action="store_true") + parser.add_argument( + "--github_api_token_env_name", + dest="github_api_token_env_name", + help="The system environment variable name that holds GitHub API token. " + "This is advisable to provide this to avoid rate-limited calls.", + type=str, + action="store", + default="GITHUB_TOKEN") args = parser.parse_args() # Simple check if a .git directory exists. When we are in a Git repo, we should rely on git. @@ -35,8 +46,11 @@ sys.exit(0) sys.exit(1) + # Get the project root directory (../../..). + project_root_dir = pathlib.Path(__file__).parent.parent.parent + # Check if we have VERSION.txt available - current_version_file = pathlib.Path("VERSION.txt") + current_version_file = project_root_dir.joinpath("VERSION.txt") if not current_version_file.exists(): print( "Failed to read VERSION.txt. " @@ -54,9 +68,26 @@ sys.exit(1) # Fetch the current version commit information from GitHub. - with urllib.request.urlopen("https://api.github.com/repos/envoyproxy/envoy/commits/v" - + current_version) as response: - commit_info = json.loads(response.read()) - source_version_file = pathlib.Path("SOURCE_VERSION") - # Write the extracted current version commit hash "sha" to SOURCE_VERSION. - source_version_file.write_text(commit_info["sha"]) + commit_info_request = urllib.request.Request( + "https://api.github.com/repos/envoyproxy/envoy/commits/v" + current_version) + if github_token := os.environ.get(args.github_api_token_env_name): + # Reference: https://github.com/octokit/auth-token.js/blob/902a172693d08de998250bf4d8acb1fdb22377a4/src/with-authorization-prefix.ts#L6-L12. + authorization_header_prefix = "bearer" if len(github_token.split(".")) == 3 else "token" + # To avoid rate-limited API calls. + commit_info_request.add_header( + "Authorization", f"{authorization_header_prefix} {github_token}") + try: + with urllib.request.urlopen(commit_info_request) as response: + commit_info = json.loads(response.read()) + source_version_file = project_root_dir.joinpath("SOURCE_VERSION") + # Write the extracted current version commit hash "sha" to SOURCE_VERSION. + source_version_file.write_text(commit_info["sha"]) + except urllib.error.HTTPError as e: + status_code = e.code + if e.code in (http.HTTPStatus.UNAUTHORIZED, http.HTTPStatus.FORBIDDEN): + print( + f"Please check the GitHub token provided in {args.github_api_token_env_name} environment variable. {e.reason}." + ) + sys.exit(1) + else: + raise Exception(f"Failed since {e.reason} ({status_code}).")