Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
119 changes: 91 additions & 28 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
pull_request:
push:
branches: [main, develop]
schedule:
- cron: "0 4 * * 1"

concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
Expand All @@ -21,7 +23,7 @@
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: ShellCheck
uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # 2.0.0

Check warning on line 26 in .github/workflows/test.yml

View workflow job for this annotation

GitHub Actions / lint

26:81 [line-length] line too long (88 > 80 characters)
with:
severity: warning

Expand All @@ -37,7 +39,7 @@
exit "$FAIL"

- name: Install uv
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0

Check warning on line 42 in .github/workflows/test.yml

View workflow job for this annotation

GitHub Actions / lint

42:81 [line-length] line too long (82 > 80 characters)

- name: Validate YAML
run: |
Expand All @@ -45,7 +47,7 @@

- name: Prettier check
run: |
npx prettier@4.0.0-alpha.8 --check "**/*.{json,yml,yaml,md}" --ignore-path .gitignore

Check warning on line 50 in .github/workflows/test.yml

View workflow job for this annotation

GitHub Actions / lint

50:81 [line-length] line too long (95 > 80 characters)

- name: Markdownlint
run: |
Expand All @@ -53,8 +55,10 @@

- name: shfmt format check
run: |
curl -fsSL https://github.com/mvdan/sh/releases/download/v3.13.0/shfmt_v3.13.0_linux_amd64 \

Check warning on line 58 in .github/workflows/test.yml

View workflow job for this annotation

GitHub Actions / lint

58:81 [line-length] line too long (102 > 80 characters)
-o /usr/local/bin/shfmt && chmod +x /usr/local/bin/shfmt
-o /usr/local/bin/shfmt
echo "70aa99784703a8d6569bbf0b1e43e1a91906a4166bf1a79de42050a6d0de7551 /usr/local/bin/shfmt" | sha256sum -c -

Check warning on line 60 in .github/workflows/test.yml

View workflow job for this annotation

GitHub Actions / lint

60:81 [line-length] line too long (120 > 80 characters)
chmod +x /usr/local/bin/shfmt
shfmt -ln bash -d -i 4 -ci src/ test/

- name: Check .sh files are executable
Expand All @@ -72,27 +76,32 @@
test-scenarios:
needs: lint
runs-on: ubuntu-latest
timeout-minutes: 60 # 10 scenarios building containers takes time
timeout-minutes: 90 # 17 scenarios building containers takes time
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0

Check warning on line 86 in .github/workflows/test.yml

View workflow job for this annotation

GitHub Actions / lint

86:81 [line-length] line too long (90 > 80 characters)

- name: Install devcontainer CLI
run: npm install -g @devcontainers/cli@0.85.0

- name: Run all scenarios
run: |
devcontainer features test --project-folder . 2>&1 | tee /tmp/scenario-test-output.log

Check warning on line 93 in .github/workflows/test.yml

View workflow job for this annotation

GitHub Actions / lint

93:81 [line-length] line too long (96 > 80 characters)
# Workaround: devcontainers/cli@0.85.0 exits 0 even when feature install fails.

Check warning on line 94 in .github/workflows/test.yml

View workflow job for this annotation

GitHub Actions / lint

94:81 [line-length] line too long (89 > 80 characters)
# Grep for known failure strings and fail explicitly. Revisit on CLI upgrade.

Check warning on line 95 in .github/workflows/test.yml

View workflow job for this annotation

GitHub Actions / lint

95:81 [line-length] line too long (87 > 80 characters)
if grep -qE "Exit code [1-9][0-9]*|failed to install|Failed to launch|Failed:| FAIL:" /tmp/scenario-test-output.log; then
echo "ERROR: Test output contains failures."
exit 1
fi
# Positive assertion: verify at least one test passed
if ! grep -qE "[0-9]+ passed" /tmp/scenario-test-output.log; then
echo "ERROR: No pass markers found — test may not have run."
exit 1
fi

