diff --git a/.github/matchers/eslint.json b/.github/matchers/eslint.json new file mode 100644 index 0000000..56090a1 --- /dev/null +++ b/.github/matchers/eslint.json @@ -0,0 +1,22 @@ +{ + "problemMatcher": [ + { + "owner": "eslint-stylish", + "pattern": [ + { + "regexp": "^(.+)$", + "file": 1 + }, + { + "regexp": "^\\s+(\\d+):(\\d+)\\s+(error|warning)\\s+(.+?)\\s{2,}(.+)$", + "line": 1, + "column": 2, + "severity": 3, + "message": 4, + "code": 5, + "loop": true + } + ] + } + ] +} diff --git a/.github/matchers/tsc.json b/.github/matchers/tsc.json new file mode 100644 index 0000000..0e5ed2d --- /dev/null +++ b/.github/matchers/tsc.json @@ -0,0 +1,18 @@ +{ + "problemMatcher": [ + { + "owner": "tsc", + "pattern": [ + { + "regexp": "^(.+)\\((\\d+),(\\d+)\\):\\s+(error|warning)\\s+(TS\\d+):\\s+(.+)$", + "file": 1, + "line": 2, + "column": 3, + "severity": 4, + "code": 5, + "message": 6 + } + ] + } + ] +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3bffdec..c12d020 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,54 +2,148 @@ name: CI on: push: - branches: [ main, develop ] + branches: [main, develop] pull_request: - branches: [ main, develop ] + branches: [main, develop] + +# Cancel in-progress runs for the same PR/branch +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true jobs: - build-and-test: - runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - node-version: ['20'] - + # ============================================ + # LINT - ESLint with GitHub annotations + # ============================================ + lint: + name: Lint + runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - - - name: Setup Node.js ${{ matrix.node-version }} + + - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - + node-version: "20" + cache: "npm" + - name: Install dependencies run: npm ci - - - name: Run type check + + # Setup ESLint problem matcher for annotations + - name: Setup ESLint problem matcher + run: echo "::add-matcher::.github/matchers/eslint.json" + + - name: Run ESLint + run: npm run lint -- --format stylish + + # ============================================ + # TYPE CHECK - TypeScript compiler + # ============================================ + type-check: + name: Type Check + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install dependencies + run: npm ci + + # Setup TypeScript problem matcher for annotations + - name: Setup TypeScript problem matcher + run: echo "::add-matcher::.github/matchers/tsc.json" + + - name: Run TypeScript type check run: npm run type-check - - - name: Run lint - run: npm run lint - + + # ============================================ + # BUILD - Compile extension and webviews + # ============================================ + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install dependencies + run: npm ci + - name: Compile extension run: npm run compile - + - name: Compile webviews run: npm run compile:webview - - # Note: We don't inject telemetry secrets for CI builds - # The extension handles missing connection strings gracefully - - name: Package extension (without telemetry) + + - name: Package extension run: npm run package - + - name: Upload build artifacts - if: matrix.os == 'ubuntu-latest' uses: actions/upload-artifact@v4 with: - name: dev-buddy-ci-build - path: '*.vsix' + name: dev-buddy-${{ github.sha }} + path: "*.vsix" retention-days: 7 + # ============================================ + # TESTS - Unit and integration tests + # (Uncomment when tests are added) + # ============================================ + # tests: + # name: Tests + # runs-on: ubuntu-latest + # steps: + # - name: Checkout code + # uses: actions/checkout@v4 + # + # - name: Setup Node.js + # uses: actions/setup-node@v4 + # with: + # node-version: "20" + # cache: "npm" + # + # - name: Install dependencies + # run: npm ci + # + # - name: Run tests with coverage + # run: npm run test:coverage + # + # - name: Upload coverage reports + # uses: codecov/codecov-action@v4 + # with: + # files: ./coverage/lcov.info + # fail_ci_if_error: false + # verbose: true + + # ============================================ + # CI SUCCESS - Gate for branch protection + # ============================================ + ci-success: + name: CI Success + runs-on: ubuntu-latest + needs: [lint, type-check, build] + if: always() + steps: + - name: Check all jobs passed + run: | + if [[ "${{ needs.lint.result }}" != "success" ]] || \ + [[ "${{ needs.type-check.result }}" != "success" ]] || \ + [[ "${{ needs.build.result }}" != "success" ]]; then + echo "❌ One or more CI jobs failed" + exit 1 + fi + echo "✅ All CI jobs passed" diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 0000000..39ba9f5 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,91 @@ +name: Nightly Build + +on: + # Run every day at 2 AM UTC + schedule: + - cron: "0 2 * * *" + # Allow manual trigger + workflow_dispatch: + +jobs: + # ============================================ + # MULTI-PLATFORM BUILD & TEST + # Full matrix testing on all platforms + # ============================================ + nightly-build: + name: Build (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + node-version: ["20"] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Run type check + run: npm run type-check + + - name: Run lint + run: npm run lint + + - name: Compile extension + run: npm run compile + + - name: Compile webviews + run: npm run compile:webview + + # Note: We don't inject telemetry secrets for nightly builds + # The extension handles missing connection strings gracefully + - name: Package extension + run: npm run package + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: dev-buddy-nightly-${{ matrix.os }}-${{ github.run_number }} + path: "*.vsix" + retention-days: 7 + + # ============================================ + # NIGHTLY SUMMARY + # ============================================ + nightly-summary: + name: Summary + runs-on: ubuntu-latest + needs: [nightly-build] + if: always() + steps: + - name: Generate summary + run: | + echo "## 🌙 Nightly Build Results" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| Platform | Status |" >> $GITHUB_STEP_SUMMARY + echo "|----------|--------|" >> $GITHUB_STEP_SUMMARY + + # Check matrix job results + if [[ "${{ needs.nightly-build.result }}" == "success" ]]; then + echo "| All Platforms | ✅ Passed |" >> $GITHUB_STEP_SUMMARY + else + echo "| Some Platforms | ❌ Failed |" >> $GITHUB_STEP_SUMMARY + fi + + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Run:** #${{ github.run_number }}" >> $GITHUB_STEP_SUMMARY + echo "**Triggered by:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY + + - name: Notify on failure + if: needs.nightly-build.result == 'failure' + run: | + echo "::warning::Nightly build failed! Check the workflow logs for details." diff --git a/.gitignore b/.gitignore index 5d5e6ce..eafc225 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,12 @@ test-env/**/.env # TypeScript *.tsbuildinfo +*.js.map + +# Test output +test/unit/**/*.js +test/unit/**/*.js.map +coverage/ # Test environments (Docker-based testing) test-env/**/data/ diff --git a/package-lock.json b/package-lock.json index ba16adf..712ce83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dev-buddy", - "version": "0.8.1", + "version": "0.8.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dev-buddy", - "version": "0.8.1", + "version": "0.8.3", "license": "SEE LICENSE IN LICENSE", "dependencies": { "@tiptap/extension-bubble-menu": "^3.13.0",