Development

Contributing, testing, and development workflows for ZineCore2

This section covers development workflows, testing, code standards, and troubleshooting for ZineCore2 contributors.

For Contributors

Development Setup

Quick start for contributors:

# Clone repository
git clone https://github.com/ZineCore2/server.git
cd server
git submodule update --init

# Setup environment
uv venv
source .venv/bin/activate
uv sync

# Configure database
createdb zinecore2
cd backend
DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py migrate

# Load data
DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py load_vocabularies

# Run tests
DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py test

# Start development server
DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py runserver

Development Workflow

1. Issue/Feature Discussion

Before writing code:

  1. Check GitHub Issues
  2. Create issue if doesn't exist
  3. Discuss approach with maintainers
  4. Get consensus before large changes

2. Create Feature Branch

git checkout -b feature/descriptive-name

Branch naming:

  • feature/ — New features
  • fix/ — Bug fixes
  • docs/ — Documentation changes
  • refactor/ — Code refactoring

3. Make Changes

  • Follow Code Style guide
  • Write tests for new functionality
  • Update documentation if needed

4. Run Tests

DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py test

All tests must pass before submitting PR.

5. Submit Pull Request

  1. Push branch to GitHub
  2. Create pull request
  3. Link to related issue
  4. Wait for review

Development Tools

Django Debug Toolbar

For development, install Django Debug Toolbar:

pip install django-debug-toolbar

Add to settings/development.py:

INSTALLED_APPS += ['debug_toolbar']
MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware']
INTERNAL_IPS = ['127.0.0.1']

Shell Plus

Enhanced Django shell with auto-loaded models:

pip install django-extensions
DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  python manage.py shell_plus

Database GUI

Connect with your preferred database tool:

Host: localhost
Port: 5433 (docker-compose) or 5432 (local)
Database: zinecore2
User: postgres
Password: postgres

Code Organization

server/
├── backend/                # Django project
│   ├── catalog/           # Zines (ZineCore2)
│   ├── agents/            # Agents (AgentCore2)
│   ├── holdings/          # Holdings (HoldingCore2)
│   ├── repositories/      # Repositories (RepoCore2)
│   ├── vocabularies/      # Controlled vocabularies
│   ├── geography/         # Geographic data
│   ├── core/              # Shared utilities
│   └── zinecore/          # Project settings
├── spec/                  # Specification (submodule)
└── docs/                  # Additional documentation

Common Development Tasks

Add a New Field

See Add Custom Fields

Create a Migration

See Database Migrations

Add a New Endpoint

Step 1: Add to ViewSet:

# catalog/views.py
from rest_framework.decorators import action
from rest_framework.response import Response

class ZineViewSet(viewsets.ModelViewSet):
    # ... existing code ...

    @action(detail=True, methods=['get'])
    def related(self, request, zine_id=None):
        """Get related zines"""
        zine = self.get_object()
        # Custom logic here
        return Response({'related': []})

Step 2: Test:

curl http://localhost:8000/api/zines/zine_001/related/

Add a New Vocabulary

Step 1: Edit spec canonical:

cd spec
# Edit vocabularies/canonical/new-vocab.json

Step 2: Rebuild:

node scripts/build-vocabularies.js

Step 3: Create Django model:

# vocabularies/models.py
class NewVocab(BaseVocabulary):
    class Meta:
        verbose_name_plural = "new vocabs"

Step 4: Create migration and load:

python manage.py makemigrations
python manage.py migrate
python manage.py load_vocabularies

Best Practices

DO:

✅ Write tests for new features

# catalog/tests.py
class ZineTestCase(TestCase):
    def test_create_zine(self):
        # Test logic
        pass

✅ Document your code

def complex_function(param):
    """
    Brief description.

    Args:
        param: Description of param

    Returns:
        Description of return value
    """
    pass

✅ Keep commits focused

One logical change per commit.

✅ Update CHANGELOG.md

Document user-facing changes.

DON'T:

❌ Commit directly to main

Always use feature branches.

❌ Mix unrelated changes

Keep PRs focused on one issue.

❌ Skip tests

All PRs must include tests.

❌ Break backwards compatibility

Without discussion and migration path.


Release Process

  1. Update version in pyproject.toml
  2. Update CHANGELOG.md
  3. Create release branch: release/v1.2.0
  4. Test thoroughly
  5. Merge to main
  6. Tag release: git tag v1.2.0
  7. Push tags: git push --tags
  8. Create GitHub release

Getting Help

Questions?

Found a bug?

  • Check existing issues
  • Create new issue with reproducible example
  • Include error messages and logs

Want to contribute?

  • Read Contributing
  • Pick an issue labeled "good first issue"
  • Ask questions before starting

Ready to contribute? Start with the Contributing guide.
Copyright ©2026 ZineCore2 Contributors,