Commit Graph

1460 Commits

Author SHA1 Message Date
Chris Coutinho ea96a58678 fix(helm): address PR #447 reviewer feedback
Critical fix:
- deployment.yaml: Only reference OAuth credentials when clientId is set
- Fixes pod failure when using existingSecret without static OAuth creds
- Aligns deployment behavior with secret template logic

Previously, the deployment referenced OAuth credentials when either
clientId OR existingSecret was set. However, the secret template only
includes OAuth credentials when clientId is explicitly provided. This
caused pod failures when users provided an existingSecret for offline
access without static OAuth credentials (intending to use DCR).

The fix ensures OAuth env vars are only referenced when clientId is set,
matching the OAuth mode pattern and allowing DCR to work correctly with
existingSecret configurations.

Minor improvements:
- values.yaml: Clarify OAuth credentials are optional (uses DCR if not provided)

Testing verified all scenarios:
 Pass-through only (no offline access): No secrets/PVCs/OAuth vars
 Offline + DCR (no clientId): Secret with encryption key only, no OAuth vars
 Offline + static OAuth: Secret with all keys, OAuth vars present
 existingSecret without clientId: No auto secret, no OAuth vars (FIXED)

Resolves reviewer feedback from PR #447
2025-12-22 21:34:40 +01:00
Chris Coutinho 9b5c6779e9 fix(helm): include MCP server version bumps in changelog pattern
Updates helm chart commitizen config to recognize MCP server version
bump commits (which update appVersion in Chart.yaml) as valid triggers
for helm chart version bumps.

Problem:
- When MCP server version bumps, it updates Chart.yaml appVersion
- Helm chart commitizen only matched "(helm)" scoped commits
- Result: appVersion updated but chart version not bumped

Solution:
- Extended changelog_pattern to include "bump: version X → Y" commits
- Now helm chart version will bump when either:
  1. Commits with (helm) scope are made, OR
  2. MCP server version bumps (updating appVersion)

This ensures chart version stays in sync with appVersion updates.
2025-12-22 21:17:14 +01:00
Chris Coutinho 04140d671e feat(helm): add support for multi-user BasicAuth mode
Adds multi-user-basic authentication mode to the helm chart alongside
existing basic (single-user) and oauth modes.

Multi-user BasicAuth mode enables:
- Pass-through authentication (credentials in request headers)
- Optional background operations using app passwords via Astrolabe
- Optional OAuth client credentials (uses DCR if not provided)
- Token encryption and persistent storage for background sync

Changes:
- values.yaml: Add auth.multiUserBasic configuration section
- deployment.yaml: Add ENABLE_MULTI_USER_BASIC_AUTH and related env vars
- secret.yaml: Add secret template for token encryption key and OAuth credentials
- pvc.yaml: Add PVC template for token database persistence
- _helpers.tpl: Add helper functions for secret/PVC names

Tested with:
  helm template --set auth.mode=multi-user-basic \
    --set auth.multiUserBasic.enableOfflineAccess=true \
    --set auth.multiUserBasic.tokenEncryptionKey=... \
    --set vectorSync.enabled=true

Related: Multi-user deployment support (ADR-020)
2025-12-22 21:03:10 +01:00
Chris Coutinho e49dc2bfc4 Merge pull request #445 from cbcoutinho/feature/config-consolidation-adr-021
feat(config): consolidate configuration with smart dependency resolution (ADR-021)
2025-12-22 19:49:13 +01:00
Chris Coutinho 4a5766b84e feat(config): enable DCR for multi-user BasicAuth with offline access
Allows multi-user BasicAuth mode to use Dynamic Client Registration (DCR)
for OAuth credentials when ENABLE_OFFLINE_ACCESS is enabled, making it
consistent with OAuth modes and reducing configuration burden.

**Changes:**

Configuration Validation:
- Relaxed OAuth credential requirements for multi-user BasicAuth
- OAuth credentials now optional when offline access enabled
- Will use DCR as fallback if NEXTCLOUD_OIDC_CLIENT_ID/SECRET not set
- Updated validation to log info instead of error when DCR will be used

