Merge pull request #29 from boris91/chore/header-controls-keys-naming #21
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: MDK UI CI | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - "ui-client/**" | |
| - ".github/workflows/ui.yaml" | |
| pull_request: | |
| branches: [main] | |
| types: [opened, reopened, synchronize] | |
| paths: | |
| - "ui-client/**" | |
| - ".github/workflows/ui.yaml" | |
| permissions: {} | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| NODE_VERSION: "lts/*" | |
| PNPM_VERSION: "10.5.0" | |
| UI_DIR: ui-client | |
| jobs: | |
| dependency-review: | |
| name: Dependency Review | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| persist-credentials: false | |
| - name: Dependency Review | |
| uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0 | |
| with: | |
| fail-on-severity: moderate | |
| vulnerability-check: true | |
| license-check: true | |
| comment-summary-in-pr: always | |
| ui-setup: | |
| name: UI Setup Dependencies | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| defaults: | |
| run: | |
| working-directory: ${{ env.UI_DIR }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Setup runtime | |
| uses: ./.github/actions/setup-runtime | |
| with: | |
| node_version: ${{ env.NODE_VERSION }} | |
| package_manager: pnpm | |
| pnpm_version: ${{ env.PNPM_VERSION }} | |
| cache_dependency_path: ${{ env.UI_DIR }}/pnpm-lock.yaml | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| ui-lint: | |
| name: UI Lint | |
| runs-on: ubuntu-latest | |
| needs: [ui-setup] | |
| permissions: | |
| contents: read | |
| defaults: | |
| run: | |
| working-directory: ${{ env.UI_DIR }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Setup runtime | |
| uses: ./.github/actions/setup-runtime | |
| with: | |
| node_version: ${{ env.NODE_VERSION }} | |
| package_manager: pnpm | |
| pnpm_version: ${{ env.PNPM_VERSION }} | |
| cache_dependency_path: ${{ env.UI_DIR }}/pnpm-lock.yaml | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Lint | |
| run: pnpm run lint | |
| ui-typecheck: | |
| name: UI Typecheck | |
| runs-on: ubuntu-latest | |
| needs: [ui-setup] | |
| permissions: | |
| contents: read | |
| defaults: | |
| run: | |
| working-directory: ${{ env.UI_DIR }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Setup runtime | |
| uses: ./.github/actions/setup-runtime | |
| with: | |
| node_version: ${{ env.NODE_VERSION }} | |
| package_manager: pnpm | |
| pnpm_version: ${{ env.PNPM_VERSION }} | |
| cache_dependency_path: ${{ env.UI_DIR }}/pnpm-lock.yaml | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Typecheck | |
| run: pnpm run typecheck | |
| ui-test: | |
| name: UI Test | |
| runs-on: ubuntu-latest | |
| needs: [ui-setup] | |
| permissions: | |
| contents: read | |
| defaults: | |
| run: | |
| working-directory: ${{ env.UI_DIR }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Setup runtime | |
| uses: ./.github/actions/setup-runtime | |
| with: | |
| node_version: ${{ env.NODE_VERSION }} | |
| package_manager: pnpm | |
| pnpm_version: ${{ env.PNPM_VERSION }} | |
| cache_dependency_path: ${{ env.UI_DIR }}/pnpm-lock.yaml | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Format check | |
| continue-on-error: true | |
| run: pnpm run format | |
| - name: Test with coverage | |
| id: run-tests | |
| run: pnpm run test:coverage || pnpm test | |
| - name: Coverage summary | |
| if: always() | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| TEST_OUTCOME="${{ steps.run-tests.outcome }}" | |
| mapfile -t COVERAGE_JSON_FILES < <(find . -type f -path '*/coverage/coverage-final.json') | |
| mapfile -t LCOV_FILES < <(find . -type f -path '*/coverage/lcov.info') | |
| if [ ${#COVERAGE_JSON_FILES[@]} -gt 0 ]; then | |
| rm -rf .nyc_output | |
| mkdir -p .nyc_output | |
| i=0 | |
| for file in "${COVERAGE_JSON_FILES[@]}"; do | |
| cp "$file" ".nyc_output/out-$i.json" | |
| i=$((i + 1)) | |
| done | |
| npx --yes nyc merge .nyc_output coverage-merged.json >/dev/null | |
| cp coverage-merged.json .nyc_output/out.json | |
| NYC_REPORT="$(npx --yes nyc report --reporter=text-summary 2>&1)" | |
| echo "$NYC_REPORT" | |
| STMT=$(echo "$NYC_REPORT" | sed -n 's/^Statements[^:]*: *\([0-9.]*\)%.*/\1/p') | |
| BRANCH=$(echo "$NYC_REPORT" | sed -n 's/^Branches[^:]*: *\([0-9.]*\)%.*/\1/p') | |
| FN=$(echo "$NYC_REPORT" | sed -n 's/^Functions[^:]*: *\([0-9.]*\)%.*/\1/p') | |
| LINES=$(echo "$NYC_REPORT" | sed -n 's/^Lines[^:]*: *\([0-9.]*\)%.*/\1/p') | |
| [ -z "$STMT" ] && STMT="—"; [ -z "$BRANCH" ] && BRANCH="—"; [ -z "$FN" ] && FN="—"; [ -z "$LINES" ] && LINES="—" | |
| SRC="coverage-final.json" | |
| elif [ ${#LCOV_FILES[@]} -gt 0 ]; then | |
| LF=$(awk -F: '/^LF:/ {sum+=$2} END {print sum+0}' "${LCOV_FILES[@]}") | |
| LH=$(awk -F: '/^LH:/ {sum+=$2} END {print sum+0}' "${LCOV_FILES[@]}") | |
| FNF=$(awk -F: '/^FNF:/ {sum+=$2} END {print sum+0}' "${LCOV_FILES[@]}") | |
| FNH=$(awk -F: '/^FNH:/ {sum+=$2} END {print sum+0}' "${LCOV_FILES[@]}") | |
| BRF=$(awk -F: '/^BRF:/ {sum+=$2} END {print sum+0}' "${LCOV_FILES[@]}") | |
| BRH=$(awk -F: '/^BRH:/ {sum+=$2} END {print sum+0}' "${LCOV_FILES[@]}") | |
| LINES=$(awk -v h="$LH" -v f="$LF" 'BEGIN { if (f==0) print "0.00"; else printf "%.2f", (h/f)*100 }') | |
| STMT="$LINES" | |
| FN=$(awk -v h="$FNH" -v f="$FNF" 'BEGIN { if (f==0) print "0.00"; else printf "%.2f", (h/f)*100 }') | |
| BRANCH=$(awk -v h="$BRH" -v f="$BRF" 'BEGIN { if (f==0) print "0.00"; else printf "%.2f", (h/f)*100 }') | |
| SRC="lcov.info" | |
| else | |
| STMT="—"; BRANCH="—"; FN="—"; LINES="—"; SRC="none" | |
| fi | |
| [ "$TEST_OUTCOME" = "success" ] && ICON="✅ PASS" || ICON="❌ FAIL" | |
| { | |
| echo "## UI Coverage Summary" | |
| echo "" | |
| echo "| Scope | Status | Statements | Branches | Functions | Lines | Source | Gate |" | |
| echo "|---|---|---:|---:|---:|---:|---|---|" | |
| echo "| UI | ${ICON} | ${STMT}% | ${BRANCH}% | ${FN}% | ${LINES}% | ${SRC} | Vitest thresholds |" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| [ "$TEST_OUTCOME" = "success" ] || exit 1 | |
| ui-build: | |
| name: UI Build | |
| runs-on: ubuntu-latest | |
| needs: [ui-setup] | |
| permissions: | |
| contents: read | |
| defaults: | |
| run: | |
| working-directory: ${{ env.UI_DIR }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Setup runtime | |
| uses: ./.github/actions/setup-runtime | |
| with: | |
| node_version: ${{ env.NODE_VERSION }} | |
| package_manager: pnpm | |
| pnpm_version: ${{ env.PNPM_VERSION }} | |
| cache_dependency_path: ${{ env.UI_DIR }}/pnpm-lock.yaml | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Security audit | |
| run: | | |
| set +e | |
| pnpm audit --audit-level=moderate 2>&1 | |
| MODERATE_EXIT=$? | |
| pnpm audit --audit-level=high 2>&1 | |
| HIGH_EXIT=$? | |
| set -e | |
| [ $MODERATE_EXIT -eq 0 ] && MODERATE_STATUS="PASS" || MODERATE_STATUS="WARN" | |
| [ $HIGH_EXIT -eq 0 ] && HIGH_STATUS="PASS" || HIGH_STATUS="WARN" | |
| { | |
| echo "## UI Security Audit Summary" | |
| echo "" | |
| echo "| Scope | Moderate Audit | High Audit | Gate |" | |
| echo "|---|---|---|---|" | |
| echo "| UI | ${MODERATE_STATUS} | ${HIGH_STATUS} | High/Critical blocking |" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| if [ $MODERATE_EXIT -ne 0 ]; then | |
| echo "::error::pnpm audit reported moderate-level issues" | |
| fi | |
| if [ $HIGH_EXIT -ne 0 ]; then | |
| echo "::error::pnpm audit reported high-level issues" | |
| fi | |
| [ $HIGH_EXIT -eq 0 ] | |
| - name: Build | |
| run: pnpm run build | |
| - name: Bundle size report | |
| continue-on-error: true | |
| run: | | |
| echo "## UI Bundle Size Report" >> "$GITHUB_STEP_SUMMARY" | |
| echo "" >> "$GITHUB_STEP_SUMMARY" | |
| pnpm run size -- --markdown 2>&1 | tee -a "$GITHUB_STEP_SUMMARY" |