- name: Annotate install warnings
if: always()
Expand Down Expand Up @@ -123,39 +132,83 @@
contents: read
strategy:
fail-fast: false
max-parallel: 10
max-parallel: 8
matrix:
image:
# Raw OS images
- "ubuntu:22.04"
- "mcr.microsoft.com/devcontainers/base:ubuntu"
- "mcr.microsoft.com/devcontainers/base:debian"
- "mcr.microsoft.com/devcontainers/base:alpine"
- "mcr.microsoft.com/devcontainers/javascript-node"
- "ubuntu:24.04"
- "debian:bullseye"
- "debian:bookworm"
- "alpine:3.19"
- "alpine:3.20"
- "alpine:3.21"
- "archlinux:latest"
- "fedora:39"
- "fedora:40"
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0

- name: Install devcontainer CLI
run: npm install -g @devcontainers/cli@0.85.0

- name: Test on ${{ matrix.image }}
run: |
devcontainer features test \
--features claude-code \
--skip-scenarios \
--base-image "${{ matrix.image }}" \
--project-folder . 2>&1 | tee /tmp/test-output.log
# Workaround: devcontainers/cli@0.85.0 exits 0 even when feature install fails.
# Grep for known failure strings and fail explicitly. Revisit on CLI upgrade.
if grep -qE "Exit code [1-9][0-9]*|failed to install|Failed to launch|Failed:| FAIL:" /tmp/test-output.log; then
echo "ERROR: Test output contains failures."
exit 1
fi
# Positive assertion: verify at least one test passed
if ! grep -qE "[0-9]+ passed" /tmp/test-output.log; then
echo "ERROR: No pass markers found — test may not have run."
exit 1
fi

- name: Annotate install warnings
if: always()
run: |
mapfile -t warnings < <(grep -oP '(?<=claude-code feature\] WARNING: ).*' /tmp/test-output.log 2>/dev/null | tr -d '\r' | sort -u || true)
if [[ ${#warnings[@]} -gt 0 ]]; then
echo "## :warning: Install Warnings" >> "$GITHUB_STEP_SUMMARY"
for msg in "${warnings[@]}"; do
echo "- ${msg}" >> "$GITHUB_STEP_SUMMARY"
echo "::warning title=Install Warning::${msg}"
done
fi

- name: Upload logs on failure
if: failure()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: logs-amd64-${{ strategy.job-index }}
path: /tmp/test-output.log
retention-days: 7

# Nightly-only extended image matrix for broader coverage
test-image-matrix-extended:
needs: lint
if: github.event_name == 'schedule'
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
strategy:
fail-fast: false
max-parallel: 5
matrix:
image:
- "rockylinux:9"
- "almalinux:9"
- "amazonlinux:2023"
# DevContainer base images
- "mcr.microsoft.com/devcontainers/base:debian"
- "mcr.microsoft.com/devcontainers/base:ubuntu"
- "mcr.microsoft.com/devcontainers/base:alpine"
- "mcr.microsoft.com/devcontainers/universal:2"
# Language-specific images
- "mcr.microsoft.com/devcontainers/python:3"
- "mcr.microsoft.com/devcontainers/javascript-node"
- "mcr.microsoft.com/devcontainers/typescript-node"
- "mcr.microsoft.com/devcontainers/rust"
- "mcr.microsoft.com/devcontainers/go"
- "mcr.microsoft.com/devcontainers/cpp"
- "mcr.microsoft.com/devcontainers/dotnet"
- "mcr.microsoft.com/devcontainers/java"
- "mcr.microsoft.com/devcontainers/ruby"
- "mcr.microsoft.com/devcontainers/php"
- "debian:bookworm"
- "ubuntu:22.04"
- "alpine:3.20"
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

Expand All @@ -178,6 +231,11 @@
echo "ERROR: Test output contains failures."
exit 1
fi
# Positive assertion: verify at least one test passed
if ! grep -qE "[0-9]+ passed" /tmp/test-output.log; then
echo "ERROR: No pass markers found — test may not have run."
exit 1
fi

- name: Annotate install warnings
if: always()
Expand All @@ -195,7 +253,7 @@
if: failure()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: logs-amd64-${{ strategy.job-index }}
name: logs-extended-${{ strategy.job-index }}
path: /tmp/test-output.log
retention-days: 7

Expand Down Expand Up @@ -240,6 +298,11 @@
echo "ERROR: Test output contains failures."
exit 1
fi
# Positive assertion: verify at least one test passed
if ! grep -qE "[0-9]+ passed" /tmp/test-output.log; then
echo "ERROR: No pass markers found — test may not have run."
exit 1
fi

- name: Annotate install warnings
if: always()
Expand Down
Loading
Loading