Startup Logic (app.py):
- Added DCR workflow for multi-user BasicAuth before uvicorn starts
- Creates oauth_context for management APIs when offline access enabled
- Allows Astrolabe to authenticate management API calls with OAuth
- DCR runs synchronously at same lifecycle point as OAuth modes
- Added traceback import for better error logging
- Fixed type assertions for nextcloud_host
- Fixed undefined variable references in vector sync logging

Management API:
- Improved auth mode detection using proper detect_auth_mode()
- Added auth_mode field to /status endpoint:
  * "basic" - Single-user BasicAuth
  * "multi_user_basic" - Multi-user BasicAuth
  * "oauth" - OAuth modes
  * "smithery" - Smithery stateless
- Added supports_app_passwords indicator for multi-user BasicAuth

Docker Compose:
- Updated mcp-multi-user-basic service configuration:
  * Enabled vector sync (VECTOR_SYNC_ENABLED=true)
  * Added ENABLE_OFFLINE_ACCESS=true for app password support
  * Added NEXTCLOUD_MCP_SERVER_URL for Astrolabe integration
  * Documented optional static OAuth credentials

Testing:
- Updated test_config_validators.py to expect DCR fallback
- Enhanced configure_astrolabe_for_mcp_server fixture with verification
- Added debug logging to test_users_setup fixture

**Workflow:**
1. User configures ENABLE_OFFLINE_ACCESS=true
2. Server checks for static NEXTCLOUD_OIDC_CLIENT_ID/SECRET
3. If not found, performs DCR before uvicorn starts
4. DCR registers client with Nextcloud OIDC provider
5. OAuth credentials used for Astrolabe management API auth
6. Background sync can retrieve user app passwords via Astrolabe

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 19:43:24 +01:00
Chris Coutinho 65c3f099fa feat(astrolabe): implement app password provisioning for multi-user background sync
Adds complete app password provisioning workflow for multi-user BasicAuth
deployments, allowing users to independently enable background sync by
generating and storing Nextcloud app passwords.

**New Components:**

Backend (PHP):
- CredentialsController: Validates and stores app passwords
  * Validates app password format and authenticity via OCS API
  * Stores encrypted passwords in oc_preferences
  * Provides status and credential management endpoints
- AstrolabeAdminSettings: Admin configuration page for MCP server URL
- AstrolabeAdminSettingsListener: Event listener for admin section
- Updated McpTokenStorage: Added background sync credential methods

Frontend:
- personalSettings.js: Form handling for app password entry
  * AJAX submission with error handling
  * Shows success/error notifications
  * Triggers page reload after successful save
- settings.css: Styling for settings pages
- Updated personal.php template: Two-option UI
  * Option 1: OAuth refresh token (future, not yet available)
  * Option 2: App password (works today, recommended)
  * Shows "Active" badge when provisioned
  * Displays credential type and provisioned timestamp

Routes:
- POST /api/v1/background-sync/credentials - Store app password
- GET /api/v1/background-sync/status - Get provisioning status
- DELETE /api/v1/background-sync/credentials - Revoke credentials
- GET /api/v1/background-sync/credentials/{userId} - Admin only

**Testing:**
- test_astrolabe_settings_buttons.py: Integration test for UI buttons

**Workflow:**
1. User generates app password in Nextcloud Security settings
2. User navigates to Astrolabe personal settings
3. User enters app password in "Option 2: App Password" form
4. Backend validates password via OCS API call
5. Password stored encrypted in oc_preferences
6. Page reloads showing "Active" badge with credential details
7. MCP server can now use stored password for background operations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 19:39:13 +01:00
Chris Coutinho b293258210 test(astrolabe): fix app password extraction in multi-user background sync test
Fixes the Playwright-based integration test that verifies multi-user app
password provisioning for background sync in Astrolabe.

**Root Cause:**
The test was failing to extract the generated app password from Nextcloud's
"New app password" dialog due to overly specific CSS selectors that didn't
match the actual DOM structure.

**Changes:**
- Enhanced network response logging to capture HTTP status codes
- Simplified app password extraction logic:
  * Wait for dialog heading using text selector
  * Iterate through ALL text inputs on page
  * Find password by pattern: contains dashes and length > 20
  * Validate extracted password against expected format
