Skip to content

Pass through env variables#53

Merged
Pajn merged 3 commits into
mainfrom
env-variables
May 21, 2026
Merged

Pass through env variables#53
Pajn merged 3 commits into
mainfrom
env-variables

Conversation

@Pajn
Copy link
Copy Markdown
Owner

@Pajn Pajn commented May 21, 2026

Stack

Summary by CodeRabbit

  • Chores

    • Updated Rust toolchain to 1.95.0 and refreshed CI workflow configurations.
  • Bug Fixes

    • Improved environment variable handling for git editor operations during continue commands.
  • Refactor

    • Simplified internal control-flow patterns and added test infrastructure utilities.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

📝 Walkthrough

Walkthrough

This PR standardizes the Rust build toolchain across CI, release, and local environments, enhances the continue command to properly forward editor environment variables to git rebase, adds test infrastructure for consistent git command setup, and includes a minor loop refactoring in stack section removal.

Changes

Rust Toolchain and Git Environment Propagation

Layer / File(s) Summary
Rust toolchain standardization
rust-toolchain.toml, .github/workflows/ci.yml, .github/workflows/release.yml
Pins Rust to channel 1.95.0 with clippy and rustfmt components, and updates CI/release workflows from dtolnay/rust-toolchain@stable to actions-rust-lang/setup-rust-toolchain@v1 with explicit rustflags="".
Continue command with environment forwarding
src/commands/continue_cmd.rs
Refactors git rebase --continue invocation to inherit all environment variables, set GIT_EDITOR from EDITOR or VISUAL when unset, and properly forward editor preferences to git.
Test infrastructure for git command environments
tests/common/mod.rs, tests/move_tests.rs, tests/reorder_tests.rs
Introduces git_command helper that constructs git commands with test author/committer environment variables, adds integration test validating kin continue with editor environment, and migrates existing tests to use the helper.
Minor control-flow refactoring
src/commands/pr.rs
Simplifies stack section removal loop from loop { ... else { break } } to while let Some(...) = ... pattern.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Pajn/Kindra#35: Modifies src/commands/pr.rs stack-section parsing logic including remove_existing_stack_section, which is also refactored in this PR's loop control-flow change.
  • Pajn/Kindra#44: Modifies src/commands/continue_cmd.rs continue_cmd() routing logic; this PR extends it with environment variable forwarding to git rebase.

Poem

🐰 A toolchain unified, rustflags tidy and neat,
Environments forwarded where continue commands meet,
Test helpers assembled for reproducible grace,
Loops made while-let-ful, control flow in place! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Pass through env variables' directly describes the primary objective of the PR, which involves passing environment variables through to child processes (particularly in git operations and tests).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Base automatically changed from completions to abort May 21, 2026 07:27
Base automatically changed from abort to main May 21, 2026 14:15
@Pajn Pajn force-pushed the env-variables branch from 7b8559a to e233e41 Compare May 21, 2026 14:38
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release.yml:
- Around line 40-43: The setup step using
actions-rust-lang/setup-rust-toolchain@v1 currently enables the default cache;
to force release isolation disable caching by adding the cache input set to
false for that action (update the step that references uses:
actions-rust-lang/setup-rust-toolchain@v1 and its with: block), so the workflow
will not restore ~/.cargo or target/ during tag-triggered releases and will
ensure a clean build environment.

In `@tests/move_tests.rs`:
- Around line 299-360: The test currently covers only the EDITOR branch in
test_move_continue_forwards_editor_env_to_git; add two additional assertions (or
separate tests) to cover the VISUAL fallback and the "do not override existing
GIT_EDITOR" behavior by invoking the same flow that triggers continue_cmd: (1)
run kin_cmd().arg("continue") with env("VISUAL","true") and assert success and
the same rebase/move result as the EDITOR case, and (2) set
env("GIT_EDITOR","preexisting") plus env("EDITOR","true") (or VISUAL) before
running kin_cmd().arg("continue") and assert the command succeeds and that
GIT_EDITOR remains "preexisting" (or at least that the behavior uses the
existing GIT_EDITOR rather than replacing it). Locate changes around the
existing test function name test_move_continue_forwards_editor_env_to_git,
kin_cmd() invocations, and the continue_cmd logic to implement these assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 45ea330c-c961-4f75-9e5f-588b6a76b24e

📥 Commits

Reviewing files that changed from the base of the PR and between b1a65fe and ece959e.

📒 Files selected for processing (8)
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • rust-toolchain.toml
  • src/commands/continue_cmd.rs
  • src/commands/pr.rs
  • tests/common/mod.rs
  • tests/move_tests.rs
  • tests/reorder_tests.rs

Comment on lines +40 to +43
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
targets: ${{ matrix.target }}
target: ${{ matrix.target }}
rustflags: ""
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

actions-rust-lang/setup-rust-toolchain default cache input behavior

💡 Result:

