diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 447e720..bfdc7db 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -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 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1f15e77..a50e660 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -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 @@ -88,11 +118,24 @@ jobs: - name: Install devcontainer CLI run: npm install -g @devcontainers/cli@0.85.0 - - 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/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/scenario-test-output.log; then echo "ERROR: Test output contains failures." exit 1 @@ -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