Skip to content

Commit d7af53e

Browse files
refactor: consolidate install/update scripts, expand CI matrix
- Merge lib/check.sh into lib/utils.sh; remove now-redundant check.sh - Move install-cmake.sh, install-git.sh to scripts/ subdirectory - Drop versions.env; versions are fetched at runtime from GitHub releases - base.sh: install fzf/zoxide/delta/eza via private helpers instead of apt so they pick up latest releases and work on Ubuntu 20.04+ - CI: add Ubuntu 20.04 to test matrix (previously blocked by apt zoxide) - CI: simplify workflow — drop inline verify block, delegate to test.sh - ci: apply curl auth header for all profiles (not workstation-only) - zsh: add DISABLE_MAGIC_FUNCTIONS, restore explicit fzf.zsh source, fix TERM guard to not clobber existing $TERM - tmux: fix config indentation and plugin handling - Add test-local.sh (local CI matrix runner) and clean-test-images.sh - Add .dockerignore to speed up Docker build context - Reformat git/.gitconfig to use consistent indentation
1 parent fd99c1f commit d7af53e

23 files changed

Lines changed: 1388 additions & 789 deletions

.dockerignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Git history — not needed inside the image
2+
.git
3+
4+
# Local dev artifacts — must not pollute the build context or break layer caching
5+
.test-results
6+
test-logs
7+
8+
# Claude Code session data
9+
.claude
10+
11+
# Downloaded install artifacts (gitignored; stale files from old runs)
12+
parallel-*/
13+
*.tar.bz2
14+
*.tar.bz2.sig
15+
*.deb

.github/workflows/install.yml

Lines changed: 6 additions & 203 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@ jobs:
2121
strategy:
2222
fail-fast: false
2323
matrix:
24-
# Ubuntu 20.04 (focal) omitted: 'zoxide' is not in focal's apt repos.
25-
# The install scripts call `apt install zoxide` unconditionally, which
26-
# aborts the install on focal. Fix the scripts first, then add 20.04.
27-
ubuntu: ["22.04", "24.04"]
24+
ubuntu: ["20.04", "22.04", "24.04"]
2825
profile: [docker, minimal, workstation]
2926

3027
steps:
@@ -47,8 +44,7 @@ jobs:
4744
cp -r . /home/testuser/dotfiles
4845
chown -R testuser:testuser /home/testuser/dotfiles
4946
50-
- name: Configure curl auth (workstation — avoids GitHub API rate limit in _install_cheat)
51-
if: matrix.profile == 'workstation'
47+
- name: Configure curl auth (avoids GitHub API rate limit)
5248
run: |
5349
printf 'header = "Authorization: Bearer %s"\n' "${{ secrets.GITHUB_TOKEN }}" \
5450
> /home/testuser/.curlrc
@@ -61,204 +57,11 @@ jobs:
6157
- name: Idempotency — re-run install.sh
6258
run: su -s /bin/bash -c 'HOME=/home/testuser; export HOME; cd ~/dotfiles && bash install.sh ${{ matrix.profile }}' testuser
6359

