feat(aios-dashboard): AIOS Dashboard & ADE Implementation (#53) #131
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: CI | |
| # Story 6.1: GitHub Actions Cost Optimization | |
| # Story TD-3: CI/CD Optimization & Test Coverage | |
| # Consolidated CI workflow - single source of truth for validation | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths-ignore: | |
| - 'docs/**' | |
| - '*.md' | |
| - '.aios/**' | |
| - 'squads/**' | |
| - 'LICENSE' | |
| - '.gitignore' | |
| pull_request: | |
| branches: | |
| - main | |
| paths-ignore: | |
| - 'docs/**' | |
| - '*.md' | |
| - '.aios/**' | |
| - 'squads/**' | |
| - 'LICENSE' | |
| - '.gitignore' | |
| workflow_dispatch: | |
| concurrency: | |
| group: ci-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| # Path-based change detection for smart job skipping | |
| changes: | |
| name: Detect Changes | |
| runs-on: ubuntu-latest | |
| outputs: | |
| code: ${{ steps.filter.outputs.code }} | |
| tests: ${{ steps.filter.outputs.tests }} | |
| config: ${{ steps.filter.outputs.config }} | |
| stories: ${{ steps.filter.outputs.stories }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dorny/paths-filter@v3 | |
| id: filter | |
| with: | |
| filters: | | |
| code: | |
| - 'src/**' | |
| - '.aios-core/**' | |
| - 'bin/**' | |
| - 'packages/**' | |
| - 'scripts/**' | |
| - 'tools/**' | |
| tests: | |
| - 'tests/**' | |
| - 'jest.config.js' | |
| config: | |
| - 'package.json' | |
| - 'package-lock.json' | |
| - 'tsconfig.json' | |
| - '.eslintrc.*' | |
| - 'eslint.config.*' | |
| stories: | |
| - 'docs/stories/**' | |
| lint: | |
| name: ESLint | |
| needs: changes | |
| if: ${{ needs.changes.outputs.code == 'true' || needs.changes.outputs.config == 'true' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| cache-dependency-path: package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run ESLint | |
| run: npm run lint | |
| typecheck: | |
| name: TypeScript Type Checking | |
| needs: changes | |
| if: ${{ needs.changes.outputs.code == 'true' || needs.changes.outputs.config == 'true' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| cache-dependency-path: package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run TypeScript type checking | |
| run: npm run typecheck | |
| test: | |
| name: Jest Tests (Node ${{ matrix.node }}) | |
| needs: changes | |
| if: ${{ needs.changes.outputs.code == 'true' || needs.changes.outputs.tests == 'true' || needs.changes.outputs.config == 'true' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| strategy: | |
| matrix: | |
| node: ['18', '20'] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ matrix.node }} | |
| cache: 'npm' | |
| cache-dependency-path: package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run tests with coverage | |
| run: npm run test:coverage | |
| - name: Check coverage threshold | |
| run: | | |
| echo "=== Coverage Threshold Check ===" | |
| # Coverage threshold is enforced by jest.config.js | |
| # Target: 80% overall, 85% for core modules | |
| - name: Upload coverage reports | |
| uses: codecov/codecov-action@v4 | |
| if: always() | |
| with: | |
| files: ./coverage/lcov.info | |
| flags: unittests | |
| name: codecov-umbrella | |
| fail_ci_if_error: false | |
| continue-on-error: true | |
| story-validation: | |
| name: Story Checkbox Validation | |
| needs: changes | |
| if: ${{ needs.changes.outputs.stories == 'true' || needs.changes.outputs.code == 'true' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| cache-dependency-path: package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Validate story checkboxes | |
| run: node .aios-core/utils/aios-validator.js stories | |
| manifest-validation: | |
| name: Install Manifest Validation | |
| needs: changes | |
| if: ${{ needs.changes.outputs.code == 'true' || needs.changes.outputs.config == 'true' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| cache-dependency-path: package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Validate install manifest | |
| run: npm run validate:manifest | |
| ide-sync-validation: | |
| name: IDE Command Sync Validation | |
| needs: changes | |
| if: ${{ needs.changes.outputs.code == 'true' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| cache-dependency-path: package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Validate IDE sync | |
| run: npm run sync:ide:check | |
| - name: Report on failure | |
| if: failure() | |
| run: | | |
| echo "::error::IDE command files out of sync" | |
| echo "Run 'npm run sync:ide' locally and commit" | |
| npm run sync:ide:validate | |
| validation-summary: | |
| name: Validation Summary | |
| runs-on: ubuntu-latest | |
| needs: [changes, lint, typecheck, test, story-validation, manifest-validation, ide-sync-validation] | |
| if: always() | |
| steps: | |
| - name: Check all jobs | |
| run: | | |
| echo "=== AIOS CI Validation Summary ===" | |
| echo "" | |
| echo "📋 Change Detection:" | |
| echo " Code changed: ${{ needs.changes.outputs.code }}" | |
| echo " Tests changed: ${{ needs.changes.outputs.tests }}" | |
| echo " Config changed: ${{ needs.changes.outputs.config }}" | |
| echo " Stories changed: ${{ needs.changes.outputs.stories }}" | |
| echo "" | |
| echo "📊 Job Results:" | |
| echo " Lint: ${{ needs.lint.result }}" | |
| echo " TypeCheck: ${{ needs.typecheck.result }}" | |
| echo " Tests: ${{ needs.test.result }}" | |
| echo " Story Validation: ${{ needs.story-validation.result }}" | |
| echo " Manifest Validation: ${{ needs.manifest-validation.result }}" | |
| echo " IDE Sync Validation: ${{ needs.ide-sync-validation.result }}" | |
| echo "" | |
| # Check for failures (skipped is OK when changes don't affect that area) | |
| FAILED=false | |
| # Lint: fail if ran and didn't succeed | |
| if [ "${{ needs.lint.result }}" == "failure" ]; then | |
| echo "❌ ESLint check failed" | |
| FAILED=true | |
| fi | |
| # TypeCheck: fail if ran and didn't succeed | |
| if [ "${{ needs.typecheck.result }}" == "failure" ]; then | |
| echo "❌ TypeScript check failed" | |
| FAILED=true | |
| fi | |
| # Tests: fail if ran and didn't succeed | |
| if [ "${{ needs.test.result }}" == "failure" ]; then | |
| echo "❌ Jest tests failed" | |
| FAILED=true | |
| fi | |
| # Story Validation: fail if ran and didn't succeed | |
| if [ "${{ needs.story-validation.result }}" == "failure" ]; then | |
| echo "❌ Story validation failed" | |
| FAILED=true | |
| fi | |
| # Manifest Validation: fail if ran and didn't succeed | |
| if [ "${{ needs.manifest-validation.result }}" == "failure" ]; then | |
| echo "❌ Manifest validation failed" | |
| FAILED=true | |
| fi | |
| # IDE Sync: fail if ran and didn't succeed | |
| if [ "${{ needs.ide-sync-validation.result }}" == "failure" ]; then | |
| echo "❌ IDE sync validation failed" | |
| FAILED=true | |
| fi | |
| if [ "$FAILED" == "true" ]; then | |
| echo "" | |
| echo "❌ One or more validation checks failed" | |
| exit 1 | |
| fi | |
| echo "✅ All validation checks passed (skipped jobs are OK when no relevant changes)" | |
| # Performance monitoring (optional, informational only) | |
| performance: | |
| name: Performance Metrics | |
| needs: changes | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' && needs.changes.outputs.code == 'true' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| cache-dependency-path: package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Measure validation performance | |
| run: | | |
| echo "=== Validation Performance Metrics ===" | |
| echo "ESLint execution time:" | |
| time npm run lint || true | |
| echo -e "\nTypeScript execution time:" | |
| time npm run typecheck || true | |
| echo -e "\nStory validation time:" | |
| time node .aios-core/utils/aios-validator.js stories || true | |
| continue-on-error: true | |
| # Cross-platform testing - ONLY on main branch push | |
| # Moved from cross-platform-tests.yml (Story 6.1) | |
| cross-platform: | |
| name: Cross-Platform (${{ matrix.os }}, Node ${{ matrix.node }}) | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| needs: [changes, lint, typecheck, test] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| node: ['18', '20', '22', '24'] | |
| # All combinations supported for Node.js 18-24 (isolated-vm removed in v3.11.0) | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js ${{ matrix.node }} | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ matrix.node }} | |
| cache: 'npm' | |
| cache-dependency-path: package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run tests | |
| run: npm test | |
| - name: Test CLI installation | |
| run: npm link | |
| continue-on-error: true | |
| - name: Test CLI basic commands | |
| run: | | |
| npx aios-core --version || echo "CLI version check skipped" | |
| npx aios-core --help || echo "CLI help check skipped" | |
| continue-on-error: true |