diff --git a/README.md b/README.md index cd96d86..0479b29 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ This action can be used in other repositories' workflows to clone multiple repos **Inputs:** - **`repo-list`** (required): Space-separated list of repositories in `org/repo` format to clone - **`git-pat`** (optional): Git Personal Access Token for authentication +- **`default-repo-ref`** (optional): Default Git reference to check out +- **`pyproject-path`** (optional): Path to the pyproject.toml file **Example workflow:** @@ -22,7 +24,8 @@ This action can be used in other repositories' workflows to clone multiple repos with: repo-list: "org/repo1 org/repo2" git-pat: ${{ secrets.GIT_PAT }} - default-repo-ref: "main" + default-repo-ref: main + pyproject-path: pyproject.toml ~~~ ### Features diff --git a/git-clone/action.yml b/git-clone/action.yml index ea354a5..f0d4173 100644 --- a/git-clone/action.yml +++ b/git-clone/action.yml @@ -10,7 +10,11 @@ inputs: required: false default-repo-ref: description: 'Default Git reference to check out' - default: 'main' + default: '' + required: false + pyproject-path: + description: 'Path to the pyproject.toml file' + default: '' required: false runs: using: "composite" @@ -22,5 +26,7 @@ runs: env: GIT_PAT: ${{ inputs.git-pat }} REPO_LIST: ${{ inputs.repo-list }} + DEFAULT_REPO_REF: ${{ inputs.default-repo-ref }} + PYPROJECT_PATH: ${{ inputs.pyproject-path }} run: | - uv run ${{ github.action_path }}/../scripts/git-clone-ref.py ${REPO_LIST} + uv run ${{ github.action_path }}/../scripts/git-clone-ref.py ${REPO_LIST} --default-repo-ref "${DEFAULT_REPO_REF}" --pyproject-path "${PYPROJECT_PATH}" diff --git a/scripts/git-clone-ref.py b/scripts/git-clone-ref.py index ea3eeb2..7032df4 100755 --- a/scripts/git-clone-ref.py +++ b/scripts/git-clone-ref.py @@ -6,11 +6,13 @@ # ] # /// -import os import logging +import os import shutil +from typing import Annotated import git +import tomllib import typer logger = logging.getLogger(__name__) @@ -24,7 +26,8 @@ def git_clone_repo( repo_ref: str, multi_options: tuple[str, ...] = ("--depth=1", "--recurse-submodules"), ) -> str: - multi_options += (f"--branch {repo_ref}",) + if repo_ref: + multi_options += (f"--branch {repo_ref}",) if os.path.exists(repo_path): logger.info(f"removing {repo_path!r}") @@ -44,7 +47,10 @@ def git_clone_repos( git_pat: str, default_repo_ref: str, ) -> None: - for repo_path in paths: + if not paths: + logger.warning("No repository to clone.") + + for repo_path in set(paths): repo_name = os.path.basename(repo_path) repo_org = os.path.basename(os.path.dirname(repo_path)) git_pat_org = os.getenv(f"GIT_PAT_{repo_org.upper()}", git_pat) @@ -68,17 +74,32 @@ def git_clone_repos( @app.command() def main( - github_repos: list[str] = typer.Argument(..., help="GitHub repositories to clone"), - git_pat: str = typer.Option( - default="", envvar="GIT_PAT", help="GitHub Personal Access Token" - ), - default_repo_ref: str = typer.Option( - default="main", help="Default Git reference to check out" - ), + repo_list: Annotated[ + list[str], + typer.Argument(help="GitHub repositories to clone."), + ] = [], + git_pat: Annotated[ + str, + typer.Option(envvar="GIT_PAT", help="GitHub Personal Access Token."), + ] = "", + default_repo_ref: Annotated[ + str, + typer.Option(help="Default Git reference to check out."), + ] = "", + pyproject_path: Annotated[ + str | None, + typer.Option(help="Path to the pyproject.toml file."), + ] = None, ): + if pyproject_path: + with open(pyproject_path, "rb") as fp: + pyproject = tomllib.load(fp) + config = pyproject.get("tool", {}).get("git-clone", {}) + repo_list.extend(config.get("repo-list", [])) + logging.basicConfig(level=logging.INFO) git_clone_repos( - github_repos, + repo_list, "https://{credentials}github.com/{repo_org}/{repo_name}.git", git_pat, default_repo_ref,