Compare commits

..

18 Commits

Author SHA1 Message Date
Chris Coutinho e2e0ffce44 fix(ci): improve versioning and error handling
Addresses remaining high-priority code review feedback:

VERSIONING SCHEME FIXES:
- Helm chart: Changed from pep440 to semver (correct for Helm)
- Astrolabe: Changed from pep440 to semver (correct for Nextcloud apps)
- MCP server: Remains pep440 (correct for Python packages)

Helm charts must use semantic versioning per Helm specification.
Nextcloud apps use semantic versioning in info.xml and package.json.

ENHANCED ERROR HANDLING IN BUMP SCRIPTS:
All three bump scripts now include:
- Comprehensive validation checks
  * Tool availability (uv)
  * Directory structure (must run from repo root)
  * Required files exist (Chart.yaml, info.xml, package.json)
- Better error messages
  * Stderr output for errors
  * Captured commitizen output on failure
  * Common failure causes listed
- Success confirmation
  * Clear indication of what was updated
  * Next steps guidance (git push --follow-tags)
- Robust shell options (set -euo pipefail)

Scripts now provide helpful guidance when:
- No conventional commits found
- No commits with required scope
- Git working directory not clean
- Required dependencies missing
2025-12-19 19:38:24 +01:00
Chris Coutinho 2f3a3e0be4 fix(ci): address critical workflow and validation issues
Addresses code review feedback on PR #418:

CRITICAL FIXES:
1. Workflow trigger: Changed from release:published to push:tags
   - Enables "tag and publish in one step" workflow as intended
   - Automatically creates GitHub release on tag push
   - Removed redundant if condition (filtering now via trigger)
   - Added prerelease detection based on tag (-alpha, -beta, -rc)

2. Server path: Explicitly pass server_dir to make command
   - Fixes path mismatch between local (../../server) and CI
   - Uses absolute path: server_dir=${{ github.workspace }}/server
   - Prevents signing failures in GitHub Actions

3. Regex validation: Added test script for commitizen patterns
   - Validates scope filtering works correctly
   - Tests all three components: mcp, helm, astrolabe
   - Tests unscoped commits (default to mcp)
   - Tests breaking changes and invalid commits
   - Location: scripts/test-commitizen-scopes.sh

WORKFLOW IMPROVEMENTS:
- Release creation now automatic on tag push
- Better step naming for clarity
- Consistent prerelease handling across GitHub and App Store
- Explicit server_dir prevents reliance on fragile relative paths

All 16 test cases pass for scope filtering patterns.
2025-12-19 19:34:21 +01:00
Chris Coutinho c5f7221fb2 fix(astrolabe): address code review feedback
CRITICAL FIXES:
- Fix tag parsing in workflow to strip "astrolabe-v" instead of "v"
  For tag astrolabe-v0.1.0, now correctly extracts "0.1.0"
- Add workflow filtering to only run on astrolabe-v* tags
  Prevents wasting CI resources on MCP/Helm releases

RECOMMENDED IMPROVEMENTS:
- Make Nextcloud server path configurable in Makefile
  Can now override: make appstore server_dir=/path/to/server
- Add dependency validation to Makefile
  Checks for composer, npm, php before building
- Add signing prerequisite validation
  Verifies server/occ, private key, and certificate exist
- Add dependency checks to all bump scripts
  Validates uv is installed before running cz bump

These changes improve local build experience and prevent common
errors with clear error messages and installation guidance.
2025-12-19 18:34:14 +01:00
Chris Coutinho 4a42b947bc feat(astrolabe): add Nextcloud App Store deployment automation
Add complete CI/CD pipeline for automated Astrolabe app releases:
- GitHub Actions workflow for build, sign, and publish
- Makefile for app store package creation
- Version synchronization between info.xml and package.json
- CHANGELOG.md with v0.1.0 release notes

feat: configure commitizen monorepo with independent versioning