The actions-rust-lang/setup-rust-toolchain GitHub Action provides built-in support for caching Rust dependencies and toolchain artifacts [1][2]. Its default behavior regarding caching is controlled by the cache input, which is enabled by default [1][2]. Key details regarding the cache input behavior include: Default State: The cache input defaults to true, meaning the action will automatically attempt to configure Rust caching when used in a workflow [1][2]. Underlying Mechanism: The action leverages the Swatinem/rust-cache action to perform the actual caching operations [1][2]. Additional Caching Controls: - cache-on-failure: Defaults to true, determining whether the cache is saved even if the job fails [1][2]. - cache-bin: Defaults to true, which propagates the cache-bin setting to the underlying Swatinem/rust-cache [1][2]. - cache-provider: Defaults to 'github', specifying the caching service used [1][2]. - cache-all-crates and cache-workspace-crates: Both default to false [1][2]. Because this action propagates many of its caching inputs to Swatinem/rust-cache, users can further refine behavior using inputs like cache-directories, cache-key, and cache-shared-key if specific customization is required for complex monorepo or workspace setups [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=".github/workflows/release.yml"
echo "== File: $FILE =="
wc -l "$FILE"

echo
echo "== Lines 1-120 =="
nl -ba "$FILE" | sed -n '1,120p'

echo
echo "== Lines around 30-80 =="
nl -ba "$FILE" | sed -n '30,90p'

Repository: Pajn/Kindra

Length of output: 211


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=".github/workflows/release.yml"
echo "== File: $FILE =="
wc -l "$FILE"

echo
echo "== Matches for triggers/releases =="
rg -n --hidden --no-messages -S "on:|tags:|github\.com|release|upload|action-gh-release|upload-release-asset|softprops" "$FILE" || true

echo
echo "== Lines 1-80 =="
cat -n "$FILE" | sed -n '1,80p'

echo
echo "== Lines 80-110 =="
cat -n "$FILE" | sed -n '80,110p'

Repository: Pajn/Kindra

Length of output: 4023


🌐 Web query:

Swatinem/rust-cache default cached directories target directory and cache key contents

💡 Result:

The Swatinem/rust-cache GitHub Action is designed to speed up Rust builds by caching critical Cargo directories and build artifacts [1][2]. Default Cached Directories By default, the action caches the following locations [1][3]: - ~/.cargo: This includes the cargo registry (downloaded crates), git dependencies, installed binaries, and the cargo cache [1][3][2]. -./target: This directory contains compiled build artifacts for your project [1][3][2]. The./target directory is cached by default, but this can be toggled using the cache-targets input [1][4]. Furthermore, you can define specific Cargo workspace mappings using the workspaces input, which follows the format $workspace -> $target (defaulting to. -> target if not specified) [1][4]. Cache Key Contents The cache key is automatically generated to ensure builds are only restored when the environment is compatible [5]. By default, this generated key includes [5]: - A hash of all Cargo.lock and Cargo.toml files found in the repository [5]. - A hash of all rust-toolchain or rust-toolchain.toml files in the root directory [5]. - A hash of all.cargo/config.toml files in the root directory [5]. - Values from specific compiler-related environment variables (e.g., RUSTFLAGS) [5]. - Optionally, the job ID, if add-job-id-key is set to true (default is true) [5]. You can control these behaviors via parameters like add-rust-environment-hash-key and prefix-key to customize how or when the cache is invalidated or reused [5].

Citations:


🌐 Web query:

rust-cache caches target correctness cargo rebuild fingerprints stale artifacts

💡 Result:

Cargo’s rebuild correctness (i.e., whether stale artifacts can be reused) is driven by two things: (1) unit fingerprints that encode “what should be rebuilt”, and (2) filesystem mtime checks against per-unit “dep-info” files under target/.fingerprint. 1) What Cargo stores to decide if an artifact is up to date - Cargo computes a Fingerprint (a hash) for each compilation “Unit” and saves it on disk in a.fingerprint directory; if the fingerprint is missing, or if any fingerprint fields change, the Unit is considered dirty and will rebuild [1][2][3]. - The fingerprint includes information about the unit’s dependencies so that if an upstream crate changes, downstream units become dirty and will rebuild as well [1][3]. 2) How Cargo detects “stale” vs “fresh” on the filesystem - Cargo’s documentation explains the core mechanism: it compares the mtime of a Unit’s source/input files against the mtime of the unit’s dep-info file in the fingerprint directory; if input files are missing or newer than the dep-info, the unit is dirty [2]. - The fingerprint implementation also records whether produced output files are present and whether dependencies’ outputs are newer; if any dependency is newer, the unit is stale, and if output files are missing, the unit is stale [2]. - The source code comments describe how mtime equality is treated conservatively: Cargo considers equal mtimes “stale” to avoid missing changes on filesystems with low timestamp precision (e.g., 1s). It also discusses edge cases where kernel time caching can cause very small updates to not be detected reliably, and the equality check is intended as a conservative approximation to mitigate that [4]. 3) “Target correctness”: what this means for stale artifacts In practice, “stale artifacts in target/” are prevented because Cargo: - Won’t reuse a compiled unit if it has no prior fingerprint state or if relevant fingerprint inputs changed (source, flags, compiler version, etc.) [1][3]. - Won’t reuse it if filesystem checks determine inputs/dependencies are newer than the recorded dep-info anchor, or if expected outputs are missing [2]. - Propagates dirtiness through dependency fingerprints so that a rebuild upstream forces downstream recompilation [1][3]. 4) Rebuild fingerprints vs. “content-based” fingerprints - Cargo’s current approach is mtime-based for filesystem freshness checks (as described above) rather than always hashing file contents. - There is historical discussion/issue material about possibly switching to content-based fingerprinting (digesting files) instead of mtime, but it’s noted that mtime was chosen partly to avoid race conditions around file changes during the build [5]. If you want, tell me which workflow you’re worried about (e.g., switching branches, network filesystems/mtime precision, using incremental compilation, CI cache restore, or running parallel builds), and I can map the risk to the specific fingerprint/mtime checks above and suggest mitigation commands/config.