- Added format validation with regex before returning password
- Added detailed debug logging for each extraction step
- Improved error messages with screenshot paths

**Testing:**
Test now successfully completes for both alice and bob test users:
- Logs in to Nextcloud
- Generates app password in Security settings
- Extracts password from dialog
- Navigates to Astrolabe settings
- Enters and saves app password
- Verifies "Active" badge appears
- Confirms credentials stored in database

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 19:32:06 +01:00
Chris Coutinho 8f83034c79 Merge pull request #446 from cbcoutinho/renovate/qdrant-1.x
chore(deps): update helm release qdrant to v1.16.3
2025-12-22 13:21:33 +01:00
renovate-bot-cbcoutinho[bot] d195fc43d2 chore(deps): update helm release qdrant to v1.16.3 2025-12-22 11:09:45 +00:00
Chris Coutinho 1a5bb10cd0 feat(config): consolidate configuration with smart dependency resolution (ADR-021)
Simplifies configuration by consolidating overlapping settings and adding
automatic dependency resolution. This makes semantic search configuration
significantly easier for users while maintaining 100% backward compatibility.

## Key Changes

### Variable Renaming (Backward Compatible)
- `VECTOR_SYNC_ENABLED` → `ENABLE_SEMANTIC_SEARCH` (old name still works)
- `ENABLE_OFFLINE_ACCESS` → `ENABLE_BACKGROUND_OPERATIONS` (old name still works)
- Deprecation warnings logged when old names used
- Old names will be removed in v1.0.0

### Smart Dependency Resolution
- `ENABLE_SEMANTIC_SEARCH` automatically enables background operations in multi-user modes
- No need to set both `ENABLE_OFFLINE_ACCESS` and `VECTOR_SYNC_ENABLED` anymore
- Single-user mode doesn't auto-enable background ops (not needed)

### Explicit Mode Selection (Optional)
- New `MCP_DEPLOYMENT_MODE` environment variable
- Valid values: single_user_basic, multi_user_basic, oauth_single_audience,
  oauth_token_exchange, smithery
- Removes ambiguity about which deployment mode is active
- Falls back to auto-detection if not set (existing behavior)

### Configuration Templates
- Reorganized `env.sample` by deployment mode with clear sections
- Added mode-specific quick-start templates:
  - `env.sample.single-user` - Simplest configuration
  - `env.sample.oauth-multi-user` - Recommended multi-user
  - `env.sample.oauth-advanced` - Token exchange mode

## Implementation Details

### Files Modified
- `nextcloud_mcp_server/config.py` - Smart dependency resolution helpers
- `nextcloud_mcp_server/config_validators.py` - Simplified validation, explicit mode
- `tests/unit/test_config_validators.py` - 19 new tests (60 total, all passing)
- `env.sample` - Reorganized by deployment mode
- `docs/configuration.md` - Complete rewrite with consolidated approach
- `docs/troubleshooting.md` - New consolidation troubleshooting section
- `README.md` - Updated variable references

### New Files
- `docs/ADR-021-configuration-consolidation.md` - Architecture decision record
- `docs/configuration-migration-v2.md` - Comprehensive migration guide
- `env.sample.single-user` - Single-user quick-start template
- `env.sample.oauth-multi-user` - OAuth multi-user quick-start template
- `env.sample.oauth-advanced` - Token exchange quick-start template

## User Impact

### Before (Confusing)
```bash
ENABLE_OFFLINE_ACCESS=true      # Why both?
VECTOR_SYNC_ENABLED=true        # What's the relationship?
```

### After (Simplified)
```bash
MCP_DEPLOYMENT_MODE=oauth_single_audience  # Explicit (optional)
ENABLE_SEMANTIC_SEARCH=true                # Auto-enables background ops!
```

### Benefits
- 📉 2 fewer variables to understand for semantic search
- 📋 Clear intent ("I want semantic search")
- 🎯 Explicit mode declaration available
- 🔄 100% backward compatible
-  All 265 unit tests passing