Enable independent versioning for three components using scope-based commits:
- MCP Server (feat(mcp) or unscoped): v* tags, updates pyproject.toml + Chart.yaml:appVersion
- Helm Chart (feat(helm)): nextcloud-mcp-server-* tags, updates Chart.yaml:version
- Astrolabe App (feat(astrolabe)): astrolabe-v* tags, updates info.xml + package.json

Changes:
- Add .cz.toml configs for Astrolabe and Helm chart
- Update root pyproject.toml with scope filtering and tag ignores
- Create bump helper scripts (bump-mcp.sh, bump-helm.sh, bump-astrolabe.sh)
- Add CONTRIBUTING.md with version management documentation
- Create component-specific changelogs
- Configure appVersion/version separation for Helm chart

This allows each component to release independently while maintaining
proper version tracking and changelog generation.
2025-12-19 18:06:39 +01:00
github-actions[bot] 46b260641f bump: version 0.52.1 → 0.53.0 2025-12-19 13:23:12 +00:00
Chris Coutinho 60d80970a4 Merge pull request #401 from cbcoutinho/feature/nc-app-ui
feat(astrolabe): Nextcloud app UI with PDF viewer, webhooks, and OAuth refresh
2025-12-19 14:22:42 +01:00
Chris Coutinho 6babbc99e7 Merge pull request #403 from cbcoutinho/renovate/ghcr.io-astral-sh-uv-0.x
chore(deps): update ghcr.io/astral-sh/uv docker tag to v0.9.18
2025-12-17 19:46:00 +01:00
Chris Coutinho 1f5e9d815b Merge pull request #402 from cbcoutinho/renovate/anthropics-claude-code-action-digest
chore(deps): update anthropics/claude-code-action digest to d7b6d50
2025-12-17 19:44:51 +01:00
renovate-bot-cbcoutinho[bot] 83caa48cdb chore(deps): update ghcr.io/astral-sh/uv docker tag to v0.9.18 2025-12-17 11:07:53 +00:00
renovate-bot-cbcoutinho[bot] b51019a7e8 chore(deps): update anthropics/claude-code-action digest to d7b6d50 2025-12-17 11:07:48 +00:00
Chris Coutinho 72d65cd7ae Merge pull request #400 from cbcoutinho/renovate/docker.io-library-nextcloud-32.0.3
chore(deps): update docker.io/library/nextcloud:32.0.3 docker digest to 53231a9
2025-12-15 12:53:17 +01:00
renovate-bot-cbcoutinho[bot] 76251e935e chore(deps): update docker.io/library/nextcloud:32.0.3 docker digest to 53231a9 2025-12-15 11:06:31 +00:00
Chris Coutinho 49230c3a44 Merge pull request #398 from cbcoutinho/renovate/astral-sh-setup-uv-7.x
chore(deps): update astral-sh/setup-uv action to v7.1.6
2025-12-14 15:26:44 +01:00
Chris Coutinho 262d2b2133 Merge pull request #397 from cbcoutinho/renovate/docker.io-library-nginx-alpine
chore(deps): update docker.io/library/nginx:alpine docker digest to 052b75a
2025-12-14 15:26:31 +01:00
Chris Coutinho ad2ff2ccc4 Merge pull request #399 from cbcoutinho/renovate/ollama-1.x
chore(deps): update helm release ollama to v1.36.0
2025-12-14 15:22:50 +01:00
renovate-bot-cbcoutinho[bot] dff7a58736 chore(deps): update helm release ollama to v1.36.0 2025-12-14 11:07:14 +00:00
renovate-bot-cbcoutinho[bot] 44c9bd645e chore(deps): update astral-sh/setup-uv action to v7.1.6 2025-12-14 11:06:57 +00:00
renovate-bot-cbcoutinho[bot] 4741d60e4c chore(deps): update docker.io/library/nginx:alpine docker digest to 052b75a 2025-12-14 11:06:52 +00:00
26 changed files with 719 additions and 26 deletions
@@ -0,0 +1,87 @@
name: Build and Publish Astrolabe App Release
on:
push:
tags:
- 'astrolabe-v*'
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/astrolabe-v}" >> $GITHUB_OUTPUT
- name: Validate version in info.xml matches tag
working-directory: ${{ env.APP_DIR }}
run: |
INFO_VERSION=$(sed -n 's/.*<version>\(.*\)<\/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 server_dir=${{ github.workspace }}/server
- name: Create GitHub release and attach tarball
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 }}
release_name: Astrolabe ${{ steps.tag.outputs.TAG }}
prerelease: ${{ contains(steps.tag.outputs.TAG, '-alpha') || contains(steps.tag.outputs.TAG, '-beta') || contains(steps.tag.outputs.TAG, '-rc') }}
- 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: ${{ contains(steps.tag.outputs.TAG, '-alpha') || contains(steps.tag.outputs.TAG, '-beta') || contains(steps.tag.outputs.TAG, '-rc') }}
+1 -1
View File
@@ -33,7 +33,7 @@ jobs:
- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@f0c8eb29807907de7f5412d04afceb5e24817127 # v1
uses: anthropics/claude-code-action@d7b6d50442a89f005016e778bf825a72ef582525 # v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
prompt: |
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@f0c8eb29807907de7f5412d04afceb5e24817127 # v1
uses: anthropics/claude-code-action@d7b6d50442a89f005016e778bf825a72ef582525 # v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
+1 -1
View File
@@ -42,7 +42,7 @@ jobs:
VECTOR_SYNC_SCAN_INTERVAL: "5"
- name: Install the latest version of uv
uses: astral-sh/setup-uv@ed21f2f24f8dd64503750218de024bcf64c7250a # v7.1.5
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6
- name: Wait for Nextcloud to be ready
run: |
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
- name: Install uv
uses: astral-sh/setup-uv@ed21f2f24f8dd64503750218de024bcf64c7250a # v7.1.5
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6
- name: Install Python 3.11
run: uv python install 3.11
- name: Build
+2 -2
View File
@@ -11,7 +11,7 @@ jobs:
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Install the latest version of uv
uses: astral-sh/setup-uv@ed21f2f24f8dd64503750218de024bcf64c7250a # v7.1.5
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6
- name: Check format
run: |
uv run --frozen ruff format --diff
@@ -56,7 +56,7 @@ jobs:
up-flags: "--build"
- name: Install the latest version of uv
uses: astral-sh/setup-uv@ed21f2f24f8dd64503750218de024bcf64c7250a # v7.1.5
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6
- name: Install Playwright dependencies
run: |
+46
View File
@@ -1,3 +1,49 @@
# 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
- add Alembic database migration system
- make chunk modal title clickable link to documents
- add native Plotly hover styling for clickable points
- add click interactivity to Plotly 3D scatter chart
- improve chunk viewer with fixed navigation and markdown rendering
- **astrolabe**: enable multi-select for document types and refactor PDF viewer
- **auth**: implement refresh token rotation for Nextcloud OIDC
- **astrolabe**: enhance unified search and add webhook management
- **astrolabe**: add webhook management UI to admin settings
- **astrolabe**: add OAuth token refresh and webhook presets
- **search**: add file_path metadata and chunk offsets to search results
- **astrolabe**: use proper icons and thumbnails in unified search
- **astrolabe**: add admin search settings and enhanced UI
- **astrolabe**: add unified search provider with clickable file links
- **astrolabe**: add 3D PCA visualization for semantic search
- **astrolabe**: add Nextcloud PHP app for MCP server management
- **vector-sync**: enable background sync in OAuth mode
### Fix
- **security**: address critical security issues from PR #401 code review
- **oauth**: enable PKCE for all clients and add token_broker to oauth_context
- **astrolabe**: revert invalid files_pdfviewer URL for file links
- resolve type checking warnings for CI
- move Alembic to package submodule for Docker compatibility
- update unified search results to match chunk viz display
- **astrolabe**: handle OAuth refresh token rotation
- address critical code review issues (4 fixes)
- resolve CI linting issues for Astroglobe
### Refactor
- **astrolabe**: extract PDF viewer to dedicated component
- **astrolabe**: reframe UI as semantic search service
## v0.52.1 (2025-12-13)
### Perf
+116
View File
@@ -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.
+1 -1
View File
@@ -1,6 +1,6 @@
FROM docker.io/library/python:3.12-slim-trixie@sha256:fa48eefe2146644c2308b909d6bb7651a768178f84fc9550dcd495e4d6d84d01
COPY --from=ghcr.io/astral-sh/uv:0.9.17@sha256:5cb6b54d2bc3fe2eb9a8483db958a0b9eebf9edff68adedb369df8e7b98711a2 /uv /uvx /bin/
COPY --from=ghcr.io/astral-sh/uv:0.9.18@sha256:5713fa8217f92b80223bc83aac7db36ec80a84437dbc0d04bbc659cae030d8c9 /uv /uvx /bin/
# Install dependencies
# 1. git (required for caldav dependency from git)
+1 -1
View File
@@ -17,7 +17,7 @@ FROM docker.io/library/python:3.12-slim-trixie@sha256:fa48eefe2146644c2308b909d6
WORKDIR /app
# Install uv for fast dependency management
COPY --from=ghcr.io/astral-sh/uv:0.9.17@sha256:5cb6b54d2bc3fe2eb9a8483db958a0b9eebf9edff68adedb369df8e7b98711a2 /uv /uvx /bin/
COPY --from=ghcr.io/astral-sh/uv:0.9.18@sha256:5713fa8217f92b80223bc83aac7db36ec80a84437dbc0d04bbc659cae030d8c9 /uv /uvx /bin/
# Install dependencies
# 1. git (required for caldav dependency from git)
+24
View File
@@ -0,0 +1,24 @@
[tool.commitizen]
name = "cz_conventional_commits"
version = "0.53.0"
tag_format = "nextcloud-mcp-server-$version"
version_scheme = "semver"
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}}"
+18
View File
@@ -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
+3 -3
View File
@@ -4,6 +4,6 @@ dependencies:
version: 1.16.2
- name: ollama
repository: https://otwld.github.io/ollama-helm
version: 1.35.0
digest: sha256:bcb0779739e4710b90bb65f6a7baeaa295bd0ba9776f8a1cf8d9b69d233c8ec0
generated: "2025-12-05T11:11:27.999374001Z"
version: 1.36.0
digest: sha256:fab8008217b27ff4e3e139c2f481eedaa23f9f64a3a086d0e9deea2195b69b63
generated: "2025-12-14T11:07:07.024787592Z"
+3 -3
View File
@@ -2,8 +2,8 @@ apiVersion: v2
name: nextcloud-mcp-server
description: A Helm chart for Nextcloud MCP Server - enables AI assistants to interact with Nextcloud
type: application
version: 0.52.1
appVersion: "0.52.1"
version: 0.53.0
appVersion: "0.53.0"
keywords:
- nextcloud
- mcp
@@ -31,6 +31,6 @@ dependencies:
repository: https://qdrant.github.io/qdrant-helm
condition: qdrant.networkMode.deploySubchart
- name: ollama
version: "1.35.0"
version: "1.36.0"
repository: https://otwld.github.io/ollama-helm
condition: ollama.enabled
+2 -2
View File
@@ -21,7 +21,7 @@ services:
restart: always
app:
image: docker.io/library/nextcloud:32.0.3@sha256:54993ed39dc77f7a6ade142b1625972cb7a9393074325373402d47231314afbb
image: docker.io/library/nextcloud:32.0.3@sha256:53231a9fb9233af2c15bfe70fc03ebe639fd53243fa42a9369884b1e0008deae
restart: always
ports:
- 0.0.0.0:8080:80
@@ -52,7 +52,7 @@ services:
retries: 30
recipes:
image: docker.io/library/nginx:alpine@sha256:289decab414250121a93c3f1b8316b9c69906de3a4993757c424cb964169ad42
image: docker.io/library/nginx:alpine@sha256:052b75ab72f690f33debaa51c7e08d9b969a0447a133eb2b99cc905d9188cb2b
restart: always
volumes:
- ./tests/fixtures/test_recipe.html:/usr/share/nginx/html/test_recipe.html:ro
+13 -4
View File
@@ -1,6 +1,6 @@
[project]
name = "nextcloud-mcp-server"
version = "0.52.1"
version = "0.53.0"
description = "Model Context Protocol (MCP) server for Nextcloud integration - enables AI assistants to interact with Nextcloud data"
authors = [
{name = "Chris Coutinho", email = "chris@coutinho.io"}
@@ -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"]
+56
View File
@@ -0,0 +1,56 @@
#!/bin/bash
# Bump Astrolabe app version
set -euo pipefail
# Validate dependencies
command -v uv >/dev/null 2>&1 || {
echo "❌ Error: uv not found" >&2
echo " Install from https://docs.astral.sh/uv/" >&2
exit 1
}
# Validate Astrolabe directory exists
if [ ! -d "third_party/astrolabe" ]; then
echo "❌ Error: Must run from repository root (third_party/astrolabe not found)" >&2
exit 1
fi
cd third_party/astrolabe
# Validate required files exist
if [ ! -f "appinfo/info.xml" ]; then
echo "❌ Error: appinfo/info.xml not found" >&2
exit 1
fi
if [ ! -f "package.json" ]; then
echo "❌ Error: package.json not found" >&2
exit 1
fi
echo "Bumping Astrolabe version..."
# Run commitizen bump and capture output
if ! output=$(uv run cz --config .cz.toml bump --yes 2>&1); then
cd ../..
echo "❌ Error: Version bump failed" >&2
echo "$output" >&2
echo "" >&2
echo "Common causes:" >&2
echo " - No commits with scope 'astrolabe' since last version" >&2
echo " - No conventional commits found (use feat(astrolabe):, fix(astrolabe):, etc.)" >&2
echo " - Git working directory not clean" >&2
exit 1
fi
echo "$output"
echo ""
echo "✓ Astrolabe version bumped successfully"
echo " Updated: appinfo/info.xml, package.json"
echo " Tag format: astrolabe-v\${version}"
echo ""
echo "Next steps:"
echo " cd ../.."
echo " git push --follow-tags"
cd ../..
+52
View File
@@ -0,0 +1,52 @@
#!/bin/bash
# Bump Helm chart version
set -euo pipefail
# Validate dependencies
command -v uv >/dev/null 2>&1 || {
echo "❌ Error: uv not found" >&2
echo " Install from https://docs.astral.sh/uv/" >&2
exit 1
}
# Validate Helm chart directory exists
if [ ! -d "charts/nextcloud-mcp-server" ]; then
echo "❌ Error: Must run from repository root (charts/ not found)" >&2
exit 1
fi
cd charts/nextcloud-mcp-server
# Validate Chart.yaml exists
if [ ! -f "Chart.yaml" ]; then
echo "❌ Error: Chart.yaml not found" >&2
exit 1
fi
echo "Bumping Helm chart version..."
# Run commitizen bump and capture output
if ! output=$(uv run cz --config .cz.toml bump --yes 2>&1); then
cd ../..
echo "❌ Error: Version bump failed" >&2
echo "$output" >&2
echo "" >&2
echo "Common causes:" >&2
echo " - No commits with scope 'helm' since last version" >&2
echo " - No conventional commits found (use feat(helm):, fix(helm):, etc.)" >&2
echo " - Git working directory not clean" >&2
exit 1
fi
echo "$output"
echo ""
echo "✓ Helm chart version bumped successfully"
echo " Updated: Chart.yaml:version"
echo " Tag format: nextcloud-mcp-server-\${version}"
echo " Note: appVersion stays at MCP server version"
echo ""
echo "Next steps:"
echo " cd ../.."
echo " git push --follow-tags"
cd ../..
+39
View File
@@ -0,0 +1,39 @@
#!/bin/bash
# Bump MCP server version
set -euo pipefail
# Validate dependencies
command -v uv >/dev/null 2>&1 || {
echo "❌ Error: uv not found" >&2
echo " Install from https://docs.astral.sh/uv/" >&2
exit 1
}
# Validate we're in the repository root
if [ ! -f "pyproject.toml" ]; then
echo "❌ Error: Must run from repository root (pyproject.toml not found)" >&2
exit 1
fi
echo "Bumping MCP server version..."
# Run commitizen bump and capture output
if ! output=$(uv run cz bump --yes 2>&1); then
echo "❌ Error: Version bump failed" >&2
echo "$output" >&2
echo "" >&2
echo "Common causes:" >&2
echo " - No commits since last version" >&2
echo " - No conventional commits found (use feat:, fix:, etc.)" >&2
echo " - Git working directory not clean" >&2
exit 1
fi
echo "$output"
echo ""
echo "✓ MCP server version bumped successfully"
echo " Updated: pyproject.toml, Chart.yaml:appVersion"
echo " Tag format: v\${version}"
echo ""
echo "Next steps:"
echo " git push --follow-tags"
+102
View File
@@ -0,0 +1,102 @@
#!/bin/bash
# Test commitizen scope filtering patterns
set -uo pipefail
echo "Testing commitizen scope filtering patterns..."
echo
# Regex patterns from configs
MCP_PATTERN='^(feat|fix|docs|refactor|perf|test|build|ci|chore)(\(mcp\))?(!)?:'
HELM_PATTERN='^(feat|fix|docs|refactor|perf|test|build|ci|chore)\(helm\)(!)?:'
ASTROLABE_PATTERN='^(feat|fix|docs|refactor|perf|test|build|ci|chore)\(astrolabe\)(!)?:'
test_pattern() {
local message="$1"
local pattern="$2"
if echo "$message" | grep -qE "$pattern"; then
return 0
else
return 1
fi
}
run_test() {
local message="$1"
local expected="$2"
local matched_components=()
# Check which components match
if test_pattern "$message" "$MCP_PATTERN"; then
matched_components+=("mcp")
fi
if test_pattern "$message" "$HELM_PATTERN"; then
matched_components+=("helm")
fi
if test_pattern "$message" "$ASTROLABE_PATTERN"; then
matched_components+=("astrolabe")
fi
# Convert array to space-separated string, or "none" if empty
local matched
if [ ${#matched_components[@]} -eq 0 ]; then
matched="none"
else
matched="${matched_components[*]}"
fi
# Validate expectation
if [ "$matched" = "$expected" ]; then
echo "✓ PASS: '$message'"
echo " → Matched: $matched"
return 0
else
echo "✗ FAIL: '$message'"
echo " → Matched: $matched (expected: $expected)"
return 1
fi
}
# Run all test cases
failed=0
passed=0
# MCP server commits (scope=mcp or unscoped)
run_test "feat: add new feature" "mcp" && passed=$((passed+1)) || failed=$((failed+1))
run_test "feat(mcp): add API endpoint" "mcp" && passed=$((passed+1)) || failed=$((failed+1))
run_test "fix(mcp): resolve authentication bug" "mcp" && passed=$((passed+1)) || failed=$((failed+1))
run_test "docs: update README" "mcp" && passed=$((passed+1)) || failed=$((failed+1))
# Helm chart commits
run_test "feat(helm): add resource limits" "helm" && passed=$((passed+1)) || failed=$((failed+1))
run_test "fix(helm): correct values schema" "helm" && passed=$((passed+1)) || failed=$((failed+1))
run_test "docs(helm): update deployment guide" "helm" && passed=$((passed+1)) || failed=$((failed+1))
# Astrolabe commits
run_test "feat(astrolabe): add dark mode" "astrolabe" && passed=$((passed+1)) || failed=$((failed+1))
run_test "fix(astrolabe): resolve UI bug" "astrolabe" && passed=$((passed+1)) || failed=$((failed+1))
run_test "perf(astrolabe): optimize rendering" "astrolabe" && passed=$((passed+1)) || failed=$((failed+1))
# Breaking changes
run_test "feat(mcp)!: breaking API change" "mcp" && passed=$((passed+1)) || failed=$((failed+1))
run_test "feat(helm)!: rename values" "helm" && passed=$((passed+1)) || failed=$((failed+1))
run_test "feat(astrolabe)!: remove deprecated feature" "astrolabe" && passed=$((passed+1)) || failed=$((failed+1))
# Invalid commits (should not match any)
run_test "feat(invalid): test" "none" && passed=$((passed+1)) || failed=$((failed+1))
run_test "random commit message" "none" && passed=$((passed+1)) || failed=$((failed+1))
run_test "feat (mcp): space before scope" "none" && passed=$((passed+1)) || failed=$((failed+1))
# Summary
echo
echo "=========================================="
echo "Results: $passed passed, $failed failed"
echo "=========================================="
if [ $failed -gt 0 ]; then
echo "❌ Some tests failed - scope patterns may need adjustment"
exit 1
else
echo "✅ All tests passed - scope patterns working correctly"
exit 0
fi
+25
View File
@@ -0,0 +1,25 @@
[tool.commitizen]
name = "cz_conventional_commits"
version = "0.1.0"
tag_format = "astrolabe-v$version"
version_scheme = "semver"
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}}"
+1
View File
@@ -8,6 +8,7 @@
/tests/.phpunit.cache
dist/
build/
node_modules/
js/
css/
+21 -4
View File
@@ -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
+101
View File
@@ -0,0 +1,101 @@
# 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
# Nextcloud server path (configurable via environment variable)
server_dir?=../../server
occ=$(server_dir)/occ
# Signing
private_key=$(cert_dir)/$(app_name).key
certificate=$(cert_dir)/$(app_name).crt
sign_cmd=php $(occ) integrity:sign-app --privateKey=$(private_key) --certificate=$(certificate)
# Clean build artifacts
.PHONY: clean
clean:
rm -rf $(build_dir)
# Validate required dependencies
.PHONY: validate-deps
validate-deps:
@command -v composer >/dev/null 2>&1 || { echo "Error: composer not found. Install from https://getcomposer.org/"; exit 1; }
@command -v npm >/dev/null 2>&1 || { echo "Error: npm not found. Install Node.js from https://nodejs.org/"; exit 1; }
@command -v php >/dev/null 2>&1 || { echo "Error: php not found. Install PHP 8.1 or higher."; exit 1; }
@echo "✓ All dependencies found"
# Install PHP and Node dependencies
.PHONY: install-deps
install-deps: validate-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)/
# Validate signing prerequisites
.PHONY: validate-signing
validate-signing:
@test -f $(occ) || { echo "Error: Nextcloud server not found at $(server_dir)"; echo "Set server_dir variable: make appstore server_dir=/path/to/server"; exit 1; }
@test -f $(private_key) || { echo "Error: Private key not found at $(private_key)"; exit 1; }
@test -f $(certificate) || { echo "Error: Certificate not found at $(certificate)"; exit 1; }
@echo "✓ Signing prerequisites validated"
# Create signed release tarball for App Store
.PHONY: appstore
appstore: assemble validate-signing
# 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 "========================================="
+1 -1
View File
@@ -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",
Generated
+1 -1
View File
@@ -1988,7 +1988,7 @@ wheels = [
[[package]]
name = "nextcloud-mcp-server"
version = "0.52.1"
version = "0.53.0"
source = { editable = "." }
dependencies = [
{ name = "aiosqlite" },