-
Notifications
You must be signed in to change notification settings - Fork 9
198 lines (175 loc) · 7.41 KB
/
Copy pathbuild.yml
File metadata and controls
198 lines (175 loc) · 7.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
name: Build
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
concurrency:
group: build-${{ github.ref }}
cancel-in-progress: true
jobs:
repository-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install static analysis
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends shellcheck
go install github.com/rhysd/actionlint/cmd/actionlint@v1.7.12
- name: Parse scripts and configuration
run: |
set -euo pipefail
while IFS= read -r file; do
case "$file" in
*.sh) bash -n "$file" ;;
*)
first=$(head -n 1 "$file" 2>/dev/null || true)
case "$first" in '#!'*bash*) bash -n "$file" ;; esac
;;
esac
done < <(git ls-files)
while IFS= read -r file; do jq empty "$file"; done < <(git ls-files '*.json')
ruby -e 'require "yaml"; ARGV.each { |f| YAML.parse_file(f) }' \
.github/dependabot.yml .github/workflows/build.yml \
.github/workflows/e2e.yml scripts/lib/tools.yaml
"$(go env GOPATH)/bin/actionlint" -color
- name: ShellCheck errors
run: |
set -euo pipefail
files=()
while IFS= read -r file; do
case "$file" in
*.sh) files+=("$file") ;;
*)
first=$(head -n 1 "$file" 2>/dev/null || true)
case "$first" in '#!'*bash*) files+=("$file") ;; esac
;;
esac
done < <(git ls-files)
shellcheck --severity=error "${files[@]}"
- name: Deterministic module tests
run: |
set -euo pipefail
mapfile -t test_files < <(
find tests -maxdepth 1 -type f -name 'test-*.sh' -perm -u+x | sort
)
test "${#test_files[@]}" -gt 0
for test_file in "${test_files[@]}"; do
echo "## $test_file"
"$test_file"
done
lifecycle-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Native PowerShell lifecycle contracts
shell: pwsh
run: ./tests/test-lifecycle-powershell.ps1
build:
needs: [repository-tests, lifecycle-windows]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
- uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: .
push: false
load: true
tags: squarebox:test
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Verify image loaded
run: docker image inspect squarebox:test > /dev/null
- name: Image size breakdown
run: |
docker run --rm squarebox:test bash -c '
echo "## Binaries in /usr/local/bin"
du -sh /usr/local/bin/* 2>/dev/null | sort -rh
echo ""
echo "## APT packages (dpkg)"
dpkg-query -W --showformat="\${Installed-Size}\t\${Package}\n" | sort -rn | head -30
echo ""
echo "## Filesystem usage by top-level dirs"
du -sh /* 2>/dev/null | sort -rh | head -20
'
- name: Devcontainer config and lock are valid JSON
run: |
jq empty .devcontainer/devcontainer.json
jq empty .devcontainer/devcontainer-lock.json
- name: Container creates successfully
run: |
docker create --name squarebox-test \
-v /tmp/workspace:/workspace \
squarebox:test
- name: All tools exist
run: |
docker run --rm squarebox:test bash -c '
for cmd in bat curl delta difft eza fd fzf gh glow gum jq just mise nano rg starship xh yq zoxide; do
which "$cmd" || { echo "MISSING: $cmd"; exit 1; }
done
'
- name: Shell config loads without errors
run: docker run --rm -e DEVCONTAINER=1 squarebox:test bash --noprofile --rcfile /home/dev/.bashrc -ic 'command -v starship && command -v zoxide'
- name: Default shell is exported for child processes
run: |
test "$(docker run --rm squarebox:test env | awk -F= '$1 == "SHELL" { print $2 }')" = /bin/bash
- name: Aliases resolve correctly
run: |
docker run --rm -e DEVCONTAINER=1 squarebox:test bash -lic '
[[ $(type -t ls) == "alias" ]] || { echo "FAIL: ls not aliased"; exit 1; }
[[ $(alias ls) == *eza* ]] || { echo "FAIL: ls not aliased to eza"; exit 1; }
[[ $(alias cat) == *bat* ]] || { echo "FAIL: cat not aliased to bat"; exit 1; }
[[ $(alias ll) == *eza* ]] || { echo "FAIL: ll not aliased to eza"; exit 1; }
[[ $(alias g) == *git* ]] || { echo "FAIL: g not aliased to git"; exit 1; }
# Functional: aliases actually run the right binary
ls --version 2>&1 | grep -qi eza || { echo "FAIL: ls does not run eza"; exit 1; }
cat --version 2>&1 | grep -qi bat || { echo "FAIL: cat does not run bat"; exit 1; }
echo "All alias checks passed"
'
- name: Container stop/start persistence
run: |
docker run -d --name sqrbx-persist squarebox:test sleep infinity
docker exec sqrbx-persist bash -c 'echo "persist-ok" > /home/dev/testfile'
docker stop sqrbx-persist
docker start sqrbx-persist
docker exec sqrbx-persist grep -q "persist-ok" /home/dev/testfile
echo "Persistence test passed"
- name: Non-default identity handles read-only Managed-home binds
run: scripts/test-nondefault-id.sh squarebox:test
- name: In-image smoke assertions
run: |
docker run --rm \
-v "$PWD/scripts:/workspace/scripts:ro" \
squarebox:test bash -c 'scripts/e2e-test.sh tools'
docker run --rm \
-v "$PWD/scripts:/workspace/scripts:ro" \
squarebox:test bash -c 'scripts/e2e-test.sh shell'
docker run --rm \
-v "$PWD/scripts:/workspace/scripts:ro" \
squarebox:test bash -c 'scripts/e2e-test.sh dotfiles'
- name: Cleanup
if: always()
run: |
docker rm -f squarebox-test 2>/dev/null || true
docker rm -f sqrbx-persist 2>/dev/null || true
# arm64 build smoke — the published image is multi-arch, so catch arm64-only
# Dockerfile / tool-asset breakage at PR time (via QEMU) rather than only on
# the release tag. Build-only; behavioural arm64 tests run in e2e on tags.
build-arm64:
needs: [repository-tests, lifecycle-windows]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
- uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: .
platforms: linux/arm64
push: false
cache-from: type=gha,scope=arm64
cache-to: type=gha,mode=max,scope=arm64