## Testing
- All 60 config validation tests passing
- 10 new tests for configuration consolidation
- 9 new tests for explicit mode selection
- Full unit test suite: 265 tests passing
- Backward compatibility verified

## Migration
Users can migrate at their own pace. Old variable names continue working
with deprecation warnings. See docs/configuration-migration-v2.md for
detailed migration instructions.

Related: ADR-021

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 20:36:36 +01:00
github-actions[bot] 34273ec01e bump: version 0.4.4 → 0.5.0 astrolabe-v0.5.0 2025-12-20 20:42:30 +00:00
github-actions[bot] fd7f33943d bump: version 0.56.2 → 0.57.0 v0.57.0 2025-12-20 20:42:29 +00:00
Chris Coutinho ecaa1f8f01 Merge pull request #443 from cbcoutinho/feature/multi-user-deployment
refactor(config): centralize configuration validation and add dynamic Astrolabe testing
2025-12-20 21:42:10 +01:00
Chris Coutinho 981f102b27 fix(config): address reviewer feedback
- Restore CI test filter (-m unit -m smoke) for faster CI runs
- Replace local path reference with ADR-020 reference in config_validators.py
- Add comprehensive BasicAuthMiddleware unit tests (10 tests covering all edge cases)

Addresses critical CI issue and improves test coverage for multi-user BasicAuth mode.
2025-12-20 21:16:17 +01:00
Chris Coutinho 94febf1602 ci(test): build Astrolabe app before running tests
Add build step for Astrolabe app in CI workflow to compile frontend
assets before docker-compose starts.

Changes:
- Install Node.js 20 for Astrolabe build
- Run composer install --no-dev for Astrolabe PHP dependencies
- Run npm ci and npm run build to compile frontend assets

This ensures the Astrolabe app is properly built in CI, similar to
the existing OIDC app build process.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 21:11:28 +01:00
Chris Coutinho 286a3eb20f feat(auth): add multi-user BasicAuth pass-through mode
Implement multi-user BasicAuth pass-through mode (ADR-020) where each
request includes BasicAuth credentials that are forwarded to Nextcloud
APIs without persistent storage.

Changes:
- Add _get_client_from_basic_auth() in context.py to extract credentials
  from Authorization header (set by BasicAuthMiddleware)
- Add AstrolabeClient for app password provisioning via Astrolabe API
- Update oauth_sync.py with dual credential support (app passwords first,
  then refresh tokens as fallback)
- Simplify oauth_tools.py provisioning logic
- Add integration tests for app password provisioning and multi-user BasicAuth

Features:
- Stateless multi-user mode: credentials passed per-request
- Optional background sync via app passwords (stored in Astrolabe)
- Falls back to refresh tokens if app password not available
- Test coverage for provisioning flow and pass-through mode

Related: ADR-019 (Multi-user BasicAuth), ADR-020 (Deployment Modes)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 20:55:31 +01:00
Chris Coutinho 19b209f412 test: Enable all tests 2025-12-20 20:53:02 +01:00
Chris Coutinho cd7ba5685a feat(astrolabe): add dynamic MCP server configuration for testing
Replace static post-installation configuration with dynamic test-time
configuration to support testing multiple MCP server deployments.

Changes:
- Remove static MCP server URL and OAuth client setup from post-installation
- Add configure_astrolabe_for_mcp_server fixture (session-scoped)
- Fixture dynamically configures:
  * Nextcloud system config (mcp_server_url, mcp_server_public_url)
  * OAuth client creation via occ oidc:create
  * Client credential storage (astrolabe_client_id, astrolabe_client_secret)
- Update existing OAuth tests to use dynamic configuration
- Add test_astrolabe_multi_server_integration.py with parametrized tests

Benefits:
- Test Astrolabe with mcp-oauth, mcp-keycloak, mcp-multi-user-basic
- Each test configures for its specific MCP server
- No static configuration conflicts between deployments
- Cleaner post-installation (37 lines, down from 85)

Test Results:
- test_astrolabe_configuration_for_different_servers: PASSED (mcp-oauth, mcp-keycloak)
- test_astrolabe_reconfiguration: PASSED

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 20:49:53 +01:00
Chris Coutinho 4507359760 refactor(config): centralize configuration validation and simplify startup
Implement centralized configuration validation (ADR-020) to simplify
deployment mode detection and improve error messages.

Changes:
- Create ADR-020 documenting 5 deployment modes with required/optional config
- Add config_validators.py with validate_configuration() and mode detection
- Simplify app.py startup with single validation point at get_app()
- Remove duplicate is_oauth_mode() function (43 lines)
- Fix DeploymentMode mapping (only SELF_HOSTED and SMITHERY_STATELESS exist)
- Add comprehensive unit tests (41 tests covering all modes and edge cases)
- Add enable_multi_user_basic_auth to Settings and BasicAuthMiddleware

Docker Compose:
- Remove conflicting ENABLE_MULTI_USER_BASIC_AUTH from mcp-oauth service
- Add dedicated mcp-multi-user-basic service on port 8003

Test Results:
- 237/237 integration tests PASSED
- All deployment modes verified: single-user BasicAuth, multi-user BasicAuth,
  OAuth single-audience, OAuth token exchange (Keycloak), Smithery stateless

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 20:49:28 +01:00
Chris Coutinho 8682fa4f88 ci: Handle NO_COMMITS_TO_BUMP gracefully in bump scripts
When commitizen finds no eligible commits to bump, it exits with
code 1 and outputs [NO_COMMITS_TO_BUMP]. This was causing the
GitHub Actions workflow to fail even though this is an expected
scenario.

Updated all three bump scripts (bump-mcp.sh, bump-helm.sh,
bump-astrolabe.sh) to:
- Detect the [NO_COMMITS_TO_BUMP] message
- Exit with code 0 (success) instead of code 1
- Output an informational message instead of an error

This allows the bump-version workflow to complete successfully
when no version bumps are needed, matching the workflow's existing
logic that handles empty BUMPED_COMPONENTS.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 13:17:50 +01:00
Chris Coutinho 53b84200d4 ci: Gracefully exit on no commit bump 2025-12-20 13:11:11 +01:00
Chris Coutinho f5e5965864 Merge pull request #421 from cbcoutinho/renovate/nextcloud-openapi-extractor-1.x
chore(deps): update dependency nextcloud/openapi-extractor to v1.8.7
2025-12-20 13:01:09 +01:00
Chris Coutinho 989c3d7541 Merge pull request #420 from cbcoutinho/renovate/icewind1991-nextcloud-version-matrix-digest
chore(deps): update icewind1991/nextcloud-version-matrix digest to c2bf575
2025-12-20 13:00:39 +01:00
Chris Coutinho 4bda647271 Merge pull request #422 from cbcoutinho/renovate/peter-evans-create-pull-request-7.x
chore(deps): update peter-evans/create-pull-request action to v7.0.11
2025-12-20 13:00:02 +01:00
Chris Coutinho 32f3380205 Merge pull request #419 from cbcoutinho/renovate/pin-dependencies
chore(deps): pin dependencies
2025-12-20 12:59:55 +01:00
renovate-bot-cbcoutinho[bot] 0d6b8a935d chore(deps): update peter-evans/create-pull-request action to v7.0.11 2025-12-20 11:12:56 +00:00
renovate-bot-cbcoutinho[bot] eece9ebadc chore(deps): update dependency nextcloud/openapi-extractor to v1.8.7 2025-12-20 11:12:49 +00:00
renovate-bot-cbcoutinho[bot] c390378278 chore(deps): update icewind1991/nextcloud-version-matrix digest to c2bf575 2025-12-20 11:12:35 +00:00
renovate-bot-cbcoutinho[bot] bd424a1ab7 chore(deps): pin dependencies 2025-12-20 11:12:17 +00:00
github-actions[bot] f8734b3edd bump: version 0.56.1 → 0.56.2 v0.56.2 2025-12-20 00:13:59 +00:00
Chris Coutinho 0ea7145df1 Merge pull request #407 from cbcoutinho/renovate/docker-setup-buildx-action-digest
chore(deps): update docker/setup-buildx-action digest to 8d2750c
2025-12-20 01:13:40 +01:00
github-actions[bot] f7a3d2d8f5 bump: version 0.4.3 → 0.4.4 astrolabe-v0.4.4 2025-12-20 00:04:37 +00:00
Chris Coutinho 18298177f7 fix(astrolabe): screenshots in info.xml 2025-12-20 01:04:20 +01:00
github-actions[bot] d9fa81082a bump: version 0.4.2 → 0.4.3 astrolabe-v0.4.3 2025-12-19 23:58:57 +00:00
Chris Coutinho 651b73545d fix(astrolabe): screenshots in info.xml 2025-12-20 00:58:40 +01:00
github-actions[bot] 46505210cd bump: version 0.4.1 → 0.4.2 astrolabe-v0.4.2 2025-12-19 23:52:44 +00:00
github-actions[bot] abf051afdb bump: version 0.56.0 → 0.56.1 v0.56.1 2025-12-19 23:52:44 +00:00
Chris Coutinho d4d1a332fb fix(astrolabe): Update screenshots 2025-12-20 00:52:21 +01:00
Chris Coutinho a3ed321e14 fix(ci): skip existing Helm chart releases to prevent duplicate release errors
The chart-releaser workflow was failing when the Helm chart version hadn't
changed but the MCP server version was bumped. Added skip_existing: true to
gracefully handle this scenario.
2025-12-19 22:41:04 +01:00
Chris Coutinho 2bb738ed3f bump: version 0.4.0 → 0.4.1 astrolabe-v0.4.1 2025-12-19 22:31:29 +01:00
Chris Coutinho 10c8b62818 bump: version 0.3.2 → 0.4.0 2025-12-19 22:30:46 +01:00
github-actions[bot] 87abadbbfc bump: version 0.55.1 → 0.56.0 v0.56.0 2025-12-19 21:29:13 +00:00
Chris Coutinho defc55a5dc feat(ci): add --increment flag to bump scripts for manual version control
Allows forcing specific version bumps (PATCH|MINOR|MAJOR) instead of
relying solely on commitizen's automatic detection based on conventional
commits.

Usage:
  ./scripts/bump-mcp.sh --increment MINOR
  ./scripts/bump-helm.sh --increment PATCH
  ./scripts/bump-astrolabe.sh --increment MAJOR
2025-12-19 22:28:43 +01:00
github-actions[bot] 6a68e45e7c bump: version 0.3.1 → 0.3.2 astrolabe-v0.3.2 astrolabe-v0.3.3 2025-12-19 21:12:28 +00:00
Chris Coutinho a2fa4b2832 fix(astrolabe): add contents:write permission to appstore workflow
The workflow was failing to create GitHub releases with 'Not Found' error
because it lacked the required permissions. Added contents:write permission
to allow creating releases and uploading artifacts.
2025-12-19 22:12:06 +01:00
github-actions[bot] 9cfadbfc04 bump: version 0.3.0 → 0.3.1 astrolabe-v0.3.1 2025-12-19 21:04:50 +00:00
Chris Coutinho 6fed78196e fix(astrolabe): update commitizen pattern to properly update info.xml version
The pattern 'version' was too broad and matched multiple lines:
- <?xml version="1.0"?>
- <version>0.2.1</version>
- min-version="30" max-version="32"

Changed to '<version>' to specifically match only the version tag.

Also fixed version mismatch: info.xml now correctly shows 0.3.0 to match
the version in .cz.toml and package.json.
2025-12-19 22:04:26 +01:00
github-actions[bot] db430dd2c9 bump: version 0.2.0 → 0.3.0 2025-12-19 20:55:59 +00:00
Chris Coutinho 3618aed39e fix(astrolabe): prevent workflow failure when only helm/astrolabe commits exist
When filtering commits with grep -v, if all commits are filtered out,
grep returns exit code 1 which causes the pipeline to fail with set -e.

Wrap grep commands in { ... || true; } to ensure they don't fail the
pipeline when they filter out all results.

This fixes the workflow failure when a fix(astrolabe): commit is pushed
without any MCP server changes.
2025-12-19 21:55:36 +01:00
Chris Coutinho 4c083c7314 fix(astrolabe): info.xml 2025-12-19 21:48:27 +01:00