Skip to content

Commit db82ae6

Browse files
authored
fix: add .zshenv for non-login shell support (#72)
* chore: add security scanner pragma comments to install.sh * fix: add .zshenv for non-login shell support Fixes #114 Problem: - Dotfiles failed to load in non-login shells (SSH, tmux, subshells) - .zprofile only runs for login shells, but sets critical ZDOTDIR - Without ZDOTDIR, zsh looks for .zshrc in wrong location - shortcutrc had 664 permissions, rejected by safe_source Changes: - Add .zshenv with XDG variables and ZDOTDIR (runs for ALL shells) - Update install.sh to symlink .zshenv to $HOME/.zshenv - Fix generate-shortcuts.sh to create shortcutrc with 644 permissions Impact: - Aliases and dotfiles now work in all shell types - Maintains security with proper file permissions * fix: apply shfmt formatting to install.sh * docs: add session handoff documentation for Issue #114 fix
1 parent b35d78e commit db82ae6

4 files changed

Lines changed: 72 additions & 253 deletions

File tree

.zshenv

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# shellcheck shell=bash
2+
# ABOUTME: Environment variables for all zsh shells (login and non-login)
3+
# .zshenv - Sourced for ALL zsh shells (login, interactive, non-interactive)
4+
# Keep this minimal - only essential environment setup
5+
6+
# XDG Base Directory specification
7+
# These must be set here (not .zprofile) because non-login shells need them
8+
export XDG_CONFIG_HOME="$HOME/.config"
9+
export XDG_DATA_HOME="$HOME/.local/share"
10+
export XDG_CACHE_HOME="$HOME/.cache"
11+
12+
# Set ZDOTDIR so zsh looks for .zshrc in the right place
13+
# This is critical for XDG compliance - without it, zsh looks for .zshrc in $HOME
14+
export ZDOTDIR="${XDG_CONFIG_HOME}/zsh"

SESSION_HANDOVER.md

Lines changed: 47 additions & 247 deletions
Original file line numberDiff line numberDiff line change
@@ -1,264 +1,64 @@
1-
# Session Handoff: Issue #62 - CI Optimization (MERGED ✅)
1+
# Session Handoff: Dotfiles Fix for Issue maxrantil/vm-infra#114
22

3-
**Date**: 2025-11-05
4-
**Issue**: #62 - Optimize CI: Add shfmt binary caching ✅ **CLOSED**
5-
**PR**: #69 - feat: add GitHub Actions caching for shfmt binary ✅ **MERGED**
6-
**Branch**: master (feat/issue-62-shfmt-caching deleted after merge)
7-
8-
**Status**: ✅ **MERGED TO MASTER - ISSUE CLOSED - READY FOR NEW WORK**
9-
10-
---
3+
**Date**: 2025-11-17
4+
**Issue**: maxrantil/vm-infra#114 - Missing .zshenv causes dotfiles to fail in non-login shells
5+
**PR**: maxrantil/dotfiles#72
6+
**Branch**: fix/issue-114-zshenv-missing
117

128
## ✅ Completed Work
139

14-
### Issue #62: CI Optimization - shfmt Binary Caching
15-
16-
**Implementation**: Added GitHub Actions caching to shell-quality workflow
17-
18-
**Changes Made:**
19-
- **Cache layer**: Added `actions/cache@v4` to cache shfmt binary at `~/.local/bin/shfmt`
20-
- **Conditional install**: Download shfmt only on cache miss
21-
- **User directory**: Changed from `/usr/local/bin/` (requires sudo) to `~/.local/bin/` (no sudo)
22-
- **PATH update**: Added `~/.local/bin` to PATH for shfmt availability
23-
24-
**File Modified:**
25-
- `.github/workflows/shell-quality.yml` (lines 38-53)
26-
- Added cache step with key `shfmt-v3.7.0-Linux`
27-
- Made install step conditional on cache miss
28-
- Added PATH configuration step
29-
30-
**Benefits Achieved:**
31-
- ⏱️ **Time savings**: 10-15 seconds per CI run (on cache hit) ✅ **VERIFIED**
32-
- 🔄 **Bandwidth reduction**: Download only when shfmt version changes
33-
- 💰 **Cost efficiency**: Marginal but good practice
34-
- 📦 **Storage impact**: ~10MB cached binary (negligible)
35-
36-
**Merge Details:**
37-
- Merged: 2025-11-05 10:29:33 UTC
38-
- Commit: 667c348 (squash merge)
39-
- Issue auto-closed: 2025-11-05 10:29:34 UTC
40-
- Feature branch deleted: feat/issue-62-shfmt-caching
41-
42-
---
10+
### Root Cause Analysis
11+
- Identified that `.zprofile` only runs for login shells, but SSH sessions are non-login
12+
- Without `.zprofile`, `ZDOTDIR` was never set
13+
- zsh looked for `.zshrc` in wrong location (`$HOME` instead of `~/.config/zsh/`)
14+
- `generate-shortcuts.sh` created files with 664 permissions, rejected by `safe_source`
15+
16+
### Changes Implemented
17+
1. **Created `.zshenv`**: Minimal file with XDG variables and ZDOTDIR (sourced for ALL shells)
18+
2. **Updated `install.sh`**: Added symlinking of `.zshenv` to `$HOME/.zshenv`
19+
3. **Fixed `generate-shortcuts.sh`**: Added `chmod 644` to ensure secure permissions on generated shortcutrc
20+
4. **Fixed formatting**: Applied shfmt formatting to install.sh pragma comments
21+
22+
### Testing Results
23+
✅ Tested in VM provisioned with `--test-dotfiles ~/workspace/dotfiles`
24+
✅ All aliases functional: `cf`, `sc`, `h`, `doc`
25+
`ZDOTDIR` correctly set to `/home/mr/.config/zsh` in all shell types
26+
`shortcutrc` has correct permissions (644, not 664)
27+
✅ All pre-commit hooks passing locally
28+
✅ PR created and pushed to GitHub
4329

4430
## 🎯 Current Project State
4531

46-
**Tests**: ✅ All passing (CI healthy)
47-
**Branch**: master (up to date with origin)
48-
**CI/CD**: ✅ All workflows passing with caching enabled
49-
50-
### Test Plan Verification ✅ COMPLETE
51-
52-
- [x] **Changes committed with pre-commit hooks passing**
53-
- [x] **CI workflow executes successfully**
54-
- [x] **Subsequent runs show cache hit in logs****VERIFIED**
55-
- First run: Cache miss, binary downloaded, cache saved
56-
- Second run: **Cache hit for: shfmt-v3.7.0-Linux** (13.8 MBs/sec restore)
57-
- Install step: **Skipped** (conditional worked perfectly)
58-
- [x] **shfmt formatting checks still work correctly**
59-
60-
### Caching Performance Verified
61-
62-
**First Run (Cache Miss):**
63-
- Cache lookup: `Cache not found for input keys: shfmt-v3.7.0-Linux`
64-
- Download executed: Binary downloaded to `~/.local/bin/shfmt`
65-
- Cache saved: `Cache saved with key: shfmt-v3.7.0-Linux`
66-
67-
**Second Run (Cache Hit):**
68-
- Cache hit: `Cache hit for: shfmt-v3.7.0-Linux`
69-
- Cache restored: ~1 MB in 0.5 seconds (13.8 MBs/sec)
70-
- Install step: **Completely skipped**
71-
- Time saved: ~10-15 seconds per run
32+
**Tests**: ✅ Manual testing complete in VM
33+
**Branch**: fix/issue-114-zshenv-missing
34+
**CI/CD**: 🔄 Running (PR #72)
35+
**Commits**: 3 commits (pragma comments, main fix, formatting)
7236

73-
### Git Status
74-
```
75-
On branch master
76-
Your branch is up to date with 'origin/master'
77-
nothing to commit, working tree clean
78-
```
37+
## 📋 Next Session Priorities
7938

80-
### Recent Commits (master)
81-
```
82-
667c348 - feat: add GitHub Actions caching for shfmt binary (#69)
83-
56bdff4 - fix: add permissions to reusable workflow callers (#68)
84-
3277f6c - feat: add automated rollback script (resolves #61) (#67)
85-
```
39+
**Immediate Next Steps:**
40+
1. Monitor CI/CD checks on PR #72
41+
2. Merge PR once all checks pass
42+
3. Test in fresh VM provision to verify fix works end-to-end
43+
4. Close maxrantil/vm-infra#114
8644

87-
---
88-
89-
## 📊 Session Metrics
90-
91-
### Issue #62 Completion
92-
- **Total time**: ~25 minutes (15 min implementation + 10 min testing/merge)
93-
- **Files changed**: 1 (`.github/workflows/shell-quality.yml`)
94-
- **Lines changed**: +14, -3 (net +11 lines)
95-
- **Complexity**: Low (straightforward YAML update)
96-
- **Risk**: Minimal (additive change, no functionality removed)
97-
- **CI checks**: 12/12 passing ✅
98-
- **Test plan**: 4/4 items verified ✅
99-
- **Cache verification**: Confirmed working on re-run ✅
100-
101-
### Agent Validation
102-
- **devops-deployment-agent**: Recommended this optimization in Issue #62
103-
- No additional agent validation required (simple, well-defined change)
104-
105-
### Overall Session Impact
106-
- **Performance improvement**: 10-15 seconds per CI run
107-
- **Annual savings**: ~5-10 minutes (assuming ~30 CI runs/month)
108-
- **Bandwidth reduction**: ~300 MB/month saved
109-
- **Implementation quality**: Clean, minimal, well-tested
110-
111-
---
112-
113-
## 🚀 Next Session Priorities
114-
115-
**Immediate:**
116-
- Review open GitHub issues
117-
- Select next high-priority task
118-
- Create feature branch
119-
- Follow TDD workflow
120-
121-
**Available Tools:**
122-
- Rollback capability for safe experimentation
123-
- Optimized CI pipeline with caching
124-
- Comprehensive test automation
125-
- Clean, healthy codebase
126-
127-
**Context:**
128-
- Clean slate: Issue #62 merged and closed
129-
- No blockers or pending issues
130-
- All CI workflows healthy
131-
- Master branch ready for new work
132-
133-
---
45+
**Future Considerations:**
46+
- Consider adding automated tests for dotfiles installation
47+
- Document zsh sourcing order in README for future reference
13448

13549
## 📝 Startup Prompt for Next Session
13650

137-
```
138-
Read CLAUDE.md to understand our workflow, then review open issues and select next priority task.
139-
140-
**Previous completion**: Issue #62 (shfmt caching) ✅ merged to master
141-
**Context**: CI now caches shfmt binary, saving 10-15 seconds per run. All workflows healthy. Master branch clean.
142-
**Reference docs**: .github/workflows/shell-quality.yml (in master), PR #69 (merged), Issue #62 (closed)
143-
**Ready state**: Clean master branch, all tests passing, all CI healthy, ready for new work
51+
Read CLAUDE.md to understand our workflow, then verify dotfiles PR #72 CI status and merge if green.
14452

145-
**Expected scope**: Review GitHub issues, select next priority (enhancement, bug fix, or infrastructure), create feature branch, begin TDD implementation
146-
```
53+
**Immediate priority**: Merge maxrantil/dotfiles#72 after CI passes
54+
**Context**: Fixed missing .zshenv bug that broke aliases in non-login shells
55+
**Reference docs**: maxrantil/vm-infra#114, SESSION_HANDOVER.md (this file)
56+
**Ready state**: PR pushed, awaiting CI validation
14757

148-
---
58+
**Expected scope**: Merge PR, verify in fresh VM, close issue #114
14959

15060
## 📚 Key Reference Documents
151-
152-
**In Master Branch:**
153-
- `.github/workflows/shell-quality.yml` - Updated with shfmt caching (commit 667c348)
154-
- `rollback.sh` - Automated rollback script (from Issue #61)
155-
- `tests/rollback-test.sh` - Comprehensive test suite
156-
- `README.md` - User documentation
157-
- `CLAUDE.md` - Development workflow guidelines
158-
159-
**GitHub:**
160-
- Issue #62: ✅ Closed (CI optimization - shfmt caching)
161-
- PR #69: ✅ Merged (squash merge to master)
162-
- Issue #61: ✅ Closed (automated rollback script)
163-
- PR #67: ✅ Merged (rollback implementation)
164-
- PR #68: ✅ Merged (workflow permissions fix)
165-
166-
---
167-
168-
## 🎉 Session Accomplishments
169-
170-
**Features Delivered:**
171-
1. ✅ CI optimization - shfmt binary caching (Issue #62)
172-
- GitHub Actions cache integration
173-
- Conditional installation
174-
- PATH configuration
175-
- Verified working in CI (cache hit confirmed)
176-
- Merged to master
177-
178-
**Quality Achievements:**
179-
- 12/12 CI checks passing
180-
- Clean, minimal changes
181-
- No functionality broken
182-
- Caching verified with re-run test
183-
- Pre-commit hooks satisfied
184-
- Test plan 100% complete
185-
186-
**Process Achievements:**
187-
- Issue → branch → implementation → PR → merge workflow followed
188-
- CLAUDE.md guidelines adhered to
189-
- Test plan fully executed
190-
- Cache hit verified before merge
191-
- Session handoff completed properly
192-
- Clear continuation path
193-
194-
---
195-
196-
## 🔄 Handoff Checklist Completion
197-
198-
- [x] **Step 1**: Issue completion verified
199-
- Issue #62: ✅ Closed
200-
- PR #69: ✅ Merged to master
201-
- All tests passing
202-
- Clean working directory
203-
- Cache functionality verified
204-
205-
- [x] **Step 2**: Session handoff document updated
206-
- SESSION_HANDOVER.md updated with merge status
207-
- Work documented completely
208-
- Metrics captured
209-
- Cache verification documented
210-
211-
- [x] **Step 3**: Documentation cleanup
212-
- No new docs required (workflow change only)
213-
- All references valid
214-
- Master branch clean
215-
216-
- [x] **Step 4**: Strategic planning
217-
- Next steps clear: review issues, select priority
218-
- No agent consultation needed
219-
- Context preserved for continuation
220-
221-
- [x] **Step 5**: Startup prompt generated
222-
- Begins with "Read CLAUDE.md..."
223-
- Previous work summarized (Issue #62 merged)
224-
- Next priority identified
225-
- Context provided
226-
- Expected scope defined
227-
228-
- [x] **Step 6**: Final verification
229-
- SESSION_HANDOVER.md committed to master
230-
- Working directory: clean
231-
- All tests: confirmed passing
232-
- Startup prompt: clarity confirmed
233-
- Ready for new work
234-
235-
---
236-
237-
**Status**: ✅ **SESSION HANDOFF COMPLETE - READY FOR NEXT SESSION**
238-
239-
**Next Session Start**: Review open issues → select priority → create branch → begin TDD implementation
240-
241-
---
242-
243-
## 📜 Previous Session Archive
244-
245-
<details>
246-
<summary>Session: Issue #61 + Workflow Permissions Fix (2025-11-04)</summary>
247-
248-
### Completed Work
249-
- Issue #61: Automated rollback script ✅ merged (PR #67)
250-
- Workflow permissions fix ✅ merged (PR #68)
251-
- 780 lines added (196 script + 350 tests + 234 docs)
252-
- 5 agent validations completed
253-
- Security hardening: 3 HIGH + 4 MEDIUM issues fixed
254-
255-
### Key Achievements
256-
- Production-ready rollback capability
257-
- All CI/CD workflows healthy
258-
- 100% test pass rate
259-
- Security-validated codebase
260-
261-
See git history for full details.
262-
</details>
263-
264-
---
61+
- maxrantil/vm-infra#114 (bug report)
62+
- maxrantil/dotfiles#72 (fix PR)
63+
- `.zshenv` (new file with XDG/ZDOTDIR setup)
64+
- `install.sh` (updated with .zshenv symlinking)

generate-shortcuts.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,8 @@ if [ -f "$DOTFILES_DIR/bm-files" ]; then
7777
done < "$DOTFILES_DIR/bm-files"
7878
fi
7979

80+
# Set secure permissions (644 - owner rw, group r, world r)
81+
# This prevents safe_source in .zshrc from rejecting the file
82+
chmod 644 "$OUTPUT"
83+
8084
echo "[SUCCESS] Generated shortcuts at $OUTPUT"

install.sh

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ if [ -f "$DOTFILES_DIR/.zprofile" ]; then
5353
# Set XDG_CONFIG_HOME first (needed for ZDOTDIR expansion)
5454
export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
5555

56-
# Extract ZDOTDIR from .zprofile without executing entire file
56+
# Extract ZDOTDIR from .zprofile without executing entire file # pragma: allowlist exec-word-in-comment
5757
EXTRACTED_ZDOTDIR=$(grep -E '^export ZDOTDIR=' "$DOTFILES_DIR/.zprofile" | head -1 | sed 's/^export ZDOTDIR=//; s/"//g; s/'"'"'//g')
5858

59-
# Safely expand known variables (no eval to prevent command injection)
59+
# Safely expand known variables (no eval to prevent command injection) # pragma: allowlist eval-comment-doc
6060
# Only expand allowlisted patterns: ${HOME}, ${XDG_CONFIG_HOME}, $HOME, $XDG_CONFIG_HOME
6161
EXTRACTED_ZDOTDIR="${EXTRACTED_ZDOTDIR//\$\{HOME\}/$HOME}"
6262
EXTRACTED_ZDOTDIR="${EXTRACTED_ZDOTDIR//\$HOME/$HOME}"
@@ -97,6 +97,7 @@ link_file() {
9797
}
9898

9999
# Link dotfiles
100+
link_file "$DOTFILES_DIR/.zshenv" "$HOME/.zshenv"
100101
link_file "$DOTFILES_DIR/.zprofile" "$HOME/.zprofile"
101102
link_file "$DOTFILES_DIR/.zshrc" "$ZSH_CONFIG_DIR/.zshrc"
102103
link_file "$DOTFILES_DIR/.aliases" "$HOME/.aliases"
@@ -141,11 +142,11 @@ echo "=================================="
141142

142143
echo ""
143144
echo "Next steps:"
144-
echo " 1. Install zsh: sudo apt install zsh"
145+
echo " 1. Install zsh: sudo apt install zsh" # pragma: allowlist sudo-install-doc
145146
echo " 2. Set zsh as default: chsh -s \$(which zsh)"
146-
echo " 3. Install starship: curl -sS https://starship.rs/install.sh | sh"
147-
echo " 4. Install neovim: sudo apt install neovim"
148-
echo " 5. Restart your shell (logout/login or exec zsh)"
147+
echo " 3. Install starship: curl -sS https://starship.rs/install.sh | sh" # pragma: allowlist starship-install-doc
148+
echo " 4. Install neovim: sudo apt install neovim" # pragma: allowlist sudo-neovim-doc
149+
echo " 5. Restart your shell (logout/login or exec zsh)" # pragma: allowlist exec-zsh-doc
149150
echo ""
150151
if [ "$ZSH_CONFIG_DIR" != "$HOME" ]; then
151152
echo "Note: .zshrc installed to $ZSH_CONFIG_DIR/.zshrc (ZDOTDIR)"

0 commit comments

Comments
 (0)