Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environment variables from rc file are not available in command run and skip run #877

Open
pschirch opened this issue Nov 21, 2024 · 5 comments
Labels
bug Something isn't working

Comments

@pschirch
Copy link

🔧 Summary

We use an environment variable based tool stack. So it should be possible to skip specific lefthook commands by configure an environment variable, e.q. SOME_CHECK_ENABLED. We read about rc: in docs and found our use case:

Or if you want to use ENV variables that control the executables behaviour in lefthook.yml

Furthermore, based on the consumption that rc: exports all environment variables from an .env file, it should be possible to use skip from docs to skip a command like:

commands:
  some:check:
    skip:
      - run: test "${SOME_CHECK_ENABLED}" = "false"
    run: ...

I hope my explanations are sufficient. I am grateful for any advice.

Lefthook version

1.8.4

Steps to reproduce

.env

SOME_CHECK_ENABLED=false
SOME_OTHER_CHECK_ENABLED=false

lefthook.rc

. .env

We also test

. "$(cd "$(dirname "$0")" && pwd)/.env"

We had to use "$(cd "$(dirname "$0")" && pwd)/.env" in later mentioned command some-other:check instead of relative . .env to get this working.

and

export SOME_CHECK_ENABLED=false
export SOME_OTHER_CHECK_ENABLED=false

That always should work.

lefthook.yaml

skip_output:
  - meta
  - success
  - skips

min_version: 1.8.4

rc: ./lefthook.rc

some-framework:
  commands:
    some:check:
      skip:
        - run: test "${SOME_CHECK_ENABLED}" = "false"
      run: 'echo SOME_CHECK_ENABLED: enabled'

    some-other:check:
      skip:
        - run: |
            . "$(cd "$(dirname "$0")" && pwd)/.env"
            test "${SOME_OTHER_CHECK_ENABLED}" = "false"
      run: 'echo SOME_OTHER_CHECK_ENABLED: enabled'

We also tried rc: <some_absolute_path>/lefthook.rc

lefthook install --force && lefthook --verbose run some-framework

Expected results

The environment variable SOME_CHECK_ENABLED processed in rc file lefthook.rc should be available in command's some:check skip run to made the skip test.

Furthermore, the command's some:check run should also aware of these environment variables.

Change command some:check run to run: env for a test.

lefthook install --force && lefthook --verbose run some-framework | grep SOME_CHECK_ENABLED

Actual results

The environment variable SOME_CHECK_ENABLED is not available, the skip test fails and the command some:check will be executed.

Possible Solution

Less a solution, more a workaround.

Source . "$(cd "$(dirname "$0")" && pwd)/.env" in skip run every time.

    some-other:check:
      skip:
        - run: |
            . "$(cd "$(dirname "$0")" && pwd)/.env"
            test "${SOME_OTHER_CHECK_ENABLED}" = "false"
      run: 'echo SOME_OTHER_CHECK_ENABLED: enabled'

Logs / Screenshots

sync hooks: ✔️ (some-framework)
│ [lefthook] cmd:    [git rev-parse --path-format=absolute --show-toplevel]
│ [lefthook] stdout: /home/reghas/dev/lefthook-rc-test
                                                    
│ [lefthook] cmd:    [git rev-parse --path-format=absolute --git-path hooks]
│ [lefthook] stdout: /home/reghas/dev/lefthook-rc-test/.git/hooks
                                                               
│ [lefthook] cmd:    [git rev-parse --path-format=absolute --git-path info]
│ [lefthook] stdout: /home/reghas/dev/lefthook-rc-test/.git/info
                                                              
│ [lefthook] cmd:    [git rev-parse --path-format=absolute --git-dir]
│ [lefthook] stdout: /home/reghas/dev/lefthook-rc-test/.git
                                                         
│ [lefthook] cmd:    [git hash-object -t tree /dev/null]
│ [lefthook] stdout: 4b825dc642cb6eb9a060e54bf8d69288fbee4904
                                                           
