From 81447496418e6ae71670b9aea73c7d3b54fff436 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Fri, 22 Sep 2023 18:08:02 +0200 Subject: [PATCH 1/6] Add git info to context --- core/dbt/context/base.py | 29 +++++++++++++++++++++++++++++ core/setup.py | 1 + 2 files changed, 30 insertions(+) diff --git a/core/dbt/context/base.py b/core/dbt/context/base.py index 25373787e86..1b1f21540e1 100644 --- a/core/dbt/context/base.py +++ b/core/dbt/context/base.py @@ -26,6 +26,8 @@ from dbt.events.contextvars import get_node_info from dbt.version import __version__ as dbt_version +from pygit2 import Repository, GitError # type: ignore + # These modules are added to the context. Consider alternative # approaches which will extend well to potentially many modules import pytz @@ -204,6 +206,33 @@ def to_dict(self) -> Dict[str, Any]: self._ctx.update(builtins) return self._ctx + @contextproperty() + def git_branch(self) -> str: + """The `git_branch` variable returns the current branch if the + code is version controlled by git. + Otherwise it returns an empty string. + """ + try: + branch_name = Repository(".").head.shorthand + except GitError: + branch_name = "" + + return branch_name + + @contextproperty() + def git_sha(self) -> str: + """The `git_sha` variable returns the sha of the last commit + if the dbt code is version controlled in git. + Otherwise it returns an empty string. + """ + try: + repo = Repository(".") + sha = repo.head.target.hex + except GitError: + sha = "" + + return sha + @contextproperty() def dbt_version(self) -> str: """The `dbt_version` variable returns the installed version of dbt that diff --git a/core/setup.py b/core/setup.py index 5179e5a8fd1..58a6588ff19 100644 --- a/core/setup.py +++ b/core/setup.py @@ -83,6 +83,7 @@ "pytz>=2015.7", "pyyaml>=6.0", "typing-extensions>=3.7.4", + "pygit2 >= 1.0.0", # ---- # Match snowflake-connector-python, to ensure compatibility in dbt-snowflake "cffi>=1.9,<2.0.0", From 1176ae6535d026f879c4378ca8f216d73d4c308d Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Mon, 25 Sep 2023 18:04:13 +0200 Subject: [PATCH 2/6] Handle project_dir config --- core/dbt/context/base.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/core/dbt/context/base.py b/core/dbt/context/base.py index 1b1f21540e1..8fa18b7dde9 100644 --- a/core/dbt/context/base.py +++ b/core/dbt/context/base.py @@ -208,12 +208,18 @@ def to_dict(self) -> Dict[str, Any]: @contextproperty() def git_branch(self) -> str: - """The `git_branch` variable returns the current branch if the + """The `git_branch` variable returns the current branch name if the code is version controlled by git. Otherwise it returns an empty string. """ + + if hasattr(get_flags(), "PROJECT_DIR"): + project_dir = get_flags().PROJECT_DIR + else: + project_dir = "." + try: - branch_name = Repository(".").head.shorthand + branch_name = Repository(project_dir).head.shorthand except GitError: branch_name = "" @@ -225,8 +231,14 @@ def git_sha(self) -> str: if the dbt code is version controlled in git. Otherwise it returns an empty string. """ + + if hasattr(get_flags(), "PROJECT_DIR"): + project_dir = get_flags().PROJECT_DIR + else: + project_dir = "." + try: - repo = Repository(".") + repo = Repository(project_dir) sha = repo.head.target.hex except GitError: sha = "" From 9382fd0394f0762a542b04d0e1a17adc5f580d1a Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Mon, 25 Sep 2023 18:04:45 +0200 Subject: [PATCH 3/6] Add extra context fields for git --- tests/unit/test_context.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unit/test_context.py b/tests/unit/test_context.py index b51e8e76de5..7b39ea3b44c 100644 --- a/tests/unit/test_context.py +++ b/tests/unit/test_context.py @@ -188,6 +188,8 @@ def assert_has_keys(required_keys: Set[str], maybe_keys: Set[str], ctx: Dict[str "print", "diff_of_two_dicts", "local_md5", + "git_branch", + "git_sha", } ) From dae675913379ca57085f616acfbc67616c29fd9f Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Mon, 25 Sep 2023 18:21:05 +0200 Subject: [PATCH 4/6] Add functional test --- tests/functional/context_values/test_git.py | 37 +++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tests/functional/context_values/test_git.py diff --git a/tests/functional/context_values/test_git.py b/tests/functional/context_values/test_git.py new file mode 100644 index 00000000000..7469d5c72e0 --- /dev/null +++ b/tests/functional/context_values/test_git.py @@ -0,0 +1,37 @@ +import os +import subprocess +import pytest + +from dbt.tests.util import run_dbt_and_capture + +# we use a macro to print the value and check the logs when testing +on_run_start_macro_assert_git_branch = """ +{% macro assert_git_branch_name() %} + {{ log("git branch name: " ~ git_branch, 1) }} +{% endmacro %} +""" + + +class TestContextGitValues: + @pytest.fixture(scope="class") + def macros(self): + return { + "assert_git_branch_name.sql": on_run_start_macro_assert_git_branch, + } + + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "on-run-start": "{{ assert_git_branch_name() }}", + } + + def test_git_values(self, project): + os.chdir(project.project_root) + # Initialize a new git repository + subprocess.run(["git", "init"], check=True) + subprocess.run(["git", "checkout", "-b" "new_branch_for_testing"], check=True) + subprocess.run(["git", "add", "*"], check=True) + subprocess.run(["git", "commit", "-m", "commit to git"], check=True) + + _, run_logs = run_dbt_and_capture(["run"]) + assert "git branch name: new_branch_for_testing" in run_logs From f7f689f347f991a1a211998a5cbe5f26a849e878 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Mon, 25 Sep 2023 18:22:52 +0200 Subject: [PATCH 5/6] Changie entry --- .changes/unreleased/Features-20230925-182237.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/unreleased/Features-20230925-182237.yaml diff --git a/.changes/unreleased/Features-20230925-182237.yaml b/.changes/unreleased/Features-20230925-182237.yaml new file mode 100644 index 00000000000..5a6dca5d7de --- /dev/null +++ b/.changes/unreleased/Features-20230925-182237.yaml @@ -0,0 +1,6 @@ +kind: Features +body: Add git_branch and git_sha to the Jinja context +time: 2023-09-25T18:22:37.142445+02:00 +custom: + Author: b-per + Issue: "8690" From ddd4d0d260b198fec312f612b0304fe60ca7ce4b Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Mon, 25 Sep 2023 19:04:26 +0200 Subject: [PATCH 6/6] Update test to remove CI errors --- tests/functional/context_values/test_git.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/functional/context_values/test_git.py b/tests/functional/context_values/test_git.py index 7469d5c72e0..e26123391bc 100644 --- a/tests/functional/context_values/test_git.py +++ b/tests/functional/context_values/test_git.py @@ -29,6 +29,8 @@ def test_git_values(self, project): os.chdir(project.project_root) # Initialize a new git repository subprocess.run(["git", "init"], check=True) + subprocess.run(["git", "config", "user.email", "no-mail@dbtlabs.com"], check=True) + subprocess.run(["git", "config", "user.name", "dbt Labs"], check=True) subprocess.run(["git", "checkout", "-b" "new_branch_for_testing"], check=True) subprocess.run(["git", "add", "*"], check=True) subprocess.run(["git", "commit", "-m", "commit to git"], check=True)