diff --git a/.github/workflows/appstore-build-publish.yml b/.github/workflows/appstore-build-publish.yml new file mode 100644 index 0000000..faefd73 --- /dev/null +++ b/.github/workflows/appstore-build-publish.yml @@ -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>.*/\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') }} 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..8f4504c --- /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 = "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}}" 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..c51b8eb --- /dev/null +++ b/scripts/bump-astrolabe.sh @@ -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 ../.. diff --git a/scripts/bump-helm.sh b/scripts/bump-helm.sh new file mode 100755 index 0000000..d57aef7 --- /dev/null +++ b/scripts/bump-helm.sh @@ -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 ../.. diff --git a/scripts/bump-mcp.sh b/scripts/bump-mcp.sh new file mode 100755 index 0000000..d6b618e --- /dev/null +++ b/scripts/bump-mcp.sh @@ -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" diff --git a/scripts/test-commitizen-scopes.sh b/scripts/test-commitizen-scopes.sh new file mode 100755 index 0000000..9f2c072 --- /dev/null +++ b/scripts/test-commitizen-scopes.sh @@ -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 diff --git a/third_party/astrolabe/.cz.toml b/third_party/astrolabe/.cz.toml new file mode 100644 index 0000000..6e7c9b3 --- /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 = "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}}" 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..f96e6e0 --- /dev/null +++ b/third_party/astrolabe/Makefile @@ -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 "=========================================" 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",