fix(docs): fix GitHub Pages links and CI/CD workflow #29
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: 🚀 Release & Publish | |
| on: | |
| push: | |
| branches: [ main ] | |
| workflow_dispatch: | |
| inputs: | |
| release_type: | |
| description: 'Release type (auto, patch, minor, major)' | |
| required: false | |
| default: 'auto' | |
| type: choice | |
| options: | |
| - auto | |
| - patch | |
| - minor | |
| - major | |
| dry_run: | |
| description: 'Dry run (no actual release)' | |
| required: false | |
| default: false | |
| type: boolean | |
| concurrency: | |
| group: release-${{ github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| # ============================================================================ | |
| # RELEASE VALIDATION | |
| # ============================================================================ | |
| validate-release: | |
| name: 🔍 Validate Release Readiness | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| outputs: | |
| should-release: ${{ steps.check.outputs.should-release }} | |
| release-type: ${{ steps.check.outputs.release-type }} | |
| steps: | |
| - name: 📥 Checkout Repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: 🟢 Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: 📦 Install Dependencies | |
| run: npm ci --prefer-offline --no-audit | |
| - name: 🔍 Check Release Conditions | |
| id: check | |
| run: | | |
| # Check if this is a manual dispatch with dry run | |
| if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ inputs.dry_run }}" == "true" ]]; then | |
| echo "should-release=dry-run" >> $GITHUB_OUTPUT | |
| echo "release-type=${{ inputs.release_type }}" >> $GITHUB_OUTPUT | |
| echo "🧪 Dry run mode enabled" | |
| exit 0 | |
| fi | |
| # Enhanced commit analysis for PR merges | |
| echo "🔍 Analyzing commits for release eligibility..." | |
| # Get the last release tag | |
| LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") | |
| if [[ -z "$LAST_TAG" ]]; then | |
| echo "📝 No previous tags found, checking last 10 commits" | |
| COMMIT_RANGE="HEAD~10..HEAD" | |
| else | |
| echo "📝 Last release: $LAST_TAG" | |
| COMMIT_RANGE="$LAST_TAG..HEAD" | |
| fi | |
| # Check for conventional commits that warrant a release | |
| RELEASABLE_COMMITS=$(git log $COMMIT_RANGE --oneline --grep="^feat" --grep="^fix" --grep="^perf" --grep="^revert" --grep="BREAKING CHANGE" --extended-regexp) | |
| # Also check commit messages directly (for squashed PR merges) | |
| CONVENTIONAL_COMMITS=$(git log $COMMIT_RANGE --pretty=format:"%s" | grep -E '^(feat|fix|perf|revert)(\(.+\))?!?:' || true) | |
| BREAKING_CHANGES=$(git log $COMMIT_RANGE --pretty=format:"%B" | grep -E 'BREAKING CHANGE|BREAKING:' || true) | |
| if [[ -n "$RELEASABLE_COMMITS" ]] || [[ -n "$CONVENTIONAL_COMMITS" ]] || [[ -n "$BREAKING_CHANGES" ]]; then | |
| echo "should-release=true" >> $GITHUB_OUTPUT | |
| echo "release-type=auto" >> $GITHUB_OUTPUT | |
| echo "✅ Releasable changes detected:" | |
| [[ -n "$CONVENTIONAL_COMMITS" ]] && echo " 📝 Conventional commits found" | |
| [[ -n "$BREAKING_CHANGES" ]] && echo " 💥 Breaking changes found" | |
| [[ -n "$RELEASABLE_COMMITS" ]] && echo " 🔄 Releasable commits found" | |
| else | |
| echo "should-release=false" >> $GITHUB_OUTPUT | |
| echo "release-type=none" >> $GITHUB_OUTPUT | |
| echo "ℹ️ No releasable changes found in range $COMMIT_RANGE" | |
| echo "💡 Tip: Use conventional commits (feat:, fix:, etc.) to trigger releases" | |
| fi | |
| # Log recent commits for debugging | |
| echo "📋 Recent commits analyzed:" | |
| git log $COMMIT_RANGE --oneline --max-count=5 || echo "No commits in range" | |
| - name: 🔨 Build & Test | |
| if: steps.check.outputs.should-release != 'false' | |
| timeout-minutes: 10 | |
| run: | | |
| npm run build | |
| npm run test:unit:fast | |
| npm run lint:check | |
| npm run type-check | |
| echo "✅ Pre-release validation completed" | |
| # ============================================================================ | |
| # SEMANTIC RELEASE | |
| # ============================================================================ | |
| semantic-release: | |
| name: 📦 Semantic Release | |
| runs-on: ubuntu-latest | |
| needs: validate-release | |
| if: needs.validate-release.outputs.should-release != 'false' | |
| timeout-minutes: 15 | |
| permissions: | |
| contents: write | |
| issues: write | |
| pull-requests: write | |
| id-token: write | |
| outputs: | |
| released: ${{ steps.release.outputs.released }} | |
| version: ${{ steps.release.outputs.version }} | |
| major: ${{ steps.release.outputs.major }} | |
| minor: ${{ steps.release.outputs.minor }} | |
| patch: ${{ steps.release.outputs.patch }} | |
| steps: | |
| - name: 📥 Checkout Repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: 🟢 Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: 📦 Install Dependencies | |
| run: npm ci --prefer-offline --no-audit | |
| - name: 🔨 Build Production Assets | |
| run: | | |
| npm run build:clean | |
| npm run build:standalone | |
| npm run build:templates | |
| echo "✅ Production build completed" | |
| - name: 📋 Create Distribution Package | |
| run: | | |
| mkdir -p dist | |
| npm pack --pack-destination=dist | |
| echo "✅ Distribution package created" | |
| - name: 📚 Generate Documentation | |
| run: | | |
| npm run docs:generate | |
| echo "✅ Documentation generated" | |
| - name: 🚀 Semantic Release | |
| id: release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| run: | | |
| if [[ "${{ needs.validate-release.outputs.should-release }}" == "dry-run" ]]; then | |
| echo "🧪 Running semantic-release in dry-run mode" | |
| npm run release:dry | |
| echo "released=false" >> $GITHUB_OUTPUT | |
| echo "version=dry-run" >> $GITHUB_OUTPUT | |
| else | |
| echo "🚀 Running semantic-release" | |
| npm run release | |
| # Check if a release was actually created | |
| if git describe --tags --exact-match HEAD 2>/dev/null; then | |
| NEW_VERSION=$(git describe --tags --exact-match HEAD | sed 's/^v//') | |
| echo "released=true" >> $GITHUB_OUTPUT | |
| echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT | |
| echo "major=$(echo $NEW_VERSION | cut -d. -f1)" >> $GITHUB_OUTPUT | |
| echo "minor=$(echo $NEW_VERSION | cut -d. -f2)" >> $GITHUB_OUTPUT | |
| echo "patch=$(echo $NEW_VERSION | cut -d. -f3)" >> $GITHUB_OUTPUT | |
| echo "✅ Released version $NEW_VERSION" | |
| else | |
| echo "released=false" >> $GITHUB_OUTPUT | |
| echo "version=none" >> $GITHUB_OUTPUT | |
| echo "ℹ️ No release created (no releasable changes)" | |
| fi | |
| fi | |
| - name: 📊 Release Summary | |
| run: | | |
| echo "## 🚀 Release Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY | |
| echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| Released | ${{ steps.release.outputs.released }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Version | ${{ steps.release.outputs.version }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Trigger | ${{ github.event_name }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Branch | ${{ github.ref_name }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Commit | ${{ github.sha }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [[ "${{ steps.release.outputs.released }}" == "true" ]]; then | |
| echo "🎉 **Successfully released version ${{ steps.release.outputs.version }}!**" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### 📦 Package Information" >> $GITHUB_STEP_SUMMARY | |
| echo "- **NPM Package**: [@dipseth/dataproc-mcp-server@${{ steps.release.outputs.version }}](https://www.npmjs.com/package/@dipseth/dataproc-mcp-server/v/${{ steps.release.outputs.version }})" >> $GITHUB_STEP_SUMMARY | |
| echo "- **GitHub Release**: [v${{ steps.release.outputs.version }}](https://github.com/${{ github.repository }}/releases/tag/v${{ steps.release.outputs.version }})" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Installation**: \`npm install @dipseth/dataproc-mcp-server@${{ steps.release.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "ℹ️ **No release created** - No releasable changes detected." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # ============================================================================ | |
| # DOCUMENTATION UPDATE | |
| # ============================================================================ | |
| update-documentation: | |
| name: 📚 Update Documentation | |
| runs-on: ubuntu-latest | |
| needs: semantic-release | |
| if: needs.semantic-release.outputs.released == 'true' | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - name: 📥 Checkout Repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: 🟢 Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: 📦 Install Dependencies | |
| run: npm ci --prefer-offline --no-audit | |
| - name: 📝 Update README Version Badges | |
| run: | | |
| echo "📝 Updating README version badges..." | |
| NEW_VERSION="${{ needs.semantic-release.outputs.version }}" | |
| # Update npm version badge | |
| sed -i "s|npm/v/@dipseth/dataproc-mcp-server\.svg|npm/v/@dipseth/dataproc-mcp-server.svg|g" README.md | |
| # Update package references in README | |
| sed -i "s|@dipseth/dataproc-mcp-server@[0-9]\+\.[0-9]\+\.[0-9]\+|@dipseth/dataproc-mcp-server@$NEW_VERSION|g" README.md | |
| # Update installation commands | |
| sed -i "s|npm install -g @dataproc/mcp-server|npm install -g @dipseth/dataproc-mcp-server@$NEW_VERSION|g" README.md | |
| echo "✅ README version badges updated to v$NEW_VERSION" | |
| - name: 📚 Update Documentation Links | |
| run: | | |
| echo "📚 Updating documentation links..." | |
| NEW_VERSION="${{ needs.semantic-release.outputs.version }}" | |
| # Update package.json version references in docs | |
| find docs/ -name "*.md" -type f -exec sed -i "s|@dipseth/dataproc-mcp-server@[0-9]\+\.[0-9]\+\.[0-9]\+|@dipseth/dataproc-mcp-server@$NEW_VERSION|g" {} \; | |
| # Update docs/index.md with latest version | |
| if [ -f "docs/index.md" ]; then | |
| sed -i "s|version: [0-9]\+\.[0-9]\+\.[0-9]\+|version: $NEW_VERSION|g" docs/index.md | |
| fi | |
| echo "✅ Documentation links updated" | |
| - name: 🔄 Regenerate Documentation | |
| run: | | |
| echo "🔄 Regenerating documentation..." | |
| # Regenerate API documentation with new version | |
| npm run docs:generate | |
| # Update GitHub Pages if needed | |
| if [ -f "docs/_config.yml" ]; then | |
| sed -i "s|version: [0-9]\+\.[0-9]\+\.[0-9]\+|version: ${{ needs.semantic-release.outputs.version }}|g" docs/_config.yml | |
| fi | |
| echo "✅ Documentation regenerated" | |
| - name: 📊 Update Package Metrics | |
| run: | | |
| echo "📊 Updating package metrics..." | |
| NEW_VERSION="${{ needs.semantic-release.outputs.version }}" | |
| # Create or update package info file | |
| cat > docs/package-info.json << EOF | |
| { | |
| "name": "@dipseth/dataproc-mcp-server", | |
| "version": "$NEW_VERSION", | |
| "released": "$(date -u +%Y-%m-%dT%H:%M:%SZ)", | |
| "npmUrl": "https://www.npmjs.com/package/@dipseth/dataproc-mcp-server/v/$NEW_VERSION", | |
| "githubRelease": "https://github.com/${{ github.repository }}/releases/tag/v$NEW_VERSION", | |
| "installCommand": "npm install @dipseth/dataproc-mcp-server@$NEW_VERSION" | |
| } | |
| EOF | |
| echo "✅ Package metrics updated" | |
| - name: 🚀 Update NPM Documentation | |
| run: | | |
| echo "🚀 Updating NPM package documentation..." | |
| # Ensure package.json has correct repository and homepage URLs | |
| npm pkg set homepage="https://dipseth.github.io/dataproc-mcp/" | |
| npm pkg set repository.url="git+https://github.com/${{ github.repository }}.git" | |
| npm pkg set bugs.url="https://github.com/${{ github.repository }}/issues" | |
| # Update package keywords for better discoverability | |
| npm pkg set keywords='["mcp", "dataproc", "google-cloud", "model-context-protocol", "typescript", "nodejs"]' | |
| echo "✅ NPM documentation metadata updated" | |
| - name: 📝 Create Documentation Update Summary | |
| run: | | |
| echo "## 📚 Documentation Update Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "Updated documentation for version **v${{ needs.semantic-release.outputs.version }}**:" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### ✅ Updated Components" >> $GITHUB_STEP_SUMMARY | |
| echo "- 📝 README.md version badges and installation commands" >> $GITHUB_STEP_SUMMARY | |
| echo "- 📚 Documentation links and version references" >> $GITHUB_STEP_SUMMARY | |
| echo "- 🔄 Regenerated API documentation" >> $GITHUB_STEP_SUMMARY | |
| echo "- 📊 Package metrics and metadata" >> $GITHUB_STEP_SUMMARY | |
| echo "- 🚀 NPM package documentation" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### 🔗 Updated Links" >> $GITHUB_STEP_SUMMARY | |
| echo "- **NPM Package**: [v${{ needs.semantic-release.outputs.version }}](https://www.npmjs.com/package/@dipseth/dataproc-mcp-server/v/${{ needs.semantic-release.outputs.version }})" >> $GITHUB_STEP_SUMMARY | |
| echo "- **GitHub Pages**: [Documentation](https://dipseth.github.io/dataproc-mcp/)" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Installation**: \`npm install @dipseth/dataproc-mcp-server@${{ needs.semantic-release.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY | |
| - name: 💾 Commit Documentation Updates | |
| run: | | |
| # Configure git | |
| git config --local user.email "action@github.com" | |
| git config --local user.name "GitHub Action" | |
| # Check if there are changes to commit | |
| if git diff --quiet && git diff --staged --quiet; then | |
| echo "ℹ️ No documentation changes to commit" | |
| else | |
| echo "📝 Committing documentation updates..." | |
| git add . | |
| git commit -m "docs: update documentation for v${{ needs.semantic-release.outputs.version }} | |
| - Update README version badges and installation commands | |
| - Update documentation links and version references | |
| - Regenerate API documentation | |
| - Update package metrics and NPM metadata | |
| [skip ci]" | |
| # Pull latest changes to avoid non-fast-forward errors | |
| echo "🔄 Pulling latest changes..." | |
| git pull origin main --rebase | |
| # Push with retry logic | |
| echo "🚀 Pushing documentation updates..." | |
| for i in {1..3}; do | |
| if git push origin main; then | |
| echo "✅ Documentation updates committed and pushed" | |
| break | |
| else | |
| echo "⚠️ Push failed (attempt $i/3), retrying..." | |
| git pull origin main --rebase | |
| sleep 2 | |
| fi | |
| done | |
| fi | |
| # ============================================================================ | |
| # POST-RELEASE VALIDATION | |
| # ============================================================================ | |
| post-release-validation: | |
| name: ✅ Post-Release Validation | |
| runs-on: ubuntu-latest | |
| needs: [semantic-release, update-documentation] | |
| if: needs.semantic-release.outputs.released == 'true' | |
| timeout-minutes: 10 | |
| steps: | |
| - name: 📥 Checkout Repository | |
| uses: actions/checkout@v4 | |
| - name: 🟢 Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: 🔍 Verify NPM Package | |
| run: | | |
| echo "🔍 Verifying NPM package publication..." | |
| # Wait for NPM registry propagation | |
| sleep 30 | |
| # Check if package is available | |
| PACKAGE_VERSION="${{ needs.semantic-release.outputs.version }}" | |
| if npm view @dipseth/dataproc-mcp-server@$PACKAGE_VERSION version; then | |
| echo "✅ Package @dipseth/dataproc-mcp-server@$PACKAGE_VERSION is available on NPM" | |
| else | |
| echo "❌ Package not found on NPM registry" | |
| exit 1 | |
| fi | |
| - name: 🧪 Test Package Installation | |
| run: | | |
| echo "🧪 Testing package installation..." | |
| # Create temporary directory and test installation | |
| mkdir -p /tmp/test-install | |
| cd /tmp/test-install | |
| npm init -y | |
| npm install @dipseth/dataproc-mcp-server@${{ needs.semantic-release.outputs.version }} | |
| # Verify installation | |
| if [ -f "node_modules/@dipseth/dataproc-mcp-server/package.json" ]; then | |
| echo "✅ Package installation successful" | |
| INSTALLED_VERSION=$(node -p "require('./node_modules/@dipseth/dataproc-mcp-server/package.json').version") | |
| echo "📦 Installed version: $INSTALLED_VERSION" | |
| else | |
| echo "❌ Package installation failed" | |
| exit 1 | |
| fi | |
| - name: 🔗 Verify GitHub Release | |
| run: | | |
| echo "🔗 Verifying GitHub release..." | |
| # Check if GitHub release exists | |
| RELEASE_TAG="v${{ needs.semantic-release.outputs.version }}" | |
| if gh release view $RELEASE_TAG --repo ${{ github.repository }}; then | |
| echo "✅ GitHub release $RELEASE_TAG exists" | |
| else | |
| echo "❌ GitHub release not found" | |
| exit 1 | |
| fi | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # ============================================================================ | |
| # NOTIFICATION & CLEANUP | |
| # ============================================================================ | |
| notify-success: | |
| name: 📢 Success Notification | |
| runs-on: ubuntu-latest | |
| needs: [semantic-release, post-release-validation] | |
| if: needs.semantic-release.outputs.released == 'true' && needs.post-release-validation.result == 'success' | |
| steps: | |
| - name: 🎉 Success Notification | |
| run: | | |
| echo "## 🎉 Release v${{ needs.semantic-release.outputs.version }} Successfully Published!" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### 📦 Package Details" >> $GITHUB_STEP_SUMMARY | |
| echo "- **NPM Package**: [@dipseth/dataproc-mcp-server@${{ needs.semantic-release.outputs.version }}](https://www.npmjs.com/package/@dipseth/dataproc-mcp-server)" >> $GITHUB_STEP_SUMMARY | |
| echo "- **GitHub Release**: [v${{ needs.semantic-release.outputs.version }}](https://github.com/${{ github.repository }}/releases/tag/v${{ needs.semantic-release.outputs.version }})" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Installation**: \`npm install @dipseth/dataproc-mcp-server@latest\`" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### 🚀 Next Steps" >> $GITHUB_STEP_SUMMARY | |
| echo "1. Update documentation if needed" >> $GITHUB_STEP_SUMMARY | |
| echo "2. Announce the release to the community" >> $GITHUB_STEP_SUMMARY | |
| echo "3. Monitor for any issues or feedback" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**The Dataproc MCP Server v${{ needs.semantic-release.outputs.version }} is now live! 🚀**" >> $GITHUB_STEP_SUMMARY | |
| notify-failure: | |
| name: ❌ Failure Notification | |
| runs-on: ubuntu-latest | |
| needs: [semantic-release, post-release-validation] | |
| if: failure() | |
| steps: | |
| - name: ❌ Failure Notification | |
| run: | | |
| echo "## ❌ Release Process Failed" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "The release process encountered an error. Please check the workflow logs for details." >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### 🔍 Troubleshooting Steps" >> $GITHUB_STEP_SUMMARY | |
| echo "1. Check the failed job logs above" >> $GITHUB_STEP_SUMMARY | |
| echo "2. Verify NPM_TOKEN secret is configured" >> $GITHUB_STEP_SUMMARY | |
| echo "3. Ensure semantic-release configuration is correct" >> $GITHUB_STEP_SUMMARY | |
| echo "4. Check for any blocking issues in the repository" >> $GITHUB_STEP_SUMMARY |