ci(e2e): unify Linux + Windows UI tests into one parallel workflow #4
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: E2E UI Tests | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| # Unified parallel E2E UI pipeline for Linux + Windows. | |
| # | |
| # lint → tslint + checkstyle (ubuntu, OS-agnostic) | |
| # discover-plans → emits a matrix of test-plan basenames | |
| # build (matrix) → produces one VSIX per OS, uploaded as artifact | |
| # e2e (matrix) → cartesian product of {os × plan}, all running in parallel | |
| # analyze → aggregates results from BOTH OSes into one unified summary | |
| # | |
| # Modelled after vscode-java-pack/.github/workflows/e2e-autotest.yml; matrix | |
| # has been extended with an `os` dimension so a single `e2e` job covers both | |
| # platforms. Each matrix cell surfaces as its own PR check, so failures are | |
| # visible without an extra gate job. | |
| jobs: | |
| # ── Lint + Checkstyle (OS-agnostic) ───────────────────── | |
| lint: | |
| name: Lint & Checkstyle | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '21' | |
| distribution: 'temurin' | |
| - name: Setup Node.js environment | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - name: Install Node.js modules | |
| run: npm install | |
| - name: Lint | |
| run: npm run tslint | |
| - name: Checkstyle | |
| working-directory: ./jdtls.ext | |
| run: ./mvnw checkstyle:check | |
| # ── Discover test plans ───────────────────────────────── | |
| discover-plans: | |
| name: Discover E2E Plans | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.scan.outputs.matrix }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Scan test plans | |
| id: scan | |
| shell: bash | |
| run: | | |
| plans=$(ls test/e2e-plans/*.yaml | xargs -n1 basename | sed 's/\.yaml$//' | jq -R . | jq -sc .) | |
| echo "matrix=$plans" >> "$GITHUB_OUTPUT" | |
| echo "Found plans: $plans" | |
| # ── Build VSIX (one per OS) ───────────────────────────── | |
| build: | |
| name: Build VSIX (${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 20 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ ubuntu-latest, windows-latest ] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '21' | |
| distribution: 'temurin' | |
| - name: Setup Node.js environment | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - name: Install Node.js modules | |
| run: npm install | |
| - name: Install VSCE | |
| run: npm install -g @vscode/vsce | |
| - name: Build OSGi bundle | |
| run: npm run build-server | |
| - name: Build VSIX file | |
| run: vsce package -o vscode-java-dependency.vsix | |
| - name: Upload VSIX artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: vsix-${{ matrix.os }} | |
| path: vscode-java-dependency.vsix | |
| retention-days: 1 | |
| # ── Run every (OS × plan) combo in parallel ───────────── | |
| e2e: | |
| name: E2E (${{ matrix.os }} / ${{ matrix.plan }}) | |
| needs: [ build, discover-plans ] | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 25 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ ubuntu-latest, windows-latest ] | |
| plan: ${{ fromJson(needs.discover-plans.outputs.matrix) }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Linux Build Environment (Xvfb) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libxkbfile-dev pkg-config libsecret-1-dev libxss1 dbus xvfb libgtk-3-0 libgbm1 | |
| # Use 1920x1080 so the Java Projects view (rendered inside the Explorer | |
| # sidebar) gets enough vertical space. With 1024x768 the sticky | |
| # pane-header overlapped tree rows and intercepted click events. | |
| sudo /usr/bin/Xvfb :99 -screen 0 1920x1080x24 > /dev/null 2>&1 & | |
| sleep 3 | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '21' | |
| distribution: 'temurin' | |
| - name: Setup Node.js environment | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - name: Setup autotest | |
| run: npm install -g @vscjava/vscode-autotest | |
| - name: Download VSIX artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: vsix-${{ matrix.os }} | |
| path: . | |
| - name: E2E Test — ${{ matrix.plan }} (Linux) | |
| if: runner.os == 'Linux' | |
| shell: bash | |
| env: | |
| AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }} | |
| AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }} | |
| AZURE_OPENAI_DEPLOYMENT: ${{ secrets.AZURE_OPENAI_DEPLOYMENT }} | |
| run: | | |
| DISPLAY=:99 autotest run "test/e2e-plans/${{ matrix.plan }}.yaml" \ | |
| --vsix "$(pwd)/vscode-java-dependency.vsix" \ | |
| --output "test-results/${{ matrix.plan }}" | |
| - name: E2E Test — ${{ matrix.plan }} (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| env: | |
| AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }} | |
| AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }} | |
| AZURE_OPENAI_DEPLOYMENT: ${{ secrets.AZURE_OPENAI_DEPLOYMENT }} | |
| run: | | |
| autotest run "test/e2e-plans/${{ matrix.plan }}.yaml" --vsix "$((Get-Location).Path)\vscode-java-dependency.vsix" --output "test-results\${{ matrix.plan }}" | |
| - name: Upload test results | |
| if: ${{ always() }} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: e2e-results-${{ matrix.os }}-${{ matrix.plan }} | |
| path: test-results/ | |
| retention-days: 7 | |
| # ── Unified analysis across both OSes ─────────────────── | |
| analyze: | |
| name: E2E Summary | |
| needs: e2e | |
| if: ${{ always() }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Setup Node.js environment | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - name: Setup autotest | |
| run: npm install -g @vscjava/vscode-autotest | |
| - name: Download all plan results | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: e2e-results-* | |
| path: all-results | |
| merge-multiple: false | |
| - name: Organize results (prefix each plan by OS) | |
| shell: bash | |
| run: | | |
| mkdir -p test-results | |
| # Artifact dir names look like: e2e-results-ubuntu-latest-<plan> | |
| # or e2e-results-windows-latest-<plan> | |
| for dir in all-results/e2e-results-ubuntu-latest-*/; do | |
| [ -d "$dir" ] || continue | |
| find "$dir" -name "results.json" -exec dirname {} \; | while read d; do | |
| name=$(basename "$d") | |
| mkdir -p "test-results/linux-$name" | |
| cp -r "$d"/. "test-results/linux-$name"/ | |
| done | |
| done | |
| for dir in all-results/e2e-results-windows-latest-*/; do | |
| [ -d "$dir" ] || continue | |
| find "$dir" -name "results.json" -exec dirname {} \; | while read d; do | |
| name=$(basename "$d") | |
| mkdir -p "test-results/windows-$name" | |
| cp -r "$d"/. "test-results/windows-$name"/ | |
| done | |
| done | |
| echo "Organized plan result directories:" | |
| ls test-results/ || true | |
| - name: Analyze results | |
| env: | |
| AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }} | |
| AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }} | |
| AZURE_OPENAI_DEPLOYMENT: ${{ secrets.AZURE_OPENAI_DEPLOYMENT }} | |
| run: autotest analyze test-results --output test-results | |
| - name: Write Job Summary | |
| if: always() | |
| shell: bash | |
| run: | | |
| if [ -f test-results/summary.md ]; then | |
| cat test-results/summary.md >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| - name: Upload aggregate summary | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: e2e-aggregate-summary | |
| path: test-results/summary.md | |
| retention-days: 30 |