Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
fb2fc6a
feat: simplify external module storage and add module management comm…
hinriksnaer Jan 2, 2026
0248488
fix(module): require nodejs module for npm packages like cargo
hinriksnaer Jan 2, 2026
eb211c2
feat(rpm): add nodejs as required dependency
hinriksnaer Jan 2, 2026
46b26ba
fix(module): fail properly when cargo not found
hinriksnaer Jan 2, 2026
7438473
feat(rpm): add rust and cargo as required dependencies
hinriksnaer Jan 2, 2026
31c5672
feat(ssh): check stable socket before starting new agent
hinriksnaer Jan 4, 2026
3b03d1b
fix(ssh): use correct exit codes for ssh-add agent detection
hinriksnaer Jan 4, 2026
2491c98
feat(ssh): add fish config for stable SSH agent socket
hinriksnaer Jan 4, 2026
547ee7e
docs: update for release - remove ssh-clusters, add source commands
hinriksnaer Jan 5, 2026
8648f1b
fix(ssh): create stable socket symlink when starting new agent
hinriksnaer Jan 5, 2026
96f4a4f
fix(ssh): validate stable socket is responsive before using it
hinriksnaer Jan 5, 2026
633b9ba
fix(spec): prevent .config directory from being owned by root
hinriksnaer Jan 11, 2026
6072c2d
Merge main into unstable: sync upstream changes
hinriksnaer Jan 13, 2026
c7a0210
feat(profile): preserve git URLs in fedpunk.yaml for declarative conf…
hinriksnaer Jan 13, 2026
f347391
fix(config): use clean environment for yq to avoid shell pollution (#50)
hinriksnaer Jan 13, 2026
8fc11b5
fix(yq): apply clean environment wrapper across all yq calls
hinriksnaer Jan 14, 2026
d3ad440
fix(env): write environment configs to system-wide locations
hinriksnaer Jan 15, 2026
f29f6af
fix(env): write environment configs to user-level locations
hinriksnaer Jan 15, 2026
fd220cd
fix(deploy): generate env config after module deployment
hinriksnaer Jan 15, 2026
f092c99
fix(config): prevent duplicate modules in fedpunk.yaml
hinriksnaer Jan 15, 2026
17eaccc
fix(module-resolver): source paths.fish for FEDPUNK_USER/FEDPUNK_SYSTEM
hinriksnaer Jan 15, 2026
9540e7c
fix(config): prevent duplicate modules from profile's mode.yaml
hinriksnaer Mar 6, 2026
f2b116a
Merge branch 'main' into unstable
hinriksnaer Mar 6, 2026
ddda02d
docs(readme): rewrite intro to emphasize end-to-end orchestration
hinriksnaer Mar 13, 2026
c89cd44
docs(readme): add Configuration section with fedpunk.yaml details
hinriksnaer Mar 13, 2026
c45ccfb
docs(readme): remove incorrect root-level params field
hinriksnaer Mar 13, 2026
7af2eaf
Merge docs/readme-update: README improvements
hinriksnaer Mar 13, 2026
add83f5
fix: remove hardcoded theme symlink from core
hinriksnaer Mar 13, 2026
ce9c632
refactor: reorganize test directory structure
hinriksnaer Mar 13, 2026
94d6770
feat(config): restructure profile config with name, source, and mode
hinriksnaer Mar 13, 2026
9533080
fix(test): build from source directory, not git
hinriksnaer Mar 13, 2026
85e0cda
docs(readme): use https URLs instead of git@
hinriksnaer Mar 13, 2026
a8e768e
fix(config): fix variable scoping in profile getter functions
hinriksnaer Mar 13, 2026
13745cc
fix(config): never overwrite existing config on fresh install
hinriksnaer Mar 13, 2026
e1a4a9b
test(env): add test for module environment variable injection
hinriksnaer Mar 13, 2026
c2cd18d
docs: document environment variable injection in module.yaml
hinriksnaer Mar 13, 2026
183c992
docs(readme): remove ssh module references
hinriksnaer Mar 13, 2026
f91bfad
docs: remove fedpunk-minimal references (doesn't exist)
hinriksnaer Mar 13, 2026
e03a2e4
docs(readme): expand profiles section and directory structure
hinriksnaer Mar 13, 2026
e48a0c7
test(params): add test for module parameter injection
hinriksnaer Mar 13, 2026
4ba3b07
docs: restore ssh module references
hinriksnaer Mar 13, 2026
e9c5b09
docs(readme): add Module CLI and TUI support sections
hinriksnaer Mar 13, 2026
7a71528
fix(params): inject default parameter values from module.yaml
hinriksnaer Mar 13, 2026
6a52eed
docs(readme): simplify custom modules, reference template repo
hinriksnaer Mar 13, 2026
55d3fcc
feat: add module-template as submodule in examples/
hinriksnaer Mar 13, 2026
73def6e
chore: configure module-template submodule to track main branch
hinriksnaer Mar 13, 2026
d04361c
fix: update docs for minimal core architecture
hinriksnaer Mar 13, 2026
2868b3f
test: add comprehensive CI tests for advanced features
hinriksnaer Mar 13, 2026
e20f17d
test: add comprehensive test suite with parallel CI
hinriksnaer Mar 13, 2026
cecaab6
fix(test): use stow instead of deploy in E2E test
hinriksnaer Mar 14, 2026
6d77041
fix(test): fix test-profile-git-urls.sh path and config format
hinriksnaer Mar 14, 2026
6ef75a0
chore: remove MIGRATION.md
hinriksnaer Mar 14, 2026
33ae391
docs: add CHANGELOG.md
hinriksnaer Mar 14, 2026
790b252
fix: remove DEBUG output from module deployment
hinriksnaer Mar 14, 2026
597c21b
test: verify shells actually load environment variables
hinriksnaer Mar 14, 2026
881d407
feat: auto-load module env vars in all shells via /etc/profile.d
hinriksnaer Mar 19, 2026
9707521
test: add regression test for external module duplicate entry bug
hinriksnaer Mar 19, 2026
4253e6e
fix: prevent duplicate module entries when deploying external modules…
hinriksnaer Mar 19, 2026
ddbf2ba
test: add regression test for login vs non-login shell env vars
hinriksnaer Mar 19, 2026
b02b2e2
Merge branch 'main' into unstable - resolve test conflict
hinriksnaer Mar 19, 2026
f0d32a9
fix: convert relative paths to absolute when storing module references
hinriksnaer Mar 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions lib/fish/deployer.fish
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,26 @@ function deployer-deploy-module
fedpunk-config-init
end

# Normalize git URLs to module names for consistent config storage
# git@gitlab.com:org/thinkpad-fans.git -> thinkpad-fans
set -l module_name "$module_ref"
if module-ref-is-url "$module_ref"
# Extract repo name from URL (same logic as external-module-get-storage-path)
set module_name (string replace -r '\.git$' '' "$module_ref")
set module_name (string replace -r '^.*[/:]' '' "$module_name")
# Normalize module reference before storing
# - URLs: Keep as-is (fixes duplicate entry bug)
# - Paths: Convert to absolute (fixes relative path resolution)
# - Names: Keep as-is
set -l config_ref "$module_ref"

# Check if it's a path (contains / but not a URL)
if string match -q '*/*' "$module_ref"; and not module-ref-is-url "$module_ref"
# It's a path - convert to absolute
set -l expanded_path (string replace -r '^~' "$HOME" "$module_ref")

# If not already absolute, make it absolute relative to PWD
if not string match -q '/*' "$expanded_path"
set expanded_path (realpath "$expanded_path" 2>/dev/null; or echo "$PWD/$expanded_path")
end

set config_ref "$expanded_path"
end

# Add normalized module name to config
fedpunk-config-add-module "$module_name"
fedpunk-config-add-module "$config_ref"

# Use existing fedpunk-module deploy (already handles local + git)
if fedpunk-module deploy "$module_ref"
Expand Down
192 changes: 192 additions & 0 deletions test/ci/test-env-login-vs-nonlogin-shells.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
#!/bin/bash
# Regression test for env vars only available in login shells
#
# This test reproduces the issue where:
# 1. User deploys a module with environment variables
# 2. Env vars are NOT available in current shell
# 3. Env vars are NOT available in new non-login shell (bash from bash)
# 4. Env vars ARE available in new login shell (ssh, new terminal)
#
# Expected behavior: Env vars should be available everywhere
# Current behavior: Only in login shells (bug)

set -e

echo ""
echo "========================================="
echo "Login vs Non-Login Shell Env Test"
echo "========================================="
echo "Reproducing the 'had to run bash again' bug"
echo ""

# Setup test environment
TEST_DIR=$(mktemp -d -t fedpunk-shell-test-XXXXXX)
trap "rm -rf $TEST_DIR" EXIT

echo "Test environment: $TEST_DIR"
echo ""

# Override HOME for isolated testing
export HOME="$TEST_DIR/home"
mkdir -p "$HOME/.config/fedpunk/profile.d"
mkdir -p "$TEST_DIR/etc/profile.d"

# Simulate module deployment generating env config
# Use unique var name to avoid pollution from current shell
UNIQUE_VAR="FEDPUNK_TEST_$$_$(date +%s)"
cat > "$HOME/.config/fedpunk/profile.d/fedpunk-env.sh" <<EOF
#!/bin/sh
# Auto-generated by fedpunk - DO NOT EDIT
export ${UNIQUE_VAR}="deployed_value"
export FEDPUNK_TEST_API="https://api.test.com"
EOF

echo "Simulated module deployment - generated env config at:"
echo " $HOME/.config/fedpunk/profile.d/fedpunk-env.sh"
echo ""

# Simulate system /etc/profile.d/fedpunk.sh
cat > "$TEST_DIR/etc/profile.d/fedpunk.sh" <<'EOF'
#!/bin/sh
# Fedpunk environment variables
export FEDPUNK_SYSTEM=/usr/share/fedpunk
export FEDPUNK_USER=$HOME/.local/share/fedpunk

# Auto-load user module environment variables
if [ -f "$HOME/.config/fedpunk/profile.d/fedpunk-env.sh" ]; then
. "$HOME/.config/fedpunk/profile.d/fedpunk-env.sh"
fi
EOF

echo "Created simulated /etc/profile.d/fedpunk.sh"
echo ""

#
# Test 1: Current shell does NOT have env vars (expected)
#
echo "=== Test 1: Current shell after deployment ==="
echo "This simulates: user just ran 'fedpunk module deploy'"
echo ""

if [ -z "$FEDPUNK_TEST_API" ]; then
echo " βœ“ EXPECTED: FEDPUNK_TEST_API not set in current shell"
echo " (User would need to manually source the config)"
else
echo " βœ— UNEXPECTED: FEDPUNK_TEST_API is set: $FEDPUNK_TEST_API"
fi

echo ""

#
# Test 2: Non-login shell does NOT have env vars (BUG)
#
echo "=== Test 2: New non-login shell (bash from bash) ==="
echo "This simulates: user runs 'bash' from their current bash shell"
echo ""

# Non-login interactive shell (like running 'bash' from bash)
NONLOGIN_VALUE=$(bash -c "
export HOME='$HOME'
echo \$FEDPUNK_TEST_API
")

if [ -z "$NONLOGIN_VALUE" ]; then
echo " ❌ BUG REPRODUCED: FEDPUNK_TEST_API not set in non-login shell"
echo " /etc/profile.d/ is NOT sourced for non-login shells"
echo " This is the bug the user experienced!"
BUG_REPRODUCED=1
else
echo " βœ“ UNEXPECTED: FEDPUNK_TEST_API is set: $NONLOGIN_VALUE"
echo " (Test environment might be different from real world)"
fi

echo ""

#
# Test 3: Login shell HAS env vars (works but requires new login)
#
echo "=== Test 3: New login shell (ssh, new terminal) ==="
echo "This simulates: user SSH'ing into container or opening new terminal"
echo ""

# Login shell (sources /etc/profile which sources /etc/profile.d/*)
LOGIN_VALUE=$(bash --login -c "
export HOME='$HOME'
# Manually source profile.d to simulate login shell behavior
. '$TEST_DIR/etc/profile.d/fedpunk.sh'
echo \$FEDPUNK_TEST_API
")

if [ "$LOGIN_VALUE" = "https://api.test.com" ]; then
echo " βœ“ WORKS: FEDPUNK_TEST_API set in login shell"
echo " Value: $LOGIN_VALUE"
echo " But user had to start a NEW login shell to get it!"
else
echo " βœ— FAIL: FEDPUNK_TEST_API not set even in login shell"
echo " Expected: 1"
echo " Got: $LOGIN_VALUE"
exit 1
fi

echo ""

#
# Test 4: User's workaround - running 'bash' might create login shell
#
echo "=== Test 4: User's workaround behavior ==="
echo "When user ran 'bash' again, they might have gotten lucky with:"
echo " - Container configuration that forces login shells"
echo " - .bashrc that sources /etc/profile"
echo " - bash --login being their default"
echo ""

# Try various bash invocations
echo "Testing different bash invocations:"

# Standard non-login
STANDARD=$(bash -c "export HOME='$HOME'; echo \$FEDPUNK_TEST_API")
echo " bash -c: '$STANDARD' (empty = not set)"

# Interactive non-login
INTERACTIVE=$(bash --init-file /dev/null -i -c "export HOME='$HOME'; echo \$FEDPUNK_TEST_API" 2>/dev/null || echo "")
echo " bash -i: '$INTERACTIVE' (empty = not set)"

# Login shell
LOGIN=$(bash --login -c "export HOME='$HOME'; . '$TEST_DIR/etc/profile.d/fedpunk.sh'; echo \$FEDPUNK_TEST_API")
echo " bash --login: '$LOGIN' (should be 'https://api.test.com')"

echo ""

#
# Summary
#
echo "========================================="
if [ -n "$BUG_REPRODUCED" ]; then
echo "BUG REPRODUCED!"
else
echo "Bug not reproduced (environment differs)"
fi
echo "========================================="
echo ""
echo "Issue Summary:"
echo " ❌ Current shell: Env vars NOT available after deployment"
echo " ❌ Non-login shell (bash from bash): Env vars NOT available"
echo " βœ… Login shell (new terminal/ssh): Env vars available"
echo ""
echo "Real-world impact:"
echo " - User deploys module"
echo " - Tries to use env vars β†’ NOT AVAILABLE"
echo " - Runs 'bash' β†’ STILL NOT AVAILABLE (unless login shell)"
echo " - Has to start new terminal/ssh β†’ Finally available"
echo ""
echo "Root cause:"
echo " /etc/profile.d/ only sourced for LOGIN shells, not:"
echo " - Current shell (where deployment happens)"
echo " - Non-login interactive shells (bash from bash)"
echo " - Subshells"
echo ""
echo "Solutions needed:"
echo " 1. Source config in current shell during deployment"
echo " 2. Add to /etc/bash.bashrc for non-login interactive shells"
echo " 3. Add to /etc/zshrc for zsh"
echo ""
12 changes: 5 additions & 7 deletions test/ci/test-external-module-params-no-duplicate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,14 @@ echo ""
#
# Test 2: Simulate the bug scenario - deployer-deploy-module with params
#
echo "=== Test 2: Simulate deployer-deploy-module bug scenario ==="
echo "=== Test 2: Deploy module with parameters (testing fix) ==="

# Initialize config
run_fish "fedpunk-config-init" 2>&1 || true

# Simulate the buggy behavior:
# Step 1: deployer-deploy-module adds NORMALIZED NAME (line 58)
NORMALIZED_NAME="test-params-ext-module"
run_fish "fedpunk-config-add-module '$NORMALIZED_NAME'" 2>&1 || true
echo " Step 1: Added normalized name to config: $NORMALIZED_NAME"
# Step 1: deployer-deploy-module adds module URL (FIXED behavior)
run_fish "fedpunk-config-add-module '$TEST_MODULE_URL'" 2>&1 || true
echo " Step 1: Added module URL to config: $TEST_MODULE_URL"

# Step 2: param-save-to-config tries to find using URL (not name)
# This is what happens when fedpunk-module deploy calls param-prompt-required
Expand All @@ -131,7 +129,7 @@ param-save-to-config '$TEST_MODULE_URL' 'auth_mode' 'enabled'
" 2>&1 || true

echo " Step 2: Saved params using URL: $TEST_MODULE_URL"
echo " (This is where the duplicate gets created if bug exists)"
echo " (Should update existing entry, not create duplicate)"
echo ""

#
Expand Down
Loading
Loading