Conversation
Allow setting environment variables at the hook level via `env` in hk.pkl. Hook-level env vars are merged into each step, with step-level env taking precedence. This fixes the python-project.pkl example which already used this syntax. Closes #706 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request enhances the configuration system by enabling the definition of environment variables directly at the hook level. This provides greater flexibility and simplifies the management of environment-specific settings for hook execution, while also ensuring proper precedence rules when combined with step-level environment variables. The change addresses a previous limitation and improves the overall robustness of hook configurations. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request adds support for defining environment variables at the hook level, which are then inherited by the steps within that hook. The implementation is solid, with changes to the Pkl configuration, the Rust Hook struct, and the initialization logic. The new functionality is also well-tested with new integration tests. I have one suggestion to refactor the logic for merging environment variables to improve code clarity and remove duplication.
| if !self.env.is_empty() { | ||
| match step_or_group { | ||
| StepOrGroup::Step(step) => { | ||
| for (key, value) in &self.env { | ||
| step.env.entry(key.clone()).or_insert_with(|| value.clone()); | ||
| } | ||
| } | ||
| StepOrGroup::Group(group) => { | ||
| for step in group.steps.values_mut() { | ||
| for (key, value) in &self.env { | ||
| step.env.entry(key.clone()).or_insert_with(|| value.clone()); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
There's some code duplication in how hook-level environment variables are merged into steps and groups. You can refactor this to be more DRY and slightly more efficient by using a trait object to get an iterator over the steps, regardless of whether it's a single step or a group. This avoids creating an intermediate Vec and keeps the merging logic in one place.
if !self.env.is_empty() {
let steps_iter: Box<dyn Iterator<Item = &mut crate::step::Step>> = match step_or_group {
StepOrGroup::Step(step) => Box::new(std::iter::once(step.as_mut())),
StepOrGroup::Group(group) => Box::new(group.steps.values_mut()),
};
for step in steps_iter {
for (key, value) in &self.env {
step.env.entry(key.clone()).or_insert_with(|| value.clone());
}
}
}
Greptile SummaryAdded hook-level environment variable support to allow setting environment variables at the hook level that are inherited by all steps within that hook. The implementation correctly handles precedence where step-level env vars override hook-level ones using Confidence Score: 5/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Hook with env vars] --> B{StepOrGroup?}
B -->|Step| C[Merge hook env into step.env]
B -->|Group| D[Iterate through group.steps]
D --> C
C --> E{Key exists in step.env?}
E -->|Yes| F[Keep step-level value<br/>step takes precedence]
E -->|No| G[Add hook-level value]
F --> H[Step executes with merged env]
G --> H
Last reviewed commit: 9dce10a |
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [hk](https://github.com/jdx/hk) | minor | `1.36.0` → `1.38.0` | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>jdx/hk (hk)</summary> ### [`v1.38.0`](https://github.com/jdx/hk/blob/HEAD/CHANGELOG.md#1380---2026-03-06) [Compare Source](jdx/hk@v1.37.0...v1.38.0) ##### 🚀 Features - **(hook)** add `fail_on_fix` option by [@​jdx](https://github.com/jdx) in [#​725](jdx/hk#725) ##### 🐛 Bug Fixes - **(builtins)** remove redundant check/check\_diff from builtins by [@​nkakouros](https://github.com/nkakouros) in [#​726](jdx/hk#726) ##### 📦️ Dependency Updates - update anthropics/claude-code-action digest to [`26ec041`](jdx/hk@26ec041) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​720](jdx/hk#720) - update jdx/mise-action digest to [`e79ddf6`](jdx/hk@e79ddf6) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​721](jdx/hk#721) - update actions-rust-lang/setup-rust-toolchain digest to [`a0b538f`](jdx/hk@a0b538f) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​719](jdx/hk#719) - update rust crate tokio to v1.50.0 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​722](jdx/hk#722) ### [`v1.37.0`](https://github.com/jdx/hk/blob/HEAD/CHANGELOG.md#1370---2026-03-03) [Compare Source](jdx/hk@v1.36.0...v1.37.0) ##### 🚀 Features - **(hook)** add env support to hooks by [@​jdx](https://github.com/jdx) in [#​709](jdx/hk#709) - parse Go-style diffs by [@​jdx](https://github.com/jdx) in [#​704](jdx/hk#704) ##### 🐛 Bug Fixes - **(builtins)** strip extra trailing newlines in end-of-file-fixer by [@​jdx](https://github.com/jdx) in [#​708](jdx/hk#708) - **(docs)** correctly document what --all is about by [@​nkakouros](https://github.com/nkakouros) in [#​715](jdx/hk#715) - **(git)** exclude untracked files from unstaged\_files set by [@​nkakouros](https://github.com/nkakouros) in [#​716](jdx/hk#716) - **(hkrc)** config format and load order by [@​ivy](https://github.com/ivy) in [#​710](jdx/hk#710) - **(release)** write release notes to file instead of capturing stdout by [@​jdx](https://github.com/jdx) in [#​688](jdx/hk#688) - **(release)** make release notes editorialization non-blocking by [@​jdx](https://github.com/jdx) in [#​690](jdx/hk#690) - **(step)** gate check\_diff forced check\_first on Fix mode only by [@​nkakouros](https://github.com/nkakouros) in [#​717](jdx/hk#717) ##### 📚 Documentation - **(shanty)** add audio player with sea shanty recording by [@​jdx](https://github.com/jdx) in [67a25ad](jdx/hk@67a25ad) - document config file search paths by [@​ivy](https://github.com/ivy) in [#​701](jdx/hk#701) - require AI disclosure on GitHub comments by [@​jdx](https://github.com/jdx) in [#​703](jdx/hk#703) ##### 🔍 Other Changes - replace gen-release-notes script with communique by [@​jdx](https://github.com/jdx) in [#​700](jdx/hk#700) - add autofix.ci workflow by [@​jdx](https://github.com/jdx) in [#​705](jdx/hk#705) ##### 📦️ Dependency Updates - lock file maintenance by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​686](jdx/hk#686) - update taiki-e/upload-rust-binary-action digest to [`f391289`](jdx/hk@f391289) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​692](jdx/hk#692) - update anthropics/claude-code-action digest to [`c22f7c3`](jdx/hk@c22f7c3) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​691](jdx/hk#691) - update rust crate libc to v0.2.181 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​694](jdx/hk#694) - update rust crate clap to v4.5.58 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​693](jdx/hk#693) - lock file maintenance by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​695](jdx/hk#695) - update anthropics/claude-code-action digest to [`edd85d6`](jdx/hk@edd85d6) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​698](jdx/hk#698) - update rust crate clap to v4.5.60 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​699](jdx/hk#699) - lock file maintenance by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​702](jdx/hk#702) - lock file maintenance by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​711](jdx/hk#711) ##### New Contributors - [@​ivy](https://github.com/ivy) made their first contribution in [#​710](jdx/hk#710) - [@​nkakouros](https://github.com/nkakouros) made their first contribution in [#​715](jdx/hk#715) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My40OS4wIiwidXBkYXRlZEluVmVyIjoiNDMuNTcuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90IiwiYXV0b21hdGlvbjpib3QtYXV0aG9yZWQiLCJkZXBlbmRlbmN5LXR5cGU6Om1pbm9yIl19-->
Summary
envproperty to theHookclass inConfig.pkland the RustHookstructdocs/public/python-project.pklexample which already usedenvon a hook but gotCannot find property 'env' in object of type 'hk.Config#Hook'Closes #706
Test plan
test/hook_env.batswith 3 tests covering:🤖 Generated with Claude Code
Note
Medium Risk
Changes how step environments are constructed by merging new hook-level
envinto every step at init time, which can alter runtime behavior for existing configs that start usinghooks.<name>.env. Default is empty so unaffected hooks should behave the same.Overview
Adds a new
envfield toHookinConfig.pkland the RustHookstruct, allowing environment variables to be defined once per hook.During
Hook::init, hook-levelenvis merged into eachStep(and into each step inside aGroup), with step-levelenvtaking precedence.Introduces
test/hook_env.batsto validate propagation, precedence, and that hook env does not leak across hooks.Written by Cursor Bugbot for commit 9dce10a. This will update automatically on new commits. Configure here.