│ [lefthook] cmd:    [sh -c . "$(cd "$(dirname "$0")" && pwd)/.env"
test "${SOME_OTHER_CHECK_ENABLED}" = "false"                     
]                                                                
│ [lefthook] skip/only cmd: . "$(cd "$(dirname "$0")" && pwd)/.env"
test "${SOME_OTHER_CHECK_ENABLED}" = "false"                     
, result: true                                                   
│ [lefthook] cmd:    [sh -c test "${SOME_CHECK_ENABLED}" = "false"]
│ [lefthook] error:  exit status 1
│ [lefthook] skip/only cmd: test "${SOME_CHECK_ENABLED}" = "false", result: false
┃  some:check ❯ 

SOME_CHECK_ENABLED: enabled

                                      
  ────────────────────────────────────
summary: (done in 0.00 seconds)       
@pschirch pschirch added the bug Something isn't working label Nov 21, 2024
@mrexox
Copy link
Member

mrexox commented Nov 25, 2024

Hey @pschirch ! Does it work when you're running Git hooks? Is it important for you to have this rc file working for non-git hooks? Originally rc option was supposed to be used when you are using git in a IDE or your shell doesn't provide some environment variables required for your hooks.

@pschirch
Copy link
Author

pschirch commented Dec 3, 2024

Hey @mrexox ! Yap, running git hook by IDE triggers rc implementation correctly.

The lefthook.rc must contains the following configuration to work with .env from project root directory.

. "$(cd "$(dirname "$0")" && pwd)/../../.env"

Is it important for you to have this rc file working for non-git hooks?

Yes. We use lefthook as a task runner in our code quality stack and developers can run commands like lefthook run <framework>:(check|fix|test) independet from git lifecycle or staged area to be clear about their work. Sure, it is possible to autoload .env files by some workaround techniques, so lefthook always can work with that environment variables, but they often contains sensitive data, that should only isolated available in the specific running context.

It is possible to extend lefthook rc implementation also be available when running lefthook run ...?

Thank you in advance.

@doniz
Copy link

doniz commented Jan 22, 2025

I have a bit different angle issue but perhaps similar. The environment variables are not extendable by the local configuration. Let's say I have a hook configuration:

# hooks/mylefthook/.lefthook.yaml
---
mylefthook:
  commands:
    test:
      env:
        TEST_ENV: 1.0.0
      run: |
        echo ${TEST_ENV}

and the local configuration:

# .lefthook-local.yaml
---
extends:
  - hooks/mylefthook/.lefthook.yaml
mylefthook:
  commands:
    test:
      env: 
        TEST_ENV: 1.0.1

The command fails:

lefthook run mylefthook --commands test --file main.tf
╭──────────────────────────────────────╮
│ 🥊 lefthook v1.6.7  hook: mylefthook │
╰──────────────────────────────────────╯
┃  test ❯ 

1.0.0

                                      
  ────────────────────────────────────
summary: (done in 0.01 seconds)       
✔️  test

I've tried various methods such as using references or !!merge:

---
test_env: &test_env 1.0.0
mylefthook:
  commands:
    test:
      env:
        TEST_ENV: *test_env
      run: |
        echo ${TEST_ENV}


# .lefthook-local.yaml
extends:
  - hooks/mylefthook/.lefthook.yaml
test_env: 1.0.1

but that way also won't work. My initial goals was to distribute one single environment across all the commands in that single hook/namespace i.e.:

mylefthook:
  # this way I define the global variables and I can use across all my commands in this namespace
  env:
    TEST_ENV: 1.0.0
  commands:
    test:
      run: |
        echo ${TEST_ENV}

# .lefthook-local.yaml
extends:
  - hooks/mylefthook/.lefthook.yaml
mylefthook:
  env:
    TEST_ENV: 1.0.1

@mrexox
Copy link
Member

mrexox commented Jan 23, 2025

@doniz , please update to the latest lefthook (1.10.10). I've changed the parser in 1.9.0, and this must fix the issue

@mrexox
Copy link
Member

mrexox commented Jan 23, 2025

It is possible to extend lefthook rc implementation also be available when running lefthook run ...?

Lefthook wraps each command with a sh -c, but it inherits the environment from the caller (in our case it is git hook script). When calling lefthook run manually and including rc lefthook would have to do something like sh -c "source ${rc}; <command>" and this way the behavior changes.

I'm not ready to change the behavior right now, but I will have it on my radar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants