Contributing
Thank you for your interest in contributing to Gyre! This document outlines the standards and processes for contributing to this project.
Getting Started
Prerequisites
Quick Start (DevContainer - Recommended)
The repository includes a devcontainer that installs Node.js 22.13+, pnpm@11.1.0, and Kubernetes tooling.
- Open the repository in VS Code with the Dev Containers extension
- Press
F1→ "Dev Containers: Reopen in Container" - Wait for
.devcontainer/post-create.shto install dependencies
# Inside devcontainer, start development server
pnpm dev
The host kubeconfig is mounted read-only from ~/.kube. Use an existing cluster or create a local kind cluster with FluxCD manually when needed:
kind create cluster
flux install
Manual Setup
# Install dependencies
pnpm install
# Start development server
pnpm dev
# Or start with auto-open
pnpm dev -- --open
Development Setup
Project Structure
gyre/
├── src/
│ ├── lib/
│ │ ├── components/ # Reusable UI components
│ │ ├── server/ # Server-only code (DB, auth, K8s)
│ │ ├── templates/ # Resource creation templates
│ │ └── stores/ # Svelte 5 runes-based stores
│ └── routes/ # SvelteKit routes
├── charts/gyre/ # Helm chart for deployment
├── documentation/ # Docusaurus docs site
└── data/ # SQLite database (dev)
Important Architecture Notes
-
Server vs Client Code: Code in
src/lib/server/ONLY runs server-side. Never import from there in.sveltecomponent<script>tags—use SvelteKit load functions instead. -
Svelte 5 Runes: This project uses Svelte 5 with runes (
$state,$derived,$effect,$props). Do NOT use legacy Svelte syntax:<!-- Good --><script>let count = $state(0);let doubled = $derived(count * 2);</script><!-- Bad --><script>let count = 0;$: doubled = count * 2;</script> -
Deployment Model: Production is Helm/GitOps-first and in-cluster. Local out-of-cluster mode is supported for development/testing via
~/.kube/configas detailed in the Development Guide.
Code Standards
TypeScript
- Strict mode enabled: All code must pass TypeScript strict checks
- Use explicit types for function parameters and return values
- Avoid
anytype—useunknownwith type guards when necessary
Code Quality Commands
Use these before commit/push:
# Default local gate (auto-formats first)
pnpm verify
# Strict app-only gate (non-mutating)
pnpm verify:ci
# Docs gate
pnpm docs:check
# Repo-wide checks
pnpm helm:check
pnpm scripts:check
pnpm verify:repo
pnpm verify:repo:ci
Styling
- TailwindCSS v4: Uses the Vite plugin (not PostCSS)
- Use Tailwind utility classes for styling
- Follow the existing zinc/gold theme color palette
- Use shadcn-svelte components for consistency
Component Guidelines
-
Use TypeScript for all
.sveltefiles:<script lang="ts"> -
Keep components focused and single-responsibility
-
Use Svelte 5 snippets for reusable template blocks
-
Properly type props with
$props()rune -
Use the
classprop pattern for component customization:import { cn } from '$lib/utils.js';let { class: className, ...props }: { class?: string } = $props();
Commit Message Convention
We follow the Conventional Commits specification:
<type>(<scope>): <description>
[optional body]
[optional footer(s)]
Types
- feat: A new feature
- fix: A bug fix
- docs: Documentation-only changes
- style: Code style changes (formatting, semicolons, etc.)
- refactor: Code change that neither fixes a bug nor adds a feature
- perf: Performance improvement
- test: Adding or correcting tests
- chore: Changes to build process or auxiliary tools
- ci: Changes to CI configuration files
Scopes
Common scopes in this project:
templates- Resource creation templateswizard- Resource wizard systemauth- Authentication and authorizationui- User interface componentsapi- API routes and server endpointsserver- Server-side utilitiesdb- Database schema and queriesk8s- Kubernetes integrationflux- FluxCD resource handlinghelm- Helm chart
Examples
feat(templates): add validation for GitRepository URL format
fix(auth): resolve session timeout handling for SSO users
docs: update README with new installation instructions
refactor(api): consolidate Flux resource API endpoints
chore: bump dependencies to latest versions
ci: add multi-arch Docker build workflow
Footer for Co-Authors
If multiple people contributed to a commit:
feat(ui): add dark mode toggle
Implemented dark mode support across all components.
Co-Authored-By: Jane Doe <jane@example.com>
Branch Naming Convention
Name your branch based on the type of change you're making:
<type>/<short-description>
Branch Type Prefixes
Use the same type prefixes as commit messages:
- feat/ - New features
- fix/ - Bug fixes
- docs/ - Documentation changes
- refactor/ - Code refactoring
- chore/ - Maintenance tasks
- ci/ - CI/CD changes
Pull Request Process
- Create a branch from
mainfollowing the naming convention above. - Make your changes following the code standards.
- Test your changes in a cluster when behavior depends on Kubernetes integration.
- Run quality checks (
pnpm verifyfor app-only local checks,pnpm verify:repo:cifor full repo parity). - Commit using conventional commit format.
- Push your branch and open a Pull Request.
Testing
Automated tests are required and part of normal verification (pnpm test, pnpm verify:ci, pnpm verify:repo:ci).
Tests run through Vitest on Node.js with pnpm test.
Before Submitting a PR
- Test in a real Kubernetes cluster with FluxCD installed.
- Test both success and error paths.
- Check browser console for client-side errors.
- Review server logs for backend issues.
- Test on different screen sizes for UI changes.
Setting Up a Test Environment
# Create test cluster
kind create cluster --name gyre-test
# Install FluxCD
flux install
# Build and load image
docker build -t gyre:test .
kind load docker-image gyre:test --name gyre-test
# Install via Helm
kubectl create namespace flux-system --dry-run=client -o yaml | kubectl apply -f -
kubectl create secret generic gyre-encryption -n flux-system \
--from-literal=GYRE_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
--from-literal=AUTH_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
--from-literal=BACKUP_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
--from-literal=BETTER_AUTH_SECRET="$(openssl rand -hex 32)" \
--dry-run=client -o yaml | kubectl apply -f -
kubectl create secret generic gyre-metrics -n flux-system \
--from-literal=GYRE_METRICS_TOKEN="$(openssl rand -hex 32)" \
--dry-run=client -o yaml | kubectl apply -f -
helm install gyre charts/gyre -n flux-system \
--set image.tag=test \
--set image.pullPolicy=Never \
--set encryption.existingSecret=gyre-encryption \
--set metrics.existingSecret=gyre-metrics
# Port forward to test
kubectl port-forward -n flux-system svc/gyre 9999:80
Reporting Issues
When reporting bugs, please include:
- Gyre version
- Kubernetes version
- FluxCD version
- Steps to reproduce
- Expected vs Actual behavior
- Screenshots & Logs
Adding New Features
Adding a New FluxCD Resource Type
- Define types in
src/lib/server/kubernetes/flux/types.ts. - Add resource utilities in
src/lib/server/kubernetes/flux/resources.ts. - Create API routes in
src/routes/api/v1/flux/[resourceType]/. - Add UI components in
src/lib/components/flux/resources/. - Update navigation in
src/routes/+layout.svelte. - Add resource template in
src/lib/templates/index.ts. - Update RBAC permissions in
charts/gyre/templates/role.yamlandcharts/gyre/templates/clusterrole.yaml.
License
By contributing, you agree that your contributions will be licensed under the MIT License.