Skip to content

Commit cf9305d

Browse files
Adds an integration test workflow
Allow image caching to succeed despite the test results Thus we can fail on tests due broken code while a good image previously downloaded is retained for faster iterations.
1 parent f83e4df commit cf9305d

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed

.github/workflows/integration.yaml

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
name: Integration tests
2+
on:
3+
pull_request:
4+
workflow_dispatch:
5+
push:
6+
branches: ["main"]
7+
env:
8+
# TODO: Transform this into a matrix
9+
base_url: https://cdimages.ubuntu.com/ubuntu-wsl/daily-live/current
10+
image_name: questing-wsl-amd64.wsl
11+
images_dir: images
12+
instance: Ubuntu-${{ github.run_id }}
13+
profile_script: /etc/profile.d/99-quit-wsl.sh
14+
jobs:
15+
build-deb:
16+
name: Build wsl-setup debian package
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Check out repository
20+
uses: actions/checkout@v5
21+
- name: Build deb
22+
uses: canonical/desktop-engineering/gh-actions/common/build-debian@main
23+
with:
24+
token: ${{ secrets.GITHUB_TOKEN }}
25+
docker-image: ubuntu:devel
26+
cache-img:
27+
name: Cache the daily-live image
28+
runs-on: ubuntu-latest
29+
outputs:
30+
cache-key: ${{ steps.compute-cache-key.outputs.cache-key }}
31+
steps:
32+
- name: Compute image cache key
33+
id: compute-cache-key
34+
shell: bash
35+
run: |
36+
set -eu
37+
38+
shafile="SHA256SUMS"
39+
uri="${{ env.base_url }}/${shafile}"
40+
curl -o "$shafile" "${uri}"
41+
if [ $? -ne 0 ]; then
42+
echo "::error:: Failed to download the checksum file from $uri."
43+
exit 1
44+
fi
45+
46+
# If a line matches, then awk extracts the first field: the checksum.
47+
key=$(grep -E "^[a-f0-9]+ \*${{ env.image_name }}$" "$shafile" | awk '{print $1}')
48+
if [ -z "$key" ]; then
49+
echo "::error:: Checksum for '${{ env.image_name }}' not found in the $shafile file."
50+
exit 2
51+
fi
52+
echo "cache-key=$key" >> "$GITHUB_OUTPUT"
53+
- name: Check image cache first
54+
id: cache
55+
uses: actions/cache@v4
56+
with:
57+
path: ${{ env.images_dir }}
58+
key: ${{ steps.compute-cache-key.outputs.cache-key }}
59+
enableCrossOsArchive: true
60+
- name: Download a daily-live image
61+
if: steps.cache.outputs.cache-hit != 'true'
62+
shell: bash
63+
run: |
64+
set -eu
65+
66+
mkdir -p "${{ env.images_dir }}"
67+
curl -o "${{ env.images_dir }}/${{ env.image_name }}" "${{ env.base_url }}/${{ env.image_name }}"
68+
if [ $? -ne 0 ]; then
69+
echo "::error:: Failed to download the image from ${{ env.base_url }}/${{ env.image_name }}'."
70+
exit 1
71+
fi
72+
test-wsl-setup:
73+
needs: [build-deb, cache-img]
74+
name: "Integration tests"
75+
runs-on: windows-2025 # WSL and winget are preinstalled and working
76+
steps:
77+
- name: Download artifacts
78+
uses: actions/download-artifact@v5
79+
with:
80+
path: ci-artifacts
81+
# name: is left blank so that all artifacts are downloaded, thus we don't couple on
82+
# whatever name was chosen in the build-debian action.
83+
- name: Fetch the image from cache
84+
id: cache
85+
uses: actions/cache@v4
86+
with:
87+
path: ${{ env.images_dir }}
88+
key: ${{ needs.cache-img.outputs.cache-key }}
89+
restore-keys: |
90+
${{ needs.cache-img.outputs.cache-key }}
91+
enableCrossOsArchive: true
92+
- name: "Set up a WSL instance from the daily image"
93+
shell: powershell
94+
env:
95+
WSL_UTF8: "1" # Recommended otherwise it's hard to read wsl output on Github
96+
# Just to skip the interactive session
97+
cloudinit: |
98+
#cloud-config
99+
users:
100+
- name: u
101+
gecos: Ubuntu User
102+
groups: [adm,dialout,cdrom,floppy,sudo,audio,dip,video,plugdev,netdev]
103+
sudo: ALL=(ALL) NOPASSWD:ALL
104+
shell: /bin/bash
105+
write_files:
106+
- path: /etc/wsl.conf
107+
append: true
108+
content: |
109+
[user]
110+
default=u
111+
exit 0
112+
packages: [hello]
113+
run: |
114+
# No launch so we can install the deb before running the OOBE
115+
wsl --install --no-launch --from-file "./${{ env.images_dir }}/${{ env.image_name }}" --name "${{ env.instance }}"
116+
wsl -d "${{ env.instance }}" -u root -- ls -l "./ci-artifacts/wsl-setup_*/"
117+
wsl -d "${{ env.instance }}" -u root -- dpkg -i "./ci-artifacts/wsl-setup_*/wsl-setup_*.deb"
118+
119+
# In case cloud-init fails we don't get stuck on endless prompting.
120+
wsl -d "${{ env.instance }}" -u root -- adduser --quiet --gecos '' --disabled-password ubuntu
121+
wsl -d "${{ env.instance }}" -u root -- usermod ubuntu -aG "adm,cdrom,sudo,dip,plugdev"
122+
wsl -d "${{ env.instance }}" -u root -- cloud-init status --wait
123+
wsl -d "${{ env.instance }}" -u root -- bash -ec "rm /etc/cloud/cloud-init.disabled || true"
124+
wsl -d "${{ env.instance }}" -u root -- bash -ec 'printf "#!/bin/bash\necho Exiting because the profile says so\nexit 0\n" > ${{ env.profile_script }}'
125+
wsl -d "${{ env.instance }}" -u root -- chmod '0777' ${{ env.profile_script }}
126+
wsl -d "${{ env.instance }}" -u root -- cloud-init clean --logs
127+
wsl --shutdown
128+
129+
# Write the cloud-init user-data contents.
130+
$cloudinitdir = New-Item -ItemType "Directory" -Path "${env:UserProfile}\.cloud-init\" -Force
131+
# TODO: Investigate why UTF-8 BOM seems to break cloud-init.
132+
$filePath="${cloudinitdir}\${{ env.instance }}.user-data"
133+
$utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
134+
[System.IO.File]::WriteAllLines($filePath, $env:cloudinit, $utf8NoBomEncoding)
135+
Write-Output "Testing wsl-setup with cloud-init user data at ${cloudinitdir} :"
136+
Get-Content "${cloudinitdir}\${{ env.instance }}.user-data"
137+
- name: Test initial setup
138+
timeout-minutes: 10
139+
shell: powershell
140+
run: |
141+
wsl -d "${{ env.instance }}" # Will run the wsl-setup script.
142+
if (!(Test-Path -Path "${env:LocalAppData}\Microsoft\Windows\Fonts\Ubuntu*.ttf")) {
143+
Write-Error "Ubuntu font was not installed as expected"
144+
Exit 1
145+
}
146+
if (!(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Fonts\" -Name "Ubuntu*" )) {
147+
Write-Error "Ubuntu font was not registered"
148+
Exit 2
149+
}
150+
wsl -d "${{ env.instance }}" -u root -- bash -ec "rm ${{ env.profile_script }} || true"
151+
wsl -d "${{ env.instance }}" -u root -- bash -ec "cat /var/log/cloud-init.log || true"
152+
- name: Assertions on the new instance
153+
uses: ubuntu/WSL/.github/actions/wsl-bash@main
154+
with:
155+
distro: ${{ env.instance }}
156+
working-dir: "~/"
157+
exec: |
158+
if [[ $(id -u) == 0 ]]; then
159+
echo "::error:: Default user shouldn't be root"
160+
exit 1
161+
fi
162+
163+
if [[ $(LANG=C systemctl is-system-running) != "running" ]]; then
164+
systemctl --failed
165+
exit 2
166+
fi
167+
168+
if [[ ! -r "/etc/cloud/cloud-init.disabled" ]]; then
169+
echo "::error:: Missing cloud-init.disabled marker file"
170+
exit 3
171+
fi
172+
173+
hello
174+
if [[ $? != 0 ]]; then
175+
echo "::error:: Failed to execute the hello program that should have been installed by cloud-init"
176+
exit 4
177+
fi
178+
- name: "Clean up" # Probably not necessary since we're leveraging ephemeral GH's runners.
179+
shell: powershell
180+
run: |
181+
wsl --unregister ${{ env.instance }}

0 commit comments

Comments
 (0)