Release v1.0.1: CI/CD Simplification
We're excited to announce MoLOS v1.0.1, a maintenance release focused on simplifying our CI/CD workflows, improving manual release processes, and enhancing production Docker builds. This release makes it easier to maintain and deploy MoLOS while maintaining all the stability of v1.0.0.
What's New in v1.0.1
CI/CD Simplification
We've simplified our CI/CD workflows by removing unnecessary pipelines:
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [develop, main]
pull_request:
branches: [develop, main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm build
- name: Type check
run: pnpm typecheck
Removed Workflows
The following workflows have been removed to simplify operations:
.github/workflows/release.yml- Automated releases.github/workflows/test.yml- Separate test pipeline
These have been consolidated into the main CI workflow and manual release process.
Manual Release Workflow
We've moved to a manual release workflow for better control:
# Create a release
npm run release
# This will:
# 1. Run all tests
# 2. Update version numbers
# 3. Generate changelog
# 4. Create git tag
# 5. Push to GitHub
# 6. Create GitHub release
Release Script
The release script automates the manual process:
// scripts/release.ts
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
async function release() {
console.log('Starting release process...');
// Run tests
console.log('Running tests...');
await execAsync('pnpm test');
// Build project
console.log('Building project...');
await execAsync('pnpm build');
// Type check
console.log('Type checking...');
await execAsync('pnpm typecheck');
// Get current version
const { version } = JSON.parse(
await fs.readFile('package.json', 'utf-8')
);
// Create git tag
console.log(`Creating tag v${version}...`);
await execAsync(`git tag -a v${version} -m "Release v${version}"`);
// Push tag
console.log('Pushing tag...');
await execAsync('git push origin v${version}');
// Create GitHub release
console.log('Creating GitHub release...');
await execAsync(`gh release create v${version} --notes "Release v${version}"`);
console.log(`✓ Release v${version} complete!`);
}
release().catch(console.error);
Production Docker Build Improvements
Multi-Stage Build Optimization
We've optimized the production Docker build with better layer caching:
FROM node:20-alpine AS base
# Install build dependencies
RUN apk add --no-cache \
ca-certificates \
dumb-init \
gosu
WORKDIR /app
# Copy dependency files
COPY package.json pnpm-lock.yaml ./
RUN corepack enable pnpm && \
pnpm install --frozen-lockfile
FROM base AS build
# Copy source code
COPY . .
# Build application
RUN pnpm build
FROM node:20-alpine AS production
# Install runtime dependencies only
RUN apk add --no-cache \
ca-certificates \
dumb-init \
gosu
# Create non-root user
RUN addgroup -g 1001 -S molos && \
adduser -S -u 1001 -G molos molos
WORKDIR /app
# Copy built application
COPY --from=build --chown=molos:molos /app/dist ./dist
COPY --from=build --chown=molos:molos /app/node_modules ./node_modules
COPY --from=build --chown=molos:molos /app/package.json ./package.json
# Copy entrypoint
COPY --chown=molos:molos docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
# Switch to non-root user
USER molos
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/api/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
# Expose port
EXPOSE 3000
# Set environment
ENV NODE_ENV=production
# Use dumb-init for proper signal handling
ENTRYPOINT ["dumb-init", "--"]
CMD ["docker-entrypoint.sh", "node", "dist/index.js"]
Docker Compose Configuration
Enhanced Docker Compose for production:
version: '3.8'
services:
molos:
image: molos-app:v1.0.1
container_name: molos
restart: unless-stopped
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- ORIGIN=${ORIGIN:-https://molos.example.com}
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
- DATABASE_URL=/data/molos.db
volumes:
- molos-data:/data
healthcheck:
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/api/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
volumes:
molos-data:
driver: local
Module Improvements
Module Version Bump
We've bumped active module versions:
// modules.config.ts
export const modulesConfig = {
production: {
modules: [
{
id: 'molos-tasks',
repository: 'https://github.com/MoLOS-App/Modules/MoLOS-Tasks',
tag: 'v1.0.3', // Updated from v1.0.2
enabled: true
},
{
id: 'molos-notes',
repository: 'https://github.com/MoLOS-App/Modules/MoLOS-Notes',
tag: 'v1.0.1', // Updated from v1.0.0
enabled: true
}
]
}
};
Module Loading Refinements
Improved module loading and scoping logic:
// server/modules/loader.ts
export async function loadModule(moduleConfig: ModuleConfig) {
// Validate module configuration
const validation = await validateModule(moduleConfig);
if (!validation.valid) {
throw new ModuleLoadError(
`Module ${moduleConfig.id} is invalid: ${validation.errors.join(', ')}`
);
}
// Load module metadata
const metadata = await getModuleMetadata(moduleConfig);
// Initialize module
const module = await initializeModule(metadata);
// Apply module scoping
await applyModuleScoping(module);
console.log(`✓ Loaded module: ${metadata.name} v${metadata.version}`);
return module;
}
MCP Refinements
Auth Key Renaming
We renamed API keys to auth keys for clarity:
// Renamed from apiKey to authKey
export interface MCPAuthKey {
id: string;
name: string;
authKeyHash: string; // Previously apiKeyHash
scopes: string[];
expiresAt: Date | null;
createdAt: Date;
}
MCP Configuration UI
Enhanced MCP configuration in admin settings:
<!-- src/routes/admin/mcp/+page.svelte -->
<script lang="ts">
import MCPSettings from './MCPSettings.svelte';
import AuthKeys from './AuthKeys.svelte'; // Previously APIKeys
let activeTab = 'settings';
</script>
<div class="mcp-admin">
<nav class="tabs">
<button
class="tab {activeTab === 'settings' ? 'active' : ''}"
onclick={() => activeTab = 'settings'}
>
Settings
</button>
<button
class="tab {activeTab === 'keys' ? 'active' : ''}"
onclick={() => activeTab = 'keys'}
>
Auth Keys
</button>
</nav>
{#if activeTab === 'settings'}
<MCPSettings />
{:else if activeTab === 'keys'}
<AuthKeys />
{/if}
</div>
Admin Settings Refactoring
We extracted admin settings into modular components:
<!-- src/routes/admin/+page.svelte -->
<script lang="ts">
import GeneralSettings from './components/GeneralSettings.svelte';
import AuthSettings from './components/AuthSettings.svelte';
import ModuleSettings from './components/ModuleSettings.svelte';
import MCPSettings from './components/MCPSettings.svelte';
let activeSection = 'general';
const sections = [
{ id: 'general', label: 'General', component: GeneralSettings },
{ id: 'auth', label: 'Authentication', component: AuthSettings },
{ id: 'modules', label: 'Modules', component: ModuleSettings },
{ id: 'mcp', label: 'MCP', component: MCPSettings }
];
</script>
<div class="admin-page">
<aside class="sidebar">
<nav>
{#each sections as section}
<button
class="nav-item {activeSection === section.id ? 'active' : ''}"
onclick={() => activeSection = section.id}
>
{section.label}
</button>
{/each}
</nav>
</aside>
<main class="content">
{#each sections as section}
{#if activeSection === section.id}
<svelte:component this={section.component} />
{/if}
{/each}
</main>
</div>
Documentation Updates
Release Notes
We've added comprehensive release notes for v1.0.0:
# Release v1.0.0
## What's New
- First stable production release
- Production-ready Docker images with security hardening
- All core modules verified and tested
- Comprehensive API documentation
## Migration Guide
See [Migration Guide](/docs/migration-v1-0-0) for upgrading from previous versions.
## Breaking Changes
None from v0.5.0-alpha.
## Known Issues
See [Known Issues](https://github.com/MoLOS-App/MoLOS/issues) for current issues.
Changelog Updates
Updated changelog to reflect all changes:
# Changelog
## [1.0.1] - 2026-03-18
### Added
- Manual release workflow script
- Enhanced production Docker builds
- Modular admin settings components
### Changed
- Renamed API keys to auth keys (MCP)
- Bumped module versions
- Simplified CI/CD workflows
### Removed
- Automated release workflow
- Separate test pipeline
## [1.0.0] - 2026-03-13
### Added
- First stable production release
- Production Docker images
- All core modules
See full changelog for details.
What's Changed Since v1.0.0
Bug Fixes
- Fixed authentication issues for HTTP deployments
- Improved module loading and scoping
Improvements
- Simplified CI/CD workflows
- Enhanced production Docker builds
- Improved admin settings UI
- Better module version management
Documentation
- Added v1.0.0 release notes
- Added migration guide
- Updated changelog
Upgrading from v1.0.0
Quick Upgrade
# Pull latest changes
git fetch origin
git checkout v1.0.1
# Update dependencies
pnpm install
# Restart application
docker-compose down
docker-compose pull
docker-compose up -d
Manual Upgrade
# Update dependencies
pnpm install
# No migrations needed
# Build
pnpm build
# Restart
pnpm start
Key Commits
- chore(release): prepare v1.0.1 release
- ci: simplify workflows by removing release and test pipelines
- docs(release): add v1.0.0 release notes and migration guide
- chore(modules): bump active module versions
- refactor(admin): extract admin settings page into modular components
- refactor: improve auth flow and add MCP configuration
- refactor(mcp): rename API keys to auth keys for clarity
What's Next
The v1.0.1 release improves operational simplicity. Our focus for v1.1.0 includes:
- PostgreSQL support
- Performance optimizations
- Enhanced mobile experience
- Advanced analytics
- Real-time collaboration features
The v1.0.1 release simplifies operations while maintaining all the stability and features of v1.0.0.
