DeesseJS

Changelog Plugin

Version history and release notes management

Changelog Plugin

The Changelog Plugin provides a complete version history and release notes management system for tracking product updates, features, bug fixes, and improvements over time.

Installation

npm install @deessejs/plugin-changelog

Configuration

// deesse.config.ts
import { defineConfig } from '@deessejs/core'
import { changelogPlugin } from '@deessejs/plugin-changelog'

export const config = defineConfig({
  plugins: [
    changelogPlugin({
      // Version format
      versionFormat: 'semver', // 'semver' or 'custom'

      // Entry types
      entryTypes: [
        { id: 'added', label: 'Added', color: 'green', icon: 'Plus' },
        { id: 'changed', label: 'Changed', color: 'yellow', icon: 'RefreshCw' },
        { id: 'deprecated', label: 'Deprecated', color: 'orange', icon: 'AlertTriangle' },
        { id: 'removed', label: 'Removed', color: 'red', icon: 'Trash2' },
        { id: 'fixed', label: 'Fixed', color: 'blue', icon: 'Wrench' },
        { id: 'security', label: 'Security', color: 'purple', icon: 'Shield' },
      ],

      // Display options
      display: {
        groupByType: true,
        showDates: true,
        showAuthors: true,
        reverseOrder: false, // Newest first
      },

      // Public access
      publicAccess: {
        published: true,    // Public can see published versions
        drafts: false,      // Public cannot see drafts
        future: false,      // Public cannot see future releases
      },
    }),
  ],
})

Collections

Versions

Version entries for each release:

{
  name: 'versions',
  fields: [
    {
      name: 'version',
      type: 'string',
      required: true,
      unique: true,
      admin: {
        description: 'Semantic version (e.g., 1.0.0)',
      },
    },
    {
      name: 'status',
      type: 'enum',
      enum: ['draft', 'published', 'scheduled'],
      defaultValue: 'draft',
    },
    {
      name: 'releaseDate',
      type: 'datetime',
      admin: {
        description: 'When this version was/will be released',
      },
    },
    {
      name: 'description',
      type: 'text',
      admin: {
        description: 'Brief summary of this release',
      },
    },
    {
      name: 'type',
      type: 'enum',
      enum: ['major', 'minor', 'patch'],
      defaultValue: 'patch',
    },
    {
      name: 'featured',
      type: 'boolean',
      defaultValue: false,
      admin: {
        description: 'Highlight this version on the changelog page',
      },
    },
    {
      name: 'author',
      type: 'reference',
      relation: 'users',
    },
  ],
}

Changelog Entries

Individual change entries within versions:

{
  name: 'changelogEntries',
  fields: [
    {
      name: 'version',
      type: 'reference',
      relation: 'versions',
      required: true,
    },
    {
      name: 'type',
      type: 'enum',
      enum: ['added', 'changed', 'deprecated', 'removed', 'fixed', 'security'],
      required: true,
    },
    {
      name: 'title',
      type: 'string',
      required: true,
    },
    {
      name: 'description',
      type: 'richtext',
    },
    {
      name: 'category',
      type: 'string',
      admin: {
        description: 'Optional category for grouping',
      },
    },
    {
      name: 'breaking',
      type: 'boolean',
      defaultValue: false,
      admin: {
        description: 'This is a breaking change',
      },
    },
    {
      name: 'author',
      type: 'reference',
      relation: 'users',
    },
    {
      name: 'order',
      type: 'number',
      defaultValue: 0,
      admin: {
        description: 'Order within the version',
      },
    },
  ],
}

Admin Pages

The plugin adds the following admin pages:

Versions Page

  • List all versions
  • Version status management (draft, published, scheduled)
  • Quick publish/unpublish actions
  • Bulk operations
  • Filter by type, status, date range

Changelog Entries Page

  • List all entries grouped by version
  • Drag-and-drop reordering
  • Filter by type, category, breaking status
  • Quick edit interface

API Routes

# Get all versions
GET /api/changelog/versions

# Get published versions (public)
GET /api/changelog/versions/published

# Get latest version
GET /api/changelog/versions/latest

# Get specific version
GET /api/changelog/versions/:version

# Get entries for a version
GET /api/changelog/versions/:version/entries

# Get entries by type
GET /api/changelog/entries?type=added

# Get breaking changes
GET /api/changelog/entries/breaking

# Compare versions
GET /api/changelog/compare/:from/:to

Frontend Components

Changelog Component

import { Changelog } from '@deessejs/plugin-changelog/components'

export default function ChangelogPage() {
  return (
    <Changelog
      showFilter
      groupBy="type"      // 'type', 'category', 'version'
      reverseOrder        // Newest first
      maxVersions={10}    // Show last 10 versions
    />
  )
}

VersionCard Component

import { VersionCard } from '@deessejs/plugin-changelog/components'

export function Release({ version }) {
  return (
    <VersionCard
      version={version}
      showDate
      showAuthor
      showEntryCount
      collapsible
      defaultExpanded
    />
  )
}

EntryBadge Component