64-
- name: Verify symlinks
65-
run: |
66-
cat > /tmp/verify_links.sh << 'EOF'
67-
#!/bin/bash
68-
set -euo pipefail
69-
fail=0
70-
check_link() {
71-
if [ -L "$1" ]; then
72-
echo " OK $1 -> $(readlink "$1")"
73-
else
74-
echo " FAIL $1 is not a symlink" >&2
75-
fail=1
76-
fi
77-
}
78-
check_link ~/.zshrc
79-
check_link ~/.tmux.conf
80-
check_link ~/.tmux.conf.local
81-
check_link ~/.gitconfig
82-
check_link ~/.gitattributes
83-
exit $fail
84-
EOF
85-
chmod +x /tmp/verify_links.sh
86-
su -s /bin/bash -c /tmp/verify_links.sh testuser
87-
88-
- name: Verify tools on PATH
89-
run: |
90-
cat > /tmp/verify_tools.sh << 'EOF'
91-
#!/bin/bash
92-
set -euo pipefail
93-
export PATH="$HOME/.local/bin:$PATH"
94-
fail=0
95-
check_cmd() {
96-
if command -v "$1" &>/dev/null; then
97-
echo " OK $1 ($(command -v "$1"))"
98-
else
99-
echo " FAIL $1 not found" >&2
100-
fail=1
101-
fi
102-
}
103-
check_cmd zsh
104-
check_cmd tmux
105-
check_cmd git
106-
check_cmd fzf
107-
check_cmd rg
108-
check_cmd zoxide
109-
exit $fail
110-
EOF
111-
chmod +x /tmp/verify_tools.sh
112-
su -s /bin/bash -c /tmp/verify_tools.sh testuser
113-
114-
- name: Verify minimal-only tools
115-
if: matrix.profile == 'minimal'
116-
run: |
117-
cat > /tmp/verify_minimal.sh << 'EOF'
118-
#!/bin/bash
119-
set -euo pipefail
120-
fail=0
121-
check_cmd() {
122-
if command -v "$1" &>/dev/null; then
123-
echo " OK $1 ($(command -v "$1"))"
124-
else
125-
echo " FAIL $1 not found" >&2
126-
fail=1
127-
fi
128-
}
129-
check_cmd ranger
130-
check_cmd tig
131-
check_cmd parallel
132-
exit $fail
133-
EOF
134-
chmod +x /tmp/verify_minimal.sh
135-
su -s /bin/bash -c /tmp/verify_minimal.sh testuser
136-
137-
- name: Verify workstation-only tools and configs
138-
if: matrix.profile == 'workstation'
139-
run: |
140-
cat > /tmp/verify_workstation.sh << 'EOF'
141-
#!/bin/bash
142-
set -euo pipefail
143-
export PATH="$HOME/.local/bin:$PATH"
144-
fail=0
145-
check_cmd() {
146-
if command -v "$1" &>/dev/null; then
147-
echo " OK $1 ($(command -v "$1"))"
148-
else
149-
echo " FAIL $1 not found" >&2
150-
fail=1
151-
fi
152-
}
153-
check_file() {
154-
if [ -f "$1" ]; then
155-
echo " OK $1"
156-
else
157-
echo " FAIL $1 not found" >&2
158-
fail=1
159-
fi
160-
}
161-
check_link() {
162-
if [ -L "$1" ]; then
163-
echo " OK $1 -> $(readlink "$1")"
164-
else
165-
echo " FAIL $1 is not a symlink" >&2
166-
fail=1
167-
fi
168-
}
169-
check_cmd nvim
170-
check_cmd delta
171-
check_cmd uv
172-
check_cmd cheat
173-
check_link ~/.config/nvim
174-
check_link ~/.config/ripgrep/rc
175-
check_link ~/.config/ranger/rc.conf
176-
check_link ~/.config/ranger/rifle.conf
177-
check_link ~/.config/ranger/scope.sh
178-
exit $fail
179-
EOF
180-
chmod +x /tmp/verify_workstation.sh
181-
su -s /bin/bash -c /tmp/verify_workstation.sh testuser
182-
183-
- name: Verify oh-my-zsh and plugins
184-
run: |
185-
cat > /tmp/verify_zsh.sh << 'EOF'
186-
#!/bin/bash
187-
set -euo pipefail
188-
fail=0
189-
check_dir() {
190-
if [ -d "$1" ]; then
191-
echo " OK $1"
192-
else
193-
echo " FAIL $1 not found" >&2
194-
fail=1
195-
fi
196-
}
197-
if [ -d ~/.oh-my-zsh ]; then
198-
echo " OK ~/.oh-my-zsh"
199-
else
200-
echo " FAIL ~/.oh-my-zsh not found" >&2
201-
fail=1
202-
fi
203-
custom="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}"
204-
check_dir "$custom/plugins/zsh-autosuggestions"
205-
check_dir "$custom/plugins/fast-syntax-highlighting"
206-
check_dir "$custom/plugins/fzf-tab"
207-
check_dir "$custom/themes/powerlevel10k"
208-
exit $fail
209-
EOF
210-
chmod +x /tmp/verify_zsh.sh
211-
su -s /bin/bash -c /tmp/verify_zsh.sh testuser
212-
213-
- name: Smoke-test configs
214-
run: |
215-
cat > /tmp/smoke_test.sh << 'EOF'
216-
#!/bin/bash
217-
set -euo pipefail
218-
export PATH="$HOME/.local/bin:$PATH"
219-
export TERM=xterm-256color # tmux client needs TERM even in detached mode
220-
221-
# zsh: syntax check only — p10k needs a real terminal so we don't source
222-
zsh -n ~/.zshrc && echo " OK ~/.zshrc syntax valid"
223-
224-
# tmux: load config in detached session (no tty required)
225-
tmux -f ~/.tmux.conf new-session -d -s ci_smoke
226-
tmux kill-session -t ci_smoke
227-
echo " OK tmux config loads"
228-
229-
# git: verify our specific config was applied (not just git defaults)
230-
git config --global diff.zip.textconv | grep -q 'unzip' && echo " OK git config: dotfiles settings applied"
231-
232-
# tool versions confirm binaries are functional
233-
zsh --version
234-
tmux -V
235-
rg --version | head -1
236-
fzf --version
237-
zoxide --version
238-
EOF
239-
chmod +x /tmp/smoke_test.sh
240-
su -s /bin/bash -c /tmp/smoke_test.sh testuser
60+
- name: Run test suite
61+
run: su -s /bin/bash -c 'HOME=/home/testuser; export HOME; export TERM=xterm-256color; cd ~/dotfiles && bash test.sh ${{ matrix.profile }}' testuser
24162

