Skip to main content
Glama

π“‚€π“’π“‹Ήπ”Έβ„•π•Œπ”Ήπ•€π•Šπ“‹Ήπ“’π“‚€ - Intelligent Guidance for

by Hive-Academy
npm-publish.ymlβ€’19.8 kB
name: Build and Publish NPM Package on: pull_request: branches: [publish-npm] release: types: [published] # Manual trigger for emergency releases workflow_dispatch: inputs: version_type: description: 'Version bump type' required: true default: 'patch' type: choice options: - patch - minor - major skip_tests: description: 'Skip tests (emergency only)' required: false default: false type: boolean force_version: description: 'Force specific version (optional)' required: false type: string # Make this workflow reusable workflow_call: inputs: version_type: description: 'Version bump type' required: false default: 'patch' type: string skip_tests: description: 'Skip tests (emergency only)' required: false default: false type: boolean force_version: description: 'Force specific version (optional)' required: false type: string env: NPM_REGISTRY: https://registry.npmjs.org/ PACKAGE_NAME: '@hive-academy/anubis' DATABASE_URL: 'file:./prisma/.anubis/workflow.db' jobs: validate-and-publish: runs-on: ubuntu-latest permissions: contents: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v4 with: # Need full history for version bumping fetch-depth: 0 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' registry-url: ${{ env.NPM_REGISTRY }} - name: Install dependencies run: npm ci - name: Run tests if: ${{ !inputs.skip_tests }} run: npm test # =================================================================== # πŸ€– INTELLIGENT VERSION MANAGEMENT # =================================================================== - name: Intelligent version resolution id: version_resolution run: | echo "πŸ€– Starting intelligent version resolution..." # Get current versions CURRENT_NPM_VERSION=$(npm view ${{ env.PACKAGE_NAME }} version 2>/dev/null || echo "0.0.0") CURRENT_LOCAL_VERSION=$(node -p "require('./package.json').version") echo "πŸ“¦ Current NPM version: $CURRENT_NPM_VERSION" echo "πŸ“¦ Current local version: $CURRENT_LOCAL_VERSION" # Store original versions echo "npm_version=$CURRENT_NPM_VERSION" >> $GITHUB_OUTPUT echo "local_version=$CURRENT_LOCAL_VERSION" >> $GITHUB_OUTPUT # Determine target version TARGET_VERSION="$CURRENT_LOCAL_VERSION" VERSION_STRATEGY="use-local" # Handle forced version if [ -n "${{ inputs.force_version }}" ]; then TARGET_VERSION="${{ inputs.force_version }}" VERSION_STRATEGY="forced" echo "🎯 Using forced version: $TARGET_VERSION" # Handle workflow dispatch (manual bump) elif [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ inputs.version_type }}" ]; then git config --local user.email "action@github.com" git config --local user.name "GitHub Action" # Bump version npm version ${{ inputs.version_type }} --no-git-tag-version TARGET_VERSION=$(node -p "require('./package.json').version") VERSION_STRATEGY="manual-bump" echo "πŸ”„ Version bumped (${{ inputs.version_type }}): $TARGET_VERSION" fi # Check for version conflicts echo "πŸ” Checking version conflicts..." if npm view ${{ env.PACKAGE_NAME }}@$TARGET_VERSION version >/dev/null 2>&1; then echo "⚠️ Version conflict detected: $TARGET_VERSION already exists on NPM" # Auto-resolve conflict by finding next available version echo "πŸ€– Auto-resolving version conflict..." # Parse version components IFS='.' read -r MAJOR MINOR PATCH <<< "$TARGET_VERSION" # Try incrementing patch version until we find an available one ATTEMPT_COUNT=0 MAX_ATTEMPTS=50 while [ $ATTEMPT_COUNT -lt $MAX_ATTEMPTS ]; do NEW_PATCH=$((PATCH + ATTEMPT_COUNT + 1)) CANDIDATE_VERSION="$MAJOR.$MINOR.$NEW_PATCH" echo "πŸ” Testing version: $CANDIDATE_VERSION" if ! npm view ${{ env.PACKAGE_NAME }}@$CANDIDATE_VERSION version >/dev/null 2>&1; then TARGET_VERSION="$CANDIDATE_VERSION" VERSION_STRATEGY="auto-resolved" echo "βœ… Found available version: $TARGET_VERSION" break fi ATTEMPT_COUNT=$((ATTEMPT_COUNT + 1)) done if [ $ATTEMPT_COUNT -eq $MAX_ATTEMPTS ]; then echo "❌ Could not find available version after $MAX_ATTEMPTS attempts" echo "πŸ’‘ Consider using a manual version bump or different strategy" exit 1 fi # Update package.json with resolved version npm version $TARGET_VERSION --no-git-tag-version echo "πŸ“ Updated package.json to version: $TARGET_VERSION" else echo "βœ… No version conflict - proceeding with: $TARGET_VERSION" fi # Store final version info echo "target_version=$TARGET_VERSION" >> $GITHUB_OUTPUT echo "version_strategy=$VERSION_STRATEGY" >> $GITHUB_OUTPUT echo "conflict_resolved=$([[ $VERSION_STRATEGY == "auto-resolved" ]] && echo "true" || echo "false")" >> $GITHUB_OUTPUT echo "🎯 Final target version: $TARGET_VERSION" echo "πŸ“‹ Version strategy: $VERSION_STRATEGY" - name: Commit version changes (if needed) if: steps.version_resolution.outputs.conflict_resolved == 'true' || github.event_name == 'workflow_dispatch' run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" if [ -n "$(git diff --name-only)" ]; then git add package.json package-lock.json git commit -m "πŸ€– Auto-resolve version conflict: ${{ steps.version_resolution.outputs.target_version }} - Strategy: ${{ steps.version_resolution.outputs.version_strategy }} - Previous NPM: ${{ steps.version_resolution.outputs.npm_version }} - Previous Local: ${{ steps.version_resolution.outputs.local_version }} - Resolved: ${{ steps.version_resolution.outputs.target_version }}" echo "πŸ“ Committed version resolution changes" fi # =================================================================== # πŸ“‹ PRE-PUBLISHING CHECKLIST AUTOMATION # =================================================================== - name: Database template verification run: | echo "πŸ” Verifying pre-seeded database template..." if [ -f "prisma/.anubis/workflow.db" ]; then DB_SIZE=$(ls -lh prisma/.anubis/workflow.db | awk '{print $5}') echo "βœ… Pre-seeded database found: $DB_SIZE" # Verify it's approximately the expected size (~589kB) DB_SIZE_BYTES=$(stat -f%z prisma/.anubis/workflow.db 2>/dev/null || stat -c%s prisma/.anubis/workflow.db) if [ $DB_SIZE_BYTES -gt 500000 ] && [ $DB_SIZE_BYTES -lt 700000 ]; then echo "βœ… Database size is within expected range (500kB-700kB)" else echo "⚠️ Database size ($DB_SIZE_BYTES bytes) is outside expected range" exit 1 fi else echo "❌ Pre-seeded database not found at prisma/.anubis/workflow.db" echo "πŸ”§ Regenerating database template..." mkdir -p prisma/data echo "πŸ”§ Setting up database URL: $DATABASE_URL" echo "πŸ—οΈ Creating database schema..." npx prisma db push --accept-data-loss echo "🌱 Seeding database..." npm run db:seed if [ -f "prisma/.anubis/workflow.db" ]; then echo "βœ… Database template regenerated successfully" else echo "❌ Failed to generate database template" exit 1 fi fi - name: Package size verification run: | echo "πŸ“¦ Verifying package size..." # Dry run to check what will be included echo "πŸ“‹ Package contents (dry run):" npm pack --dry-run # Create actual package and check size PACKAGE_FILE=$(npm pack) PACKAGE_SIZE=$(ls -lh $PACKAGE_FILE | awk '{print $5}') PACKAGE_SIZE_BYTES=$(stat -f%z $PACKAGE_FILE 2>/dev/null || stat -c%s $PACKAGE_FILE) echo "πŸ“¦ Package file: $PACKAGE_FILE" echo "πŸ“¦ Package size: $PACKAGE_SIZE ($PACKAGE_SIZE_BYTES bytes)" # Verify size is reasonable (~465kB, definitely under 10MB) if [ $PACKAGE_SIZE_BYTES -gt 10485760 ]; then # 10MB echo "❌ Package too large! Size: $PACKAGE_SIZE" echo "πŸ’‘ Check if 'generated/**/*' is properly excluded in package.json" exit 1 elif [ $PACKAGE_SIZE_BYTES -gt 1048576 ]; then # 1MB echo "⚠️ Package larger than expected: $PACKAGE_SIZE" echo "πŸ’‘ Expected size: ~465kB. Current size may include unnecessary files." else echo "βœ… Package size is reasonable: $PACKAGE_SIZE" fi # Clean up test package rm $PACKAGE_FILE - name: Build verification run: | echo "πŸ”§ Running clean build..." # This runs prepublishOnly automatically, but let's be explicit npm run prepublishOnly # Verify dist directory exists and has content if [ -d "dist" ] && [ "$(ls -A dist)" ]; then echo "βœ… Build successful - dist directory populated" echo "πŸ“ Dist contents:" ls -la dist/ else echo "❌ Build failed - dist directory missing or empty" exit 1 fi # Verify CLI entry point exists if [ -f "dist/cli.js" ]; then echo "βœ… CLI entry point exists: dist/cli.js" else echo "❌ CLI entry point missing: dist/cli.js" exit 1 fi - name: Prisma validation run: | echo "πŸ” Validating Prisma schema..." npx prisma validate echo "βœ… Prisma schema validation passed" # Verify generated folder is excluded if [ -d "generated" ]; then echo "⚠️ Generated folder exists - verifying it's excluded from package" if grep -q '"generated/\*\*/\*"' package.json; then echo "❌ Generated folder not properly excluded in package.json files array" exit 1 fi fi # =================================================================== # πŸš€ PUBLISHING PROCESS # =================================================================== - name: Publish to NPM (dry run for PRs) if: github.event_name == 'pull_request' run: | echo "πŸ§ͺ NPM Publish Dry Run (PR)" npm publish --dry-run echo "βœ… Dry run successful - package would publish correctly" - name: Publish to NPM if: github.event_name != 'pull_request' run: | echo "πŸš€ Publishing to NPM..." TARGET_VERSION="${{ steps.version_resolution.outputs.target_version }}" # Final conflict check before publish (double safety) if npm view ${{ env.PACKAGE_NAME }}@$TARGET_VERSION version >/dev/null 2>&1; then echo "❌ CRITICAL: Version $TARGET_VERSION still conflicts!" echo "This should not happen after version resolution." exit 1 fi npm publish --provenance echo "βœ… Successfully published ${{ env.PACKAGE_NAME }}@$TARGET_VERSION" env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # =================================================================== # πŸ“Š POST-PUBLISH VERIFICATION (Simplified) # =================================================================== - name: Post-publish verification if: github.event_name != 'pull_request' run: | echo "πŸ” Verifying NPM publication..." # Wait for NPM registry propagation echo "⏳ Waiting for NPM registry propagation (30 seconds)..." sleep 30 # Simple verification - just check if the package exists TARGET_VERSION="${{ steps.version_resolution.outputs.target_version }}" # Try to fetch package info (this is more reliable than version comparison) if npm view ${{ env.PACKAGE_NAME }}@$TARGET_VERSION version >/dev/null 2>&1; then echo "βœ… Package ${{ env.PACKAGE_NAME }}@$TARGET_VERSION is available on NPM" else echo "⚠️ Package may still be propagating across NPM CDN" echo "βœ… Publication completed successfully (registry propagation may take a few minutes)" fi - name: Test published package if: github.event_name != 'pull_request' run: | echo "πŸ§ͺ Testing published package..." # Create a temporary directory for testing mkdir -p /tmp/npm-test cd /tmp/npm-test # Test package installation and basic functionality echo "πŸ“¦ Testing package installation..." TARGET_VERSION="${{ steps.version_resolution.outputs.target_version }}" npx ${{ env.PACKAGE_NAME }}@$TARGET_VERSION --version echo "βœ… Published package test successful" - name: Generate package health report if: github.event_name != 'pull_request' run: | echo "πŸ“Š Generating package health report..." # Get package info NPM_INFO=$(npm view ${{ env.PACKAGE_NAME }} --json) VERSION=$(echo $NPM_INFO | jq -r '.version') SIZE=$(echo $NPM_INFO | jq -r '.dist.unpackedSize // "unknown"') TARBALL_SIZE=$(echo $NPM_INFO | jq -r '.dist.fileCount // "unknown"') echo "## πŸ“¦ NPM Package Health Report" >> $GITHUB_STEP_SUMMARY echo "- **Package:** \`${{ env.PACKAGE_NAME }}\`" >> $GITHUB_STEP_SUMMARY echo "- **Version:** \`$VERSION\`" >> $GITHUB_STEP_SUMMARY echo "- **Version Strategy:** ${{ steps.version_resolution.outputs.version_strategy }}" >> $GITHUB_STEP_SUMMARY if [ "${{ steps.version_resolution.outputs.conflict_resolved }}" = "true" ]; then echo "- **Conflict Resolution:** βœ… Auto-resolved from \`${{ steps.version_resolution.outputs.local_version }}\` to \`$VERSION\`" >> $GITHUB_STEP_SUMMARY fi echo "- **Unpacked Size:** $SIZE bytes" >> $GITHUB_STEP_SUMMARY echo "- **Registry:** NPM" >> $GITHUB_STEP_SUMMARY echo "- **Provenance:** βœ… Enabled" >> $GITHUB_STEP_SUMMARY echo "- **Database Template:** βœ… Pre-seeded (~589kB)" >> $GITHUB_STEP_SUMMARY echo "- **Runtime:** Prisma generation + database copying" >> $GITHUB_STEP_SUMMARY - name: Comment PR with package details if: github.event_name == 'pull_request' uses: actions/github-script@v7 with: script: | const output = `## πŸ“¦ NPM Package Build Results The NPM package has been built and validated successfully for this PR! **Package Details:** - **Name:** \`${{ env.PACKAGE_NAME }}\` - **Current NPM Version:** \`${{ steps.version_resolution.outputs.npm_version }}\` - **Local Version:** \`${{ steps.version_resolution.outputs.local_version }}\` - **Target Version:** \`${{ steps.version_resolution.outputs.target_version }}\` - **Version Strategy:** ${{ steps.version_resolution.outputs.version_strategy }} - **Size:** Optimized (~465kB, 99.5% reduction from 86MB) - **Database:** Pre-seeded workflow.db included **Validation Results:** - βœ… Database template verified (~589kB) - βœ… Package size within limits - βœ… Build artifacts generated - βœ… Prisma schema valid - βœ… Dry run publish successful ${steps.version_resolution.outputs.conflict_resolved === 'true' ? '- βœ… Version conflict auto-resolved' : ''} **Test Installation (after merge):** \`\`\`bash # Global installation npm install -g ${{ env.PACKAGE_NAME }}@${{ steps.version_resolution.outputs.target_version }} # Or run directly npx ${{ env.PACKAGE_NAME }}@${{ steps.version_resolution.outputs.target_version }} # MCP Server usage npx ${{ env.PACKAGE_NAME }}@${{ steps.version_resolution.outputs.target_version }} \`\`\` **Claude Desktop MCP Configuration:** \`\`\`json { "mcpServers": { "anubis": { "command": "npx", "args": ["${{ env.PACKAGE_NAME }}@${{ steps.version_resolution.outputs.target_version }}"] } } } \`\`\``; github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: output }); - name: Push version changes to repository if: steps.version_resolution.outputs.conflict_resolved == 'true' || github.event_name == 'workflow_dispatch' run: | # Push the version changes back to the repository git push origin HEAD:${{ github.ref_name }} echo "πŸ“€ Pushed version changes to repository" - name: Create GitHub release (if tag) if: startsWith(github.ref, 'refs/tags/v') uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ github.ref }} release_name: Release ${{ github.ref }} body: | ## πŸš€ Release Notes ### πŸ“¦ NPM Package - **Package:** `${{ env.PACKAGE_NAME }}` - **Version:** `${{ steps.version_resolution.outputs.target_version }}` - **Version Strategy:** ${{ steps.version_resolution.outputs.version_strategy }} - **Size:** ~465kB (optimized) - **Database:** Pre-seeded workflow.db - **Runtime:** Prisma generation + database copying ### πŸ”§ Installation ```bash npm install -g ${{ env.PACKAGE_NAME }}@${{ steps.version_resolution.outputs.target_version }} # or npx ${{ env.PACKAGE_NAME }}@${{ steps.version_resolution.outputs.target_version }} ``` ### 🐳 Docker ```bash docker pull hiveacademy/anubis:latest ``` See CHANGELOG.md for detailed changes. draft: false prerelease: false

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Hive-Academy/Anubis-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server