import { EntryBadge } from '@deessejs/plugin-changelog/components'

export function ChangeTypeBadge({ type }) {
  return (
    <EntryBadge
      type={type}
      showIcon
      size="md"
    />
  )
}

BreakingChangesAlert Component

import { BreakingChangesAlert } from '@deessejs/plugin-changelog/components'

export default function Layout() {
  return (
    <BreakingChangesAlert
      version="2.0.0"
      showIn="banner"    // 'banner', 'inline', 'modal'
    />
  )
}

Hooks

useVersions

'use client'

import { useVersions } from '@deessejs/plugin-changelog/hooks'

export default function Changelog() {
  const { versions, loading, error } = useVersions({
    status: 'published',
    orderBy: { releaseDate: 'desc' },
  })

  return (
    <div>
      {versions.map(version => (
        <section key={version.id}>
          <h2>{version.version}</h2>
          <time>{version.releaseDate}</time>
        </section>
      ))}
    </div>
  )
}

useLatestVersion

'use client'

import { useLatestVersion } from '@deessejs/plugin-changelog/hooks'

export default function Header() {
  const { version, loading } = useLatestVersion()

  if (loading) return null

  return (
    <div>
      Latest: {version.version}
    </div>
  )
}

Server Components

getVersions

import { getVersions } from '@deessejs/plugin-changelog/server'

export default async function ChangelogPage() {
  const versions = await getVersions({
    where: { status: 'published' },
    include: { entries: true, author: true },
    orderBy: { releaseDate: 'desc' },
  })

  return (
    <main>
      {versions.map(version => (
        <section key={version.id}>
          <h2>{version.version}</h2>
          <p>{version.description}</p>
        </section>
      ))}
    </main>
  )
}

getVersion

import { getVersion } from '@deessejs/plugin-changelog/server'

export default async function VersionPage({ params }) {
  const version = await getVersion({
    where: { version: params.version },
    include: { entries: true },
  })

  return (
    <main>
      <h1>Version {version.version}</h1>
      <p>{version.description}</p>
    </main>
  )
}

URL Structure

/changelog                      # Changelog home
/changelog/version/:version     # Specific version
/changelog/latest               # Latest version
/changelog/feed                 # RSS feed
/changelog/atom                 # Atom feed
/admin/changelog                # Admin changelog
/admin/changelog/versions       # Admin versions page
/admin/changelog/entries        # Admin entries page

RSS/Atom Feeds

Auto-generated feeds for changelog:

# RSS feed
/rss/changelog

# Atom feed
/atom/changelog

# JSON feed
/api/changelog/feed

Version Comparison

Compare two versions to see changes:

import { compareVersions } from '@deessejs/plugin-changelog/server'

export default async function ComparePage() {
  const comparison = await compareVersions('1.0.0', '2.0.0')

  return (
    <div>
      <h2>Changes from {comparison.from} to {comparison.to}</h2>
      <ul>
        {comparison.changes.map(change => (
          <li key={change.id}>{change.title}</li>
        ))}
      </ul>
    </div>
  )
}

Breaking Changes

Special handling for breaking changes:

changelogPlugin({
  breakingChanges: {
    highlightInList: true,
    requireConfirmation: true,
    notification: {
      enabled: true,
      duration: 5000,  // Show for 5 seconds
      position: 'top',
    },
  },
})

Scheduled Releases

Schedule releases for future dates:

// Create a scheduled version
await db.versions.create({
  data: {
    version: '2.0.0',
    status: 'scheduled',
    releaseDate: new Date('2025-03-01'),
  },
})

// Cron job to auto-publish
await publishScheduledVersions()

Semantic Versioning

Enforce semantic versioning rules:

changelogPlugin({
  semver: {
    autoDetect: true,       // Auto-detect version type from changes
    requireConventional: true, // Require conventional commit format
    bumpStrategy: 'auto',   // 'major', 'minor', 'patch', 'auto'
  },
})

GitHub Integration

Integrate with GitHub releases:

changelogPlugin({
  github: {
    enabled: true,
    token: process.env.GITHUB_TOKEN,
    owner: 'your-org',
    repo: 'your-repo',
    syncOnPublish: true,    // Create GitHub release on publish
    importExisting: true,   // Import existing releases
  },
})

Custom Entry Types

Add custom entry types:

changelogPlugin({
  entryTypes: [
    { id: 'added', label: 'Added', color: 'green', icon: 'Plus' },
    { id: 'changed', label: 'Changed', color: 'yellow', icon: 'RefreshCw' },
    { id: 'fixed', label: 'Fixed', color: 'blue', icon: 'Wrench' },
    // Custom types
    { id: 'performance', label: 'Performance', color: 'purple', icon: 'Zap' },
    { id: 'documentation', label: 'Documentation', color: 'pink', icon: 'Book' },
  ],
})

Categories

Organize entries by category:

changelogPlugin({
  categories: [
    'api',
    'ui',
    'database',
    'authentication',
    'performance',
    'bugfixes',
  ],
})

Next Steps

On this page