Skip to main content
Glama
ci.yml12.7 kB
name: CI Pipeline, Security & Publish on: push: branches: [ main ] pull_request: types: [ opened, synchronize, reopened ] branches: [ main ] release: types: [ published ] workflow_dispatch: # Restrict default permissions to read-only for security permissions: read-all jobs: test: runs-on: ubuntu-latest if: github.event_name == 'pull_request' timeout-minutes: 30 permissions: contents: read # Required to checkout code steps: - name: Checkout code uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Setup Node.js uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5 with: node-version: '22.x' cache: 'npm' - name: Install dependencies run: npm ci - name: Install Devbox uses: jetify-com/devbox-install-action@a03caf5813591bc882139eba6ae947930a83a427 # v0.11.0 with: enable-cache: true - name: Run linter run: devbox run -- npm run lint - name: Build project run: devbox run -- npm run build - name: Run integration tests (with automated cluster creation and server management) run: devbox run -- npm run test:integration timeout-minutes: 15 env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} security: name: Security Analysis runs-on: ubuntu-latest if: github.event_name == 'pull_request' || github.event_name == 'push' permissions: contents: read # Required to checkout code security-events: write # Required to upload CodeQL results steps: - name: Checkout code uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Initialize CodeQL uses: github/codeql-action/init@d3ced5c96c16c4332e2a61eb6f3649d6f1b20bb8 # v3 with: languages: typescript - name: Setup Node.js uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5 with: node-version: '22.x' cache: 'npm' - name: Install dependencies run: npm ci - name: Build project run: npm run build - name: Run dependency security audit run: npm audit --audit-level moderate - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@d3ced5c96c16c4332e2a61eb6f3649d6f1b20bb8 # v3 version: runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') permissions: contents: read # Required to checkout code and read package.json outputs: new-version: ${{ steps.version-check.outputs.new-version }} version-changed: ${{ steps.version-check.outputs.version-changed }} steps: - name: Checkout code uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - name: Pull latest changes run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git pull origin main - name: Calculate next version id: version-check run: | PUBLISHED_VERSION=$(npm view @vfarcic/dot-ai version 2>/dev/null || echo "0.0.0") echo "published-version=$PUBLISHED_VERSION" >> $GITHUB_OUTPUT # Always bump from published version (avoids race conditions) MAJOR=$(echo $PUBLISHED_VERSION | cut -d. -f1) MINOR=$(echo $PUBLISHED_VERSION | cut -d. -f2) NEW_MINOR=$((MINOR + 1)) NEW_VERSION="$MAJOR.$NEW_MINOR.0" echo "new-version=$NEW_VERSION" >> $GITHUB_OUTPUT echo "Version will be incremented from $PUBLISHED_VERSION to $NEW_VERSION" echo "version-changed=true" >> $GITHUB_OUTPUT release: needs: [version] runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && needs.version.outputs.version-changed == 'true' permissions: contents: write packages: write id-token: write # Required for MCP Registry OIDC authentication steps: - name: Checkout code uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - name: Setup git config run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git pull origin main - name: Setup Node.js uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5 with: node-version: '22.x' registry-url: 'https://registry.npmjs.org' cache: 'npm' - name: Install dependencies run: npm ci - name: Build project run: npm run build - name: Update package.json version if needed run: | VERSION=${{ needs.version.outputs.new-version }} CURRENT_VERSION=$(node -p "require('./package.json').version") if [ "$CURRENT_VERSION" != "$VERSION" ]; then echo "Updating package.json from $CURRENT_VERSION to $VERSION" npm version $VERSION --no-git-tag-version else echo "Package.json already at correct version: $VERSION" fi - name: Update server.json version run: | VERSION=${{ needs.version.outputs.new-version }} if [ ! -f "server.json" ]; then echo "ERROR: server.json file not found!" echo "The server.json file is required for MCP registry publication." exit 1 fi echo "Updating server.json to version $VERSION" # Update both version fields in server.json sed -i "s/\"version\": \"[^\"]*\"/\"version\": \"$VERSION\"/g" server.json echo "Updated server.json:" cat server.json - name: Publish to npm run: npm publish --access public env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Create npm package tarball for Docker build run: npm pack - name: Set up QEMU uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3 - name: Log in to GitHub Container Registry uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GHCR_TOKEN }} - name: Build and push Docker image uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5 with: context: . push: true build-args: | PACKAGE_VERSION=${{ needs.version.outputs.new-version }} tags: | ghcr.io/vfarcic/dot-ai:${{ needs.version.outputs.new-version }} ghcr.io/vfarcic/dot-ai:latest labels: | org.opencontainers.image.source=https://github.com/vfarcic/dot-ai org.opencontainers.image.description=AI-powered development productivity platform that enhances software development workflows through intelligent automation and AI-driven assistance org.opencontainers.image.licenses=MIT org.opencontainers.image.version=${{ needs.version.outputs.new-version }} platforms: linux/amd64,linux/arm64 - name: Install Helm uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4 with: version: 'v3.14.0' - name: Update Chart.yaml and values.yaml versions run: | VERSION=${{ needs.version.outputs.new-version }} # Update Chart.yaml versions to match the coordinated release sed -i "s/^version: .*/version: \"$VERSION\"/" charts/Chart.yaml # Update Chart.yaml appVersion to match the Docker image we just built sed -i "s/^appVersion: .*/appVersion: \"$VERSION\"/" charts/Chart.yaml # Update values.yaml image tag to reference the Docker image we just built sed -i "s/tag: \".*\"/tag: \"$VERSION\"/" charts/values.yaml # Update dot.nu --dot-ai-tag default value to reference the Docker image we just built sed -i "s/--dot-ai-tag: string = \".*\"/--dot-ai-tag: string = \"$VERSION\"/" dot.nu echo "Updated chart to reference Docker image: ghcr.io/vfarcic/dot-ai:$VERSION" echo "Updated dot.nu to reference Docker image: ghcr.io/vfarcic/dot-ai:$VERSION" - name: Log in to GitHub Container Registry for Helm run: | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin <<< "${{ secrets.GHCR_TOKEN }}" env: HELM_EXPERIMENTAL_OCI: 1 - name: Package and push Helm chart run: | VERSION=${{ needs.version.outputs.new-version }} # Package the chart with coordinated version helm package charts/ --version $VERSION --app-version $VERSION # Push versioned chart to GHCR as OCI artifact helm push dot-ai-$VERSION.tgz oci://ghcr.io/vfarcic/dot-ai/charts echo "Published Helm chart: oci://ghcr.io/vfarcic/dot-ai/charts/dot-ai:$VERSION" - name: Commit all coordinated changes and create Git tag run: | VERSION=${{ needs.version.outputs.new-version }} # Add all version-related changes git add package.json charts/Chart.yaml charts/values.yaml server.json dot.nu git commit -m "chore: coordinated release v$VERSION - npm package: v$VERSION - docker image: ghcr.io/vfarcic/dot-ai:$VERSION - helm chart: oci://ghcr.io/vfarcic/dot-ai/charts/dot-ai:$VERSION [skip ci]" # Create release tag git tag -a "v$VERSION" -m "Release v$VERSION - coordinated npm, docker, and helm chart release" # Push changes and tag git push origin main git push origin "v$VERSION" echo "Released coordinated version: $VERSION" # Temporarily disabled: MCP Registry schema migration in progress # The 2025-09-29 schema is marked as deprecated but documentation hasn't been updated # with the new schema version yet. Re-enable once new schema is documented. # See: https://github.com/modelcontextprotocol/registry/blob/main/docs/reference/server-json/CHANGELOG.md # - name: Publish to MCP Registry # run: | # VERSION=${{ needs.version.outputs.new-version }} # echo "Publishing dot-ai v$VERSION to MCP Registry" # # # Install MCP publisher CLI (latest version with bug fixes) # echo "Installing MCP publisher CLI v1.1.0..." # curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.1.0/mcp-publisher_1.1.0_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher # # # Use GitHub OIDC for authentication (no login needed in GitHub Actions) # echo "Authenticating with GitHub OIDC..." # ./mcp-publisher login github-oidc # # # Publish the server # echo "Publishing server.json..." # ./mcp-publisher publish server.json # # echo "Successfully published dot-ai v$VERSION to MCP Registry" - name: Create GitHub Release with auto-generated notes run: | VERSION=${{ needs.version.outputs.new-version }} PREV_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "") # Create release notes header with coordinated artifacts cat > release_header.md << 'EOF' ## Coordinated Release Artifacts - **npm package**: `@vfarcic/dot-ai@$VERSION` - **Docker image**: `ghcr.io/vfarcic/dot-ai:$VERSION` (also available as `latest`) - **Helm chart**: `oci://ghcr.io/vfarcic/dot-ai/charts/dot-ai:$VERSION` EOF # Replace VERSION placeholder sed -i "s/\$VERSION/$VERSION/g" release_header.md # Create release with automatic notes generation and custom header # GitHub will categorize PRs based on .github/release.yml if [ -n "$PREV_TAG" ]; then gh release create "v$VERSION" \ --title "Release v$VERSION" \ --notes-file release_header.md \ --generate-notes \ --notes-start-tag "$PREV_TAG" else gh release create "v$VERSION" \ --title "Release v$VERSION" \ --notes-file release_header.md \ --generate-notes fi env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Latest Blog Posts

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/vfarcic/dot-ai'

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