diff --git a/.github/workflows/appstore-build-publish.yml b/.github/workflows/appstore-build-publish.yml new file mode 100644 index 0000000..63b20f0 --- /dev/null +++ b/.github/workflows/appstore-build-publish.yml @@ -0,0 +1,84 @@ +name: Build and Publish Astrolabe App Release + +on: + release: + types: [published] + +env: + APP_NAME: astrolabe + APP_DIR: third_party/astrolabe + +jobs: + build-and-publish: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Get version from tag + id: tag + run: | + echo "TAG=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT + + - name: Validate version in info.xml matches tag + working-directory: ${{ env.APP_DIR }} + run: | + INFO_VERSION=$(sed -n 's/.*\(.*\)<\/version>.*/\1/p' appinfo/info.xml | tr -d '\t') + if [ "$INFO_VERSION" != "${{ steps.tag.outputs.TAG }}" ]; then + echo "Version mismatch: info.xml has $INFO_VERSION but tag is ${{ steps.tag.outputs.TAG }}" + exit 1 + fi + echo "Version validated: $INFO_VERSION" + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.1 + coverage: none + + - name: Checkout Nextcloud server (for signing) + uses: actions/checkout@v4 + with: + repository: nextcloud/server + ref: stable30 + path: server + + - name: Install dependencies and build + working-directory: ${{ env.APP_DIR }} + run: | + composer install --no-dev --optimize-autoloader + npm ci + npm run build + + - name: Setup signing certificate + run: | + mkdir -p $HOME/.nextcloud/certificates + echo "${{ secrets.APP_PRIVATE_KEY }}" > $HOME/.nextcloud/certificates/${{ env.APP_NAME }}.key + echo "${{ secrets.APP_PUBLIC_CRT }}" > $HOME/.nextcloud/certificates/${{ env.APP_NAME }}.crt + + - name: Build app store package + working-directory: ${{ env.APP_DIR }} + run: make appstore + + - name: Attach tarball to GitHub release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: ${{ env.APP_DIR }}/build/artifacts/${{ env.APP_NAME }}.tar.gz + asset_name: ${{ env.APP_NAME }}-${{ steps.tag.outputs.TAG }}.tar.gz + tag: ${{ github.ref }} + + - name: Upload to Nextcloud App Store + uses: R0Wi/nextcloud-appstore-push-action@v1.0.6 + with: + app_name: ${{ env.APP_NAME }} + appstore_token: ${{ secrets.APPSTORE_TOKEN }} + download_url: ${{ github.server_url }}/${{ github.repository }}/releases/download/${{ github.ref_name }}/${{ env.APP_NAME }}-${{ steps.tag.outputs.TAG }}.tar.gz + app_private_key: ${{ secrets.APP_PRIVATE_KEY }} + nightly: ${{ github.event.release.prerelease }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 72b7c0d..842c6da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# Changelog - MCP Server + +All notable changes to the Nextcloud MCP Server will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [PEP 440](https://peps.python.org/pep-0440/). + ## v0.53.0 (2025-12-19) ### Feat diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..463962b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,116 @@ +# Contributing to Nextcloud MCP Server + +## Version Management + +This monorepo uses commitizen for version management with **independent versioning** for three components: + +### Components + +| Component | Scope | Bump Command | Tag Example | +|-----------|-------|--------------|-------------| +| MCP Server | `mcp` or none | `./scripts/bump-mcp.sh` | `v0.54.0` | +| Helm Chart | `helm` | `./scripts/bump-helm.sh` | `nextcloud-mcp-server-0.54.0` | +| Astrolabe App | `astrolabe` | `./scripts/bump-astrolabe.sh` | `astrolabe-v0.2.0` | + +### Commit Message Format + +Use conventional commits with **scopes** to target specific components: + +```bash +# MCP server changes +feat(mcp): add calendar sync API +fix(mcp): resolve authentication bug + +# Helm chart changes +feat(helm): add resource limits +docs(helm): update values documentation + +# Astrolabe app changes +feat(astrolabe): add dark mode toggle +fix(astrolabe): resolve search UI bug +``` + +**Unscoped commits** default to the MCP server: +```bash +feat: add new feature # → MCP server (v0.54.0) +``` + +### Release Workflow + +#### 1. Make Changes with Scoped Commits + +```bash +git commit -m "feat(astrolabe): add dark mode toggle" +git commit -m "feat(helm): add ingress annotations" +git commit -m "feat(mcp): add calendar sync" +``` + +#### 2. Bump Component Versions + +```bash +# Bump MCP server (reads commits with scope=mcp or unscoped) +./scripts/bump-mcp.sh +# → Creates tag: v0.54.0 +# → Updates: pyproject.toml, Chart.yaml:appVersion + +# Bump Helm chart (reads commits with scope=helm) +./scripts/bump-helm.sh +# → Creates tag: nextcloud-mcp-server-0.54.0 +# → Updates: Chart.yaml:version + +# Bump Astrolabe (reads commits with scope=astrolabe) +./scripts/bump-astrolabe.sh +# → Creates tag: astrolabe-v0.2.0 +# → Updates: info.xml, package.json +``` + +#### 3. Push Tags + +```bash +git push --follow-tags +``` + +### Changelog Filtering + +Each component maintains its own `CHANGELOG.md`: + +- **MCP Server**: `CHANGELOG.md` (root) - includes `feat(mcp):` and unscoped commits +- **Helm Chart**: `charts/nextcloud-mcp-server/CHANGELOG.md` - includes `feat(helm):` only +- **Astrolabe**: `third_party/astrolabe/CHANGELOG.md` - includes `feat(astrolabe):` only + +### Manual Version Bumps + +For specific increments: + +```bash +# Patch bump (0.53.0 → 0.53.1) +uv run cz bump --increment PATCH + +# Minor bump (0.53.0 → 0.54.0) +uv run cz bump --increment MINOR + +# Major bump (0.53.0 → 1.0.0) +uv run cz bump --increment MAJOR + +# For non-MCP components, use --config +cd charts/nextcloud-mcp-server +uv run cz --config .cz.toml bump --increment MINOR +``` + +### Versioning Philosophy + +- **MCP Server**: Follows PEP 440, `major_version_zero = true` (0.x.x for pre-1.0) +- **Helm Chart**: Follows PEP 440, starts at 0.53.0 (continues from current) +- **Astrolabe**: Follows PEP 440, `major_version_zero = true` (0.x.x for alpha/beta) + +### Chart.yaml Version vs appVersion + +The Helm chart has TWO version fields: + +- **`version`**: Chart packaging version (bumped by `feat(helm):`) + - Example: `0.53.0` → `0.54.0` when adding resource limits + +- **`appVersion`**: MCP server version being deployed (bumped by `feat(mcp):`) + - Example: `"0.53.0"` → `"0.54.0"` when MCP server releases + +This allows the chart to evolve independently from the application. diff --git a/charts/nextcloud-mcp-server/.cz.toml b/charts/nextcloud-mcp-server/.cz.toml new file mode 100644 index 0000000..c71bcdd --- /dev/null +++ b/charts/nextcloud-mcp-server/.cz.toml @@ -0,0 +1,24 @@ +[tool.commitizen] +name = "cz_conventional_commits" +version = "0.53.0" +tag_format = "nextcloud-mcp-server-$version" +version_scheme = "pep440" +update_changelog_on_bump = true +major_version_zero = true + +# Update chart version only (NOT appVersion) +version_files = [ + "Chart.yaml:^version:" +] + +# Ignore tags from other components +ignored_tag_formats = [ + "v*", # MCP server tags + "astrolabe-v*", # Astrolabe tags +] + +# Filter commits by scope +[tool.commitizen.customize] +changelog_pattern = "^(feat|fix|docs|refactor|perf|test|build|ci|chore)\\(helm\\)(!)?:" +schema_pattern = "^(feat|fix|docs|refactor|perf|test|build|ci|chore)\\(helm\\)(!)?:\\s.+" +message_template = "{{change_type}}(helm): {{message}}" diff --git a/charts/nextcloud-mcp-server/CHANGELOG.md b/charts/nextcloud-mcp-server/CHANGELOG.md new file mode 100644 index 0000000..4fb9d32 --- /dev/null +++ b/charts/nextcloud-mcp-server/CHANGELOG.md @@ -0,0 +1,18 @@ +# Changelog - Helm Chart + +All notable changes to the Helm chart will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.53.0] - 2024-12-19 + +### Added +- Initial independent versioning release +- Support for Nextcloud MCP server deployment +- Qdrant subchart integration +- Ollama subchart integration +- Configurable resource limits +- Grafana dashboard annotations diff --git a/pyproject.toml b/pyproject.toml index 60b728b..cb142ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -89,14 +89,23 @@ version_scheme = "pep440" version_provider = "uv" update_changelog_on_bump = true major_version_zero = true + +# MCP server version files + Helm appVersion version_files = [ - "charts/nextcloud-mcp-server/Chart.yaml:appVersion", - "charts/nextcloud-mcp-server/Chart.yaml:version" + "charts/nextcloud-mcp-server/Chart.yaml:^appVersion:", ] + +# Ignore tags from other components ignored_tag_formats = [ - "nextcloud-mcp-server-*" + "nextcloud-mcp-server-*", # Helm chart tags + "astrolabe-v*", # Astrolabe tags ] +# Filter commits by scope (mcp or unscoped) +[tool.commitizen.customize] +changelog_pattern = "^(feat|fix|docs|refactor|perf|test|build|ci|chore)(\\(mcp\\))?(!)?:" +schema_pattern = "^(feat|fix|docs|refactor|perf|test|build|ci|chore)(\\(mcp\\))?(!)?:\\s.+" + [tool.ruff.lint] extend-select = ["I"] diff --git a/scripts/bump-astrolabe.sh b/scripts/bump-astrolabe.sh new file mode 100755 index 0000000..79e61cc --- /dev/null +++ b/scripts/bump-astrolabe.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# Bump Astrolabe app version +set -e + +cd third_party/astrolabe + +echo "Bumping Astrolabe version..." +uv run cz --config .cz.toml bump --yes + +echo "✓ Astrolabe version bumped" +echo " - Updated: appinfo/info.xml, package.json" +echo " - Tag format: astrolabe-v\${version}" + +cd ../.. diff --git a/scripts/bump-helm.sh b/scripts/bump-helm.sh new file mode 100755 index 0000000..75d08e7 --- /dev/null +++ b/scripts/bump-helm.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# Bump Helm chart version +set -e + +cd charts/nextcloud-mcp-server + +echo "Bumping Helm chart version..." +uv run cz --config .cz.toml bump --yes + +echo "✓ Helm chart version bumped" +echo " - Updated: Chart.yaml:version" +echo " - Tag format: nextcloud-mcp-server-\${version}" +echo " - Note: appVersion stays at MCP server version" + +cd ../.. diff --git a/scripts/bump-mcp.sh b/scripts/bump-mcp.sh new file mode 100755 index 0000000..29bb045 --- /dev/null +++ b/scripts/bump-mcp.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# Bump MCP server version +set -e + +echo "Bumping MCP server version..." +uv run cz bump --yes + +echo "✓ MCP server version bumped" +echo " - Updated: pyproject.toml, Chart.yaml:appVersion" +echo " - Tag format: v\${version}" diff --git a/third_party/astrolabe/.cz.toml b/third_party/astrolabe/.cz.toml new file mode 100644 index 0000000..d16c32a --- /dev/null +++ b/third_party/astrolabe/.cz.toml @@ -0,0 +1,25 @@ +[tool.commitizen] +name = "cz_conventional_commits" +version = "0.1.0" +tag_format = "astrolabe-v$version" +version_scheme = "pep440" +update_changelog_on_bump = true +major_version_zero = true + +# Update Astrolabe-specific files only +version_files = [ + "appinfo/info.xml:version", + "package.json:version" +] + +# Ignore tags from other components +ignored_tag_formats = [ + "v*", # MCP server tags + "nextcloud-mcp-server-*", # Helm chart tags +] + +# Filter commits by scope +[tool.commitizen.customize] +changelog_pattern = "^(feat|fix|docs|refactor|perf|test|build|ci|chore)\\(astrolabe\\)(!)?:" +schema_pattern = "^(feat|fix|docs|refactor|perf|test|build|ci|chore)\\(astrolabe\\)(!)?:\\s.+" +message_template = "{{change_type}}(astrolabe): {{message}}" diff --git a/third_party/astrolabe/.gitignore b/third_party/astrolabe/.gitignore index 6f827c5..afd5e5d 100644 --- a/third_party/astrolabe/.gitignore +++ b/third_party/astrolabe/.gitignore @@ -8,6 +8,7 @@ /tests/.phpunit.cache dist/ +build/ node_modules/ js/ css/ diff --git a/third_party/astrolabe/CHANGELOG.md b/third_party/astrolabe/CHANGELOG.md index ab830f7..40fee5b 100644 --- a/third_party/astrolabe/CHANGELOG.md +++ b/third_party/astrolabe/CHANGELOG.md @@ -1,12 +1,29 @@ -# Changelog +# Changelog - Astrolabe -All notable changes to this project will be documented in this file. +All notable changes to the Astrolabe Nextcloud app will be documented in this file. -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +## [0.1.0] - 2024-12-19 + ### Added -- First release +- Initial alpha release +- Semantic search across Notes, Files, Calendar, Deck, and Contacts +- Integration with Nextcloud Unified Search +- Personal settings UI for MCP server configuration +- Admin settings for global MCP server URL +- OAuth PKCE authentication flow +- Vector visualization of semantic relationships +- Hybrid search combining semantic and keyword matching +- Background content indexing +- Support for Nextcloud 30-32 + +### Notes + +- This is an alpha release intended for early adopters and testing +- Requires external MCP server deployment +- See documentation for setup: https://github.com/cbcoutinho/nextcloud-mcp-server diff --git a/third_party/astrolabe/Makefile b/third_party/astrolabe/Makefile new file mode 100644 index 0000000..bf9f188 --- /dev/null +++ b/third_party/astrolabe/Makefile @@ -0,0 +1,81 @@ +# Nextcloud App Store Release Makefile for Astrolabe +# +# Based on: https://nextcloudappstore.readthedocs.io/en/latest/developer.html + +app_name=astrolabe +project_dir=$(CURDIR) +build_dir=$(project_dir)/build +appstore_dir=$(build_dir)/artifacts +package_name=$(appstore_dir)/$(app_name) +cert_dir=$(HOME)/.nextcloud/certificates + +# Signing +private_key=$(cert_dir)/$(app_name).key +certificate=$(cert_dir)/$(app_name).crt +sign_cmd=php ../../server/occ integrity:sign-app --privateKey=$(private_key) --certificate=$(certificate) + +# Clean build artifacts +.PHONY: clean +clean: + rm -rf $(build_dir) + +# Install PHP and Node dependencies +.PHONY: install-deps +install-deps: + composer install --no-dev --optimize-autoloader + npm ci + +# Build production frontend assets +.PHONY: build-frontend +build-frontend: + npm run build + +# Run all linters +.PHONY: lint +lint: + composer lint + composer cs:check + npm run lint + npm run stylelint + +# Assemble app files into build directory (exclude dev files) +.PHONY: assemble +assemble: clean install-deps build-frontend + mkdir -p $(package_name) + # Copy app files + rsync -av \ + --exclude='.git*' \ + --exclude='build/' \ + --exclude='tests/' \ + --exclude='node_modules/' \ + --exclude='*.log' \ + --exclude='.github/' \ + --exclude='composer.json' \ + --exclude='composer.lock' \ + --exclude='package.json' \ + --exclude='package-lock.json' \ + --exclude='vite.config.js' \ + --exclude='.eslintrc.js' \ + --exclude='.php-cs-fixer.*' \ + --exclude='psalm.xml' \ + --exclude='*.iml' \ + --exclude='.idea' \ + --exclude='src/' \ + ./ $(package_name)/ + +# Create signed release tarball for App Store +.PHONY: appstore +appstore: assemble + # Sign the app + $(sign_cmd) --path=$(package_name) + # Create tarball + cd $(appstore_dir) && \ + tar -czf $(app_name).tar.gz $(app_name) + # Show package info + @echo "=========================================" + @echo "App package created:" + @echo " $(appstore_dir)/$(app_name).tar.gz" + @echo "" + @echo "Signature:" + @cat $(package_name)/appinfo/signature.json | head -n 5 + @echo "=========================================" diff --git a/third_party/astrolabe/package.json b/third_party/astrolabe/package.json index d3fe6cc..1e6b4ac 100644 --- a/third_party/astrolabe/package.json +++ b/third_party/astrolabe/package.json @@ -1,6 +1,6 @@ { "name": "astrolabe", - "version": "1.0.0", + "version": "0.1.0", "license": "AGPL-3.0-or-later", "engines": { "node": "^22.0.0",