Skip to content

feat: add reinitialization support for terminated sessions and improve data injection in weather widget #1229

feat: add reinitialization support for terminated sessions and improve data injection in weather widget

feat: add reinitialization support for terminated sessions and improve data injection in weather widget #1229

Workflow file for this run

name: On Push
on:
push:
branches:
- main
- "next/**"
- "release/**"
pull_request:
branches:
- main
- "next/**"
- "release/**"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Minimal permissions for security (least-privilege principle)
permissions:
contents: read
jobs:
# Shared setup job that other jobs can reference
setup:
name: "Setup"
runs-on: ubuntu-latest
outputs:
node-version: ${{ steps.node-version.outputs.version }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Get Node version
id: node-version
run: echo "version=$(cat .nvmrc)" >> $GITHUB_OUTPUT
# Lint and format checks (fast, independent)
lint:
name: "Lint & Format Checks"
needs: setup
runs-on: ubuntu-latest
env:
NX_DAEMON: "false"
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: ${{ needs.setup.outputs.node-version }}
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Restore Nx cache
uses: ./.github/actions/nx-cache-restore
- name: Set Nx SHAs
uses: nrwl/nx-set-shas@v5
- name: Run linter
run: npx nx affected -t lint
- name: Run prettier
run: npx prettier --check .
continue-on-error: true
# Build all libraries
build:
name: "Build Libraries"
needs: setup
runs-on: ubuntu-latest
env:
NX_DAEMON: "false"
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: ${{ needs.setup.outputs.node-version }}
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Restore Nx cache
uses: ./.github/actions/nx-cache-restore
- name: Set Nx SHAs
uses: nrwl/nx-set-shas@v5
- name: Build libraries
id: build
continue-on-error: true
run: npx nx run-many -t build --parallel 5
- name: Reset Nx cache on failure
if: steps.build.outcome == 'failure'
run: npx nx reset
- name: Retry build without cache
if: steps.build.outcome == 'failure'
run: npx nx run-many -t build --parallel 5
- name: Save Nx cache
if: always()
uses: ./.github/actions/nx-cache-save
- name: Upload build artifacts
uses: actions/upload-artifact@v6
with:
name: dist
path: |
libs/*/dist
dist/
retention-days: 1
# Discover E2E projects dynamically using Nx tags, chunked for API rate limits
discover-e2e:
name: "Discover E2E Projects"
needs: setup
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
matrix: ${{ steps.discover.outputs.chunks }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: ${{ needs.setup.outputs.node-version }}
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Discover E2E projects and create chunks
id: discover
run: |
PROJECTS_JSON=$(npx nx show projects -p tag:type:e2e --json 2>/dev/null | jq -c '.' || echo "[]")
if [ "$PROJECTS_JSON" = "[]" ] || [ "$PROJECTS_JSON" = "null" ]; then
echo "::error::No E2E projects found with tag:type:e2e"
exit 1
fi
TOTAL=$(echo $PROJECTS_JSON | jq 'length')
echo "Found $TOTAL E2E projects"
# Chunk projects into groups of 4 to reduce API rate limit pressure
CHUNK_SIZE=4
CHUNKS=$(echo $PROJECTS_JSON | jq -c --argjson n "$CHUNK_SIZE" '[range(0; length; $n) as $i | .[$i:$i+$n]] | to_entries | map({index: .key, projects: .value})')
CHUNK_COUNT=$(echo $CHUNKS | jq 'length')
echo "Created $CHUNK_COUNT chunks of up to $CHUNK_SIZE projects each"
echo "chunks=$CHUNKS" >> $GITHUB_OUTPUT
# Unit tests (depends on build)
unit-tests:
name: "Unit Tests"
needs: [setup, build]
runs-on: ubuntu-latest
timeout-minutes: 10
env:
NX_DAEMON: "false"
RUN_COVERAGE: ${{ github.ref == 'refs/heads/main' }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: ${{ needs.setup.outputs.node-version }}
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Download build artifacts
uses: actions/download-artifact@v6
with:
name: dist
- name: Restore Nx cache
uses: ./.github/actions/nx-cache-restore
- name: Set Nx SHAs
uses: nrwl/nx-set-shas@v5
- name: Run unit tests (affected, no coverage)
if: env.RUN_COVERAGE != 'true'
run: npx nx affected -t test --passWithNoTests --exclude='demo-e2e-*'
- name: Run unit tests (all, with coverage)
if: env.RUN_COVERAGE == 'true'
run: npx nx run-many -t test --exclude='demo-e2e-*' --coverage
- name: Upload unit coverage artifacts
if: env.RUN_COVERAGE == 'true' && always()
uses: actions/upload-artifact@v6
with:
name: unit-coverage
path: coverage/unit/
retention-days: 1
if-no-files-found: warn
# E2E tests - chunked matrix strategy to reduce API rate limit pressure
e2e-tests:
name: "E2E Tests (chunk ${{ matrix.chunk.index }})"
needs: [setup, build, discover-e2e]
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
chunk: ${{ fromJson(needs.discover-e2e.outputs.matrix) }}
env:
NX_DAEMON: "false"
RUN_COVERAGE: ${{ github.ref == 'refs/heads/main' }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: ${{ needs.setup.outputs.node-version }}
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Download build artifacts
uses: actions/download-artifact@v6
with:
name: dist
- name: Restore Nx cache
uses: ./.github/actions/nx-cache-restore
- name: Set Nx SHAs
uses: nrwl/nx-set-shas@v5
- name: Run E2E tests (chunk ${{ matrix.chunk.index }})
id: test
continue-on-error: true
run: |
PROJECTS='${{ join(matrix.chunk.projects, ',') }}'
echo "Running E2E tests for: $PROJECTS"
if [ "$RUN_COVERAGE" = "true" ]; then
npx nx run-many -t test --projects="$PROJECTS" --coverage --parallel=1
else
npx nx run-many -t test --projects="$PROJECTS" --parallel=1
fi
- name: Reset Nx cache on failure
if: steps.test.outcome == 'failure'
run: npx nx reset
- name: Retry E2E tests (chunk ${{ matrix.chunk.index }})
if: steps.test.outcome == 'failure'
run: |
PROJECTS='${{ join(matrix.chunk.projects, ',') }}'
if [ "$RUN_COVERAGE" = "true" ]; then
npx nx run-many -t test --projects="$PROJECTS" --coverage --parallel=1
else
npx nx run-many -t test --projects="$PROJECTS" --parallel=1
fi
- name: Upload E2E coverage artifacts
if: env.RUN_COVERAGE == 'true' && always()
uses: actions/upload-artifact@v6
with:
name: e2e-coverage-chunk-${{ matrix.chunk.index }}
path: coverage/e2e/
retention-days: 1
if-no-files-found: warn
# Coverage report (runs on main branch only, merges artifacts from test jobs)
coverage:
name: "Coverage Report"
needs: [setup, build, unit-tests, e2e-tests]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
env:
NX_DAEMON: "false"
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: ${{ needs.setup.outputs.node-version }}
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Download unit coverage artifacts
uses: actions/download-artifact@v6
with:
name: unit-coverage
path: coverage/unit/
- name: Download E2E coverage artifacts
uses: actions/download-artifact@v6
with:
pattern: e2e-coverage-chunk-*
path: coverage/e2e/
merge-multiple: true
- name: Merge coverage reports
run: node scripts/merge-coverage.mjs
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
files: coverage/merged/lcov.info
fail_ci_if_error: false
verbose: true
- name: Check coverage threshold
run: npx nyc check-coverage --temp-dir=coverage/merged --statements 95 --branches 95 --functions 95 --lines 95