Citations:


Downgrade cache-poisoning concern to defense-in-depth; consider disabling cache for release isolation.

actions-rust-lang/setup-rust-toolchain@v1 defaults to cache: true (via Swatinem/rust-cache), which restores ~/.cargo and target. Since this workflow builds with cargo build --locked, Cargo’s fingerprint/dep-info + mtime checks should prevent stale target/ from being reused for different sources/inputs, so this is unlikely to “silently” change release artifacts. If you still want stricter isolation/repro hardening on tag-triggered releases, disable the cache here.

🔒 Proposed fix
       - name: Set up Rust
         uses: actions-rust-lang/setup-rust-toolchain@v1
         with:
           target: ${{ matrix.target }}
           rustflags: ""
+          cache: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
targets: ${{ matrix.target }}
target: ${{ matrix.target }}
rustflags: ""
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
target: ${{ matrix.target }}
rustflags: ""
cache: false
🧰 Tools
🪛 zizmor (1.25.2)

[error] 40-40: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 40-40: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default

(cache-poisoning)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 40 - 43, The setup step using
actions-rust-lang/setup-rust-toolchain@v1 currently enables the default cache;
to force release isolation disable caching by adding the cache input set to
false for that action (update the step that references uses:
actions-rust-lang/setup-rust-toolchain@v1 and its with: block), so the workflow
will not restore ~/.cargo or target/ during tag-triggered releases and will
ensure a clean build environment.

Comment thread tests/move_tests.rs
Comment on lines +299 to +360
#[test]
fn test_move_continue_forwards_editor_env_to_git() {
let dir = tempdir().unwrap();
let repo = repo_init(dir.path());

let base_id = make_commit(&repo, "refs/heads/main", "file.txt", "base", "initial", &[]);
let base = repo.find_commit(base_id).unwrap();

let target_id = make_commit(
&repo,
"refs/heads/target",
"file.txt",
"target content",
"target commit",
&[&base],
);

let feature_id = make_commit(
&repo,
"refs/heads/feature",
"file.txt",
"feature content",
"feature commit",
&[&base],
);
let feature = repo.find_commit(feature_id).unwrap();

repo.set_head("refs/heads/feature").unwrap();
repo.checkout_tree(
feature.as_object(),
Some(git2::build::CheckoutBuilder::new().force()),
)
.unwrap();

kin_cmd()
.arg("move")
.arg("--onto")
.arg("target")
.current_dir(dir.path())
.assert()
.failure()
.stderr(predicates::str::contains("Resolve conflicts"));

fs::write(dir.path().join("file.txt"), "resolved content").unwrap();
run_ok("git", &["add", "file.txt"], dir.path());

kin_cmd()
.arg("continue")
.current_dir(dir.path())
.env("EDITOR", "true")
.assert()
.success();

let feature_new = repo
.find_branch("feature", git2::BranchType::Local)
.unwrap();
let target = repo.find_commit(target_id).unwrap();
assert!(
repo.graph_descendant_of(feature_new.get().target().unwrap(), target.id())
.unwrap()
);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add integration coverage for the remaining editor-env branches.

This test validates EDITOR, but the new continue_cmd logic also includes VISUAL fallback and “don’t override existing GIT_EDITOR”. Please add cases for both branches to lock in behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/move_tests.rs` around lines 299 - 360, The test currently covers only
the EDITOR branch in test_move_continue_forwards_editor_env_to_git; add two
additional assertions (or separate tests) to cover the VISUAL fallback and the
"do not override existing GIT_EDITOR" behavior by invoking the same flow that
triggers continue_cmd: (1) run kin_cmd().arg("continue") with
env("VISUAL","true") and assert success and the same rebase/move result as the
EDITOR case, and (2) set env("GIT_EDITOR","preexisting") plus
env("EDITOR","true") (or VISUAL) before running kin_cmd().arg("continue") and
assert the command succeeds and that GIT_EDITOR remains "preexisting" (or at
least that the behavior uses the existing GIT_EDITOR rather than replacing it).
Locate changes around the existing test function name
test_move_continue_forwards_editor_env_to_git, kin_cmd() invocations, and the
continue_cmd logic to implement these assertions.

@Pajn Pajn merged commit cb41092 into main May 21, 2026
2 checks passed
@Pajn Pajn deleted the env-variables branch May 21, 2026 16:10
@coderabbitai coderabbitai Bot mentioned this pull request May 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant