name: CI on: pull_request: push: branches: [main] # Nightly the suite also runs against the newest Jellyfin, so a break there is # found within a day instead of by hand (#82). It is not on every PR: the # pinned version is what targetAbi promises, and a second leg would double the # runner minutes of every push. schedule: - cron: "11 2 * * *" workflow_dispatch: concurrency: group: ci-${{ github.ref }} cancel-in-progress: true permissions: contents: read env: DOTNET_NOLOGO: "1" DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1" DOTNET_CLI_TELEMETRY_OPTOUT: "1" # The e2e stack binds a host port and names its containers after the compose # project; both have to be unique so a second run cannot collide with this one. JELLYFIN_PORT: "8124" jobs: tests: name: tests (jellyfin ${{ matrix.jellyfin.tag }}) runs-on: ubuntu-latest timeout-minutes: 20 strategy: fail-fast: false matrix: # && binds tighter than ||, so the scheduled check has to be one # parenthesised term: without it the expression yields a boolean and # fromJSON fails. # Each leg carries a slug as well as the tag: a compose project name may # not contain dots, and "12.1" does. jellyfin: ${{ fromJSON((github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && '[{"tag":"12.1","slug":"pinned"},{"tag":"latest","slug":"latest"}]' || '[{"tag":"12.1","slug":"pinned"}]') }} env: JELLYFIN_TAG: ${{ matrix.jellyfin.tag }} COMPOSE_PROJECT_NAME: chaosflix-e2e-ci-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.jellyfin.slug }} steps: - uses: actions/checkout@v4 # run-tests.sh falls back to the SDK Docker image only when no dotnet is # on PATH; installing the SDK here keeps the build out of a container. - uses: actions/setup-dotnet@v4 with: dotnet-version: "10.0.x" - uses: actions/setup-node@v4 with: node-version: "22" cache: npm cache-dependency-path: e2e/package-lock.json - name: Cache NuGet packages uses: actions/cache@v4 with: path: ~/.nuget/packages key: nuget-${{ runner.os }}-${{ hashFiles('**/*.csproj', 'Directory.Build.props') }} restore-keys: nuget-${{ runner.os }}- - name: Resolve the Playwright version id: playwright working-directory: e2e run: | version=$(node -p "require('./package-lock.json').packages['node_modules/@playwright/test'].version") echo "version=${version}" >> "$GITHUB_OUTPUT" - name: Cache Playwright browsers id: playwright-cache uses: actions/cache@v4 with: path: ~/.cache/ms-playwright key: playwright-${{ runner.os }}-${{ steps.playwright.outputs.version }} - name: Install the Playwright browser working-directory: e2e run: | npm ci if [[ "${{ steps.playwright-cache.outputs.cache-hit }}" == "true" ]]; then npx playwright install-deps chromium else npx playwright install --with-deps chromium fi # Shell tests, Release build, xUnit suite and the Playwright e2e stack, # against the Jellyfin of this matrix leg (JELLYFIN_TAG). # ANDROID_E2E stays unset: that suite is nightly (android-e2e.yml). # ffmpeg is deliberately not installed: the runner has none, so the # fixtures are built through build-artifacts.sh's container fallback, # which stayed broken for as long as nothing exercised it. - name: Run the test suite run: ./run-tests.sh - name: Upload the Playwright report if: failure() uses: actions/upload-artifact@v4 with: # Two legs upload on a nightly run; identical names collide. name: playwright-report-${{ matrix.jellyfin.slug }} path: | e2e/playwright-report e2e/test-results if-no-files-found: ignore retention-days: 14 - name: Tear down the e2e stack if: always() working-directory: e2e run: docker compose down -v --remove-orphans || true