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
26 changes: 26 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,29 @@ jobs:
exit 1
}
echo "Published feature verified successfully."

create-release:
needs: post-publish
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0 # needed for tag history

- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_NAME: ${{ github.ref_name }}
run: |
PREV_TAG="$(git tag --sort=-v:refname | sed -n '2p')"
GENERATE_ARGS=(--generate-notes)
if [[ -n "${PREV_TAG}" ]]; then
GENERATE_ARGS+=(--notes-start-tag "${PREV_TAG}")
fi
gh release create "${TAG_NAME}" \
--title "${TAG_NAME}" \
"${GENERATE_ARGS[@]}" \
--verify-tag
53 changes: 48 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,43 @@ jobs:
done < <(find . -name '*.sh' -not -path './.git/*' -print0)
exit "$FAIL"

# Run all per-scenario tests (options-specific assertions)
# Run per-scenario tests in parallel groups for faster CI.
# The 17 scenarios are split into 3 groups by estimated build cost.
# Each group dynamically filters scenarios.json to run only its subset.
test-scenarios:
name: test-scenarios (${{ matrix.group.name }})
needs: lint
runs-on: ubuntu-latest
timeout-minutes: 90 # 17 scenarios building containers takes time
timeout-minutes: 30
permissions:
contents: read
strategy:
fail-fast: false
matrix:
group:
- name: fast
scenarios: >-
default_options
completions_pipeline
mcp_enabled
negative_validation
security_permissions
completions_disabled
- name: medium
scenarios: >-
custom_version
custom_install_path
custom_node_version
install_path_with_completions
mount_host_config
node_preinstalled
- name: slow
scenarios: >-
idempotency
upgrade_version
multi_feature_combo
alpine_specific
fedora_default
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

Expand All @@ -88,11 +118,24 @@ jobs:
- name: Install devcontainer CLI
run: npm install -g @devcontainers/[email protected]

- name: Run all scenarios
- name: Generate group scenarios.json
env:
SCENARIOS: ${{ matrix.group.scenarios }}
GROUP_NAME: ${{ matrix.group.name }}
run: |
FULL="test/claude-code/scenarios.json"
# Build a jq filter that selects only the named scenarios
JQ_FILTER=$(echo "${SCENARIOS}" | tr -s ' ' '\n' | sed 's/.*/"&"/' | paste -sd, | sed 's/^/[/;s/$/]/')
jq --argjson keys "${JQ_FILTER}" 'with_entries(select(.key as $k | $keys | index($k)))' "${FULL}" > /tmp/group-scenarios.json
echo "::group::scenarios.json for group '${GROUP_NAME}'"
cat /tmp/group-scenarios.json
echo "::endgroup::"
cp /tmp/group-scenarios.json "${FULL}"

- name: Run scenarios (${{ matrix.group.name }})
run: |
devcontainer features test --project-folder . 2>&1 | tee /tmp/scenario-test-output.log
# Workaround: devcontainers/[email protected] 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/scenario-test-output.log; then
echo "ERROR: Test output contains failures."
exit 1
Expand All @@ -119,7 +162,7 @@ jobs:
if: failure()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: logs-scenarios
name: logs-scenarios-${{ matrix.group.name }}
path: /tmp/scenario-test-output.log
retention-days: 7

Expand Down