Short identifier for the currently-deployed code. In production, ``GIT_SHA`` is baked in by the Docker build (see the ``ARG GIT_SHA`` in the Dockerfile). In a source checkout, falls back to ``git rev-parse HEAD``, appending ``-dirty`` if the working tree has uncommitted changes — m
(project_root: str)
| 34 | |
| 35 | |
| 36 | def _get_git_sha(project_root: str) -> str: |
| 37 | """Short identifier for the currently-deployed code. |
| 38 | |
| 39 | In production, ``GIT_SHA`` is baked in by the Docker build (see the |
| 40 | ``ARG GIT_SHA`` in the Dockerfile). In a source checkout, falls |
| 41 | back to ``git rev-parse HEAD``, appending ``-dirty`` if the working |
| 42 | tree has uncommitted changes — matching ``git describe --dirty``. |
| 43 | Returns ``"local"`` if neither works. |
| 44 | """ |
| 45 | env_sha = os.environ.get("GIT_SHA", "").strip() |
| 46 | if env_sha: |
| 47 | # The -dirty suffix, if any, is added by whoever set GIT_SHA |
| 48 | # (e.g. `make deploy-local`). We just pass it through. |
| 49 | return env_sha |
| 50 | try: |
| 51 | rev_parse = subprocess.run( |
| 52 | ["git", "-C", project_root, "rev-parse", "HEAD"], |
| 53 | capture_output=True, |
| 54 | text=True, |
| 55 | timeout=2, |
| 56 | check=False, |
| 57 | ) |
| 58 | if rev_parse.returncode != 0: |
| 59 | return "local" |
| 60 | sha = rev_parse.stdout.strip() |
| 61 | status = subprocess.run( |
| 62 | ["git", "-C", project_root, "status", "--porcelain"], |
| 63 | capture_output=True, |
| 64 | text=True, |
| 65 | timeout=2, |
| 66 | check=False, |
| 67 | ) |
| 68 | if status.returncode == 0 and status.stdout.strip(): |
| 69 | sha += "-dirty" |
| 70 | return sha |
| 71 | except (OSError, subprocess.SubprocessError): |
| 72 | return "local" |
| 73 | |
| 74 | |
| 75 | def get_distros() -> list[tuple[str, str]]: |