Merge pull request #20 from RaoUsama7/fix/link-cache-invalidation #59
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 | |
| on: | |
| pull_request: | |
| branches: [main] | |
| push: | |
| branches: [main] | |
| # Cancel in-progress runs for the same workflow and PR/branch | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| lint-and-typecheck: | |
| name: Lint & Type Check | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| 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: Type check | |
| run: npx tsc --noEmit | |
| - name: Check for lint script | |
| id: check-lint | |
| run: | | |
| if grep -q '"lint"' package.json; then | |
| echo "has_lint=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "has_lint=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Lint code | |
| if: steps.check-lint.outputs.has_lint == 'true' | |
| run: npm run lint | |
| test: | |
| name: Test (Node ${{ matrix.node }}) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| strategy: | |
| matrix: | |
| node: ['18', '20', '22'] | |
| fail-fast: false | |
| 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' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run tests | |
| run: npm test | |
| - name: Generate coverage report | |
| if: matrix.node == '20' | |
| run: npm test -- --coverage | |
| - name: Upload coverage reports to Codecov | |
| if: matrix.node == '20' | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ./coverage/lcov.info | |
| fail_ci_if_error: false | |
| flags: unittests | |
| name: codecov-umbrella | |
| build: | |
| name: Build Package | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| 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: Build package | |
| run: npm run build | |
| - name: Check build artifacts | |
| run: | | |
| if [ ! -d "dist" ]; then | |
| echo "Error: dist directory not found" | |
| exit 1 | |
| fi | |
| if [ ! -f "dist/index.js" ]; then | |
| echo "Error: dist/index.js not found" | |
| exit 1 | |
| fi | |
| if [ ! -f "dist/index.d.ts" ]; then | |
| echo "Error: dist/index.d.ts not found" | |
| exit 1 | |
| fi | |
| echo "Build artifacts verified successfully" | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| retention-days: 7 | |
| # Validate package.json and exports | |
| package-validation: | |
| name: Validate Package | |
| runs-on: ubuntu-latest | |
| needs: build | |
| timeout-minutes: 10 | |
| 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: Download build artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| - name: Validate package exports | |
| run: | | |
| # Check if all exports in package.json exist | |
| node -e " | |
| const pkg = require('./package.json'); | |
| const fs = require('fs'); | |
| const exports = pkg.exports || {}; | |
| let hasErrors = false; | |
| for (const [key, value] of Object.entries(exports)) { | |
| const filePath = value.replace('./', ''); | |
| if (!fs.existsSync(filePath)) { | |
| console.error(\`❌ Export '\${key}' points to missing file: \${filePath}\`); | |
| hasErrors = true; | |
| } else { | |
| console.log(\`✓ Export '\${key}' -> \${filePath}\`); | |
| } | |
| } | |
| if (hasErrors) { | |
| process.exit(1); | |
| } | |
| console.log('\\n✅ All package exports are valid'); | |
| " | |
| - name: Test package installation | |
| run: | | |
| # Create a temporary directory | |
| mkdir -p /tmp/test-install | |
| cd /tmp/test-install | |
| # Initialize a test project | |
| npm init -y | |
| # Install the package from the build | |
| npm install ${{ github.workspace }} | |
| # Try to import the package | |
| node -e " | |
| const core = require('@linkforty/core'); | |
| console.log('✓ Package imported successfully'); | |
| console.log('Exports:', Object.keys(core)); | |
| " | |
| # All checks must pass | |
| ci-success: | |
| name: CI Success | |
| runs-on: ubuntu-latest | |
| needs: [lint-and-typecheck, test, build, package-validation] | |
| if: always() | |
| steps: | |
| - name: Check job results | |
| run: | | |
| if [[ "${{ needs.lint-and-typecheck.result }}" != "success" ]] || \ | |
| [[ "${{ needs.test.result }}" != "success" ]] || \ | |
| [[ "${{ needs.build.result }}" != "success" ]] || \ | |
| [[ "${{ needs.package-validation.result }}" != "success" ]]; then | |
| echo "One or more CI jobs failed" | |
| exit 1 | |
| fi | |
| echo "All CI checks passed!" |