24263
- name: Run update.sh
24364
run: su -s /bin/bash -c 'HOME=/home/testuser; export HOME; cd ~/dotfiles && bash update.sh' testuser
24465

245-
- name: Verify tool versions after update
246-
run: |
247-
cat > /tmp/verify_versions.sh << 'EOF'
248-
#!/bin/bash
249-
set -euo pipefail
250-
export PATH="$HOME/.local/bin:$PATH"
251-
echo "── Tool versions after update ──"
252-
fzf --version
253-
rg --version | head -1
254-
fd --version 2>/dev/null || fdfind --version | head -1
255-
shellcheck --version | grep version:
256-
zoxide --version
257-
tmux -V
258-
zsh --version
259-
echo "── fzf shell integration ──"
260-
test -f /usr/share/doc/fzf/examples/key-bindings.zsh && echo " OK key-bindings.zsh present"
261-
test -f /usr/share/doc/fzf/examples/completion.zsh && echo " OK completion.zsh present"
262-
EOF
263-
chmod +x /tmp/verify_versions.sh
264-
su -s /bin/bash -c /tmp/verify_versions.sh testuser
66+
- name: Re-run test suite after update
67+
run: su -s /bin/bash -c 'HOME=/home/testuser; export HOME; export TERM=xterm-256color; cd ~/dotfiles && bash test.sh ${{ matrix.profile }}' testuser

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ parallel-*/
33
*.tar.bz2
44
*.tar.bz2.sig
55
*.deb
6+
7+
# Local test run artifacts
8+
.test-results/

Dockerfile

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
# Test dotfiles install in a clean Ubuntu environment.
22
#
33
# Build & run (installs during build, then drops to shell):
4-
# docker build -t dotfiles-test .
5-
# docker run --rm -it dotfiles-test
4+
# docker build -t dotfiles-test:24.04-docker .
5+
# docker run --rm -it dotfiles-test:24.04-docker
66
#
77
# Choose Ubuntu version or install profile:
8-
# docker build --build-arg UBUNTU=22.04 --build-arg PROFILE=minimal -t dotfiles-test .
9-
# docker build --build-arg PROFILE=workstation -t dotfiles-test .
8+
# docker build --build-arg UBUNTU=22.04 --build-arg PROFILE=minimal -t dotfiles-test:22.04-minimal .
9+
# docker build --build-arg PROFILE=workstation -t dotfiles-test:24.04-workstation .
1010
#
1111
# Iterative mode — mount live source, skip the build-time install:
12-
# docker run --rm -it -v "$PWD":/root/dotfiles dotfiles-test bash
12+
# docker build --build-arg PROFILE=docker -t dotfiles-test:24.04-docker .
13+
# docker run --rm -it -v "$PWD":/root/dotfiles dotfiles-test:24.04-docker bash
1314
# # then inside: cd ~/dotfiles && bash install.sh docker
1415

1516
ARG UBUNTU=24.04

0 commit comments

Comments
 (0)