Files
pulse/docs/RELEASE.md
T

12 KiB

Pulse Release Guide

This document outlines the process and checklist for creating new releases of the ProxMox Pulse application.

Release Types

Releases should be created when there are:

  • New features
  • Bug fixes
  • Security updates
  • Breaking changes
  • Significant dependency updates that affect runtime behavior

For development-only changes (like dev dependency updates), wait for the next feature/bugfix release.

Prerequisites

Before creating a release, ensure you have:

  • Git configured with appropriate credentials
  • Docker installed and logged in to Docker Hub
  • Docker buildx configured for multi-architecture builds:
    # Check if buildx is available
    docker buildx version
    
    # List existing builders
    docker buildx ls
    
    # Create a new builder if needed
    docker buildx create --name multiarch-builder --driver docker-container --bootstrap
    
    # Use the builder
    docker buildx use multiarch-builder
    
    # Verify platforms
    docker buildx inspect --bootstrap
    
  • GitHub CLI (gh) installed and authenticated
  • All changes committed to main branch
  • All items in the checklist below completed

Release Checklist

  1. Preparation

    • Ensure all desired changes are committed and pushed to main
    • Run tests to verify everything is working correctly
    • Decide on new version number (MAJOR.MINOR.PATCH)
  2. Documentation

    • Find the last release version:
      # List all release tags
      git tag -l 'v*' --sort=-v:refname | head -n1
      
      # Or find it in CHANGELOG.md
      head -n5 CHANGELOG.md
      
    • Review commits since last release:
      # Using the last release tag (e.g., v1.3.1)
      git log v1.3.1..HEAD --pretty=format:"%h %s"
      
      # Or using commit dates if needed
      git log --since="$(git log -1 --format=%ai v1.3.1)" --pretty=format:"%h %s"
      
    • Update CHANGELOG.md with new version section and date
    • Categorize changes based on commit types:
      • feat: → Added (new features)
      • fix: → Fixed (bug fixes)
      • security: → Security (security fixes)
      • chore:/refactor:/perf: → Changed (changes in existing functionality)
      • deprecate: → Deprecated (soon-to-be removed features)
      • remove: → Removed (now removed features)
      • docs: → Documentation (if significant)
    • Ensure all significant changes are documented in the changelog
    • Review and clean up the changelog entries:
      • Use clear, user-focused language
      • Group related changes together
      • Remove internal/trivial changes
      • Highlight breaking changes or required actions
  3. Testing

    • Build and test backend: npm run build
    • Build and test frontend: cd frontend && npm run build && cd ..
    • Test application using local development setup:
      # Start the application using the development script
      npm run dev
      
      # This script will:
      # 1. Stop any running Pulse Docker containers
      # 2. Kill any existing servers on ports 7654 and 3000
      # 3. Start the backend in development mode
      # 4. Start the frontend Vite dev server
      
      # Verify in browser:
      # 1. UI loads correctly at http://localhost:3000
      # 2. Version number is correct
      # 3. Can connect to Proxmox
      # 4. Metrics are updating
      # 5. All charts and graphs render
      # 6. Hot reloading works for frontend changes
      
    • Test Docker build (for release verification):
      # Clean all existing containers and images
      docker compose -f docker-compose.dev.yml down
      docker rmi $(docker images -q rcourtman/pulse)
      
      # Build fresh and test locally using dev compose file
      docker compose -f docker-compose.dev.yml up -d --build
      
      # Verify in browser:
      # 1. UI loads correctly at http://localhost:7654
      # 2. Version number is correct
      # 3. Can connect to Proxmox
      # 4. Metrics are updating
      # 5. All charts and graphs render
      
      # Check logs for any errors
      docker logs pulse-app
      
    • Test clean Docker installation:
      # Create a fresh test directory
      mkdir -p /tmp/pulse-test && cd /tmp/pulse-test
      
      # Create minimal docker-compose.yml
      cat > docker-compose.yml << 'EOF'
      services:
        pulse-app:
          image: rcourtman/pulse:X.Y.Z
          ports:
            - "7654:7654"
          env_file:
            - .env
          environment:
            - NODE_ENV=production
          restart: unless-stopped
      EOF
      
      # Copy your test .env file
      cp /path/to/your/test/.env .
      
      # Test deployment
      docker compose up -d
      
      # Verify as above and check logs
      docker logs pulse-app
      
    • Test multi-architecture support:
      # Verify both architectures
      docker buildx imagetools inspect rcourtman/pulse:X.Y.Z
      
      # Test pulling on different architectures if available
      

Development Workflow

For active development, use npm run dev instead of Docker. This script provides:

  • Hot reloading for frontend changes
  • Automatic backend restart on changes
  • Direct access to logs and debugging
  • Faster iteration cycles than Docker rebuilds
# Start development servers
npm run dev

# Access the application:
# - Frontend: http://localhost:3000 (with hot reloading)
# - Backend: http://localhost:7654

Additional development commands available:

# Kill specific processes if needed
npm run dev:kill:backend  # Kill backend server
npm run dev:kill:frontend # Kill frontend server
npm run dev:kill:all     # Kill all development servers

# Start frontend separately if needed
npm run dev:frontend

# Use mock data for development
npm run dev:mock

Only use Docker testing when:

  • Verifying the release build
  • Testing multi-architecture support
  • Checking production deployment configurations
  • Validating the Docker image before release

Release Process

  1. Update version numbers in:

    • frontend/src/utils/version.js
    • package.json
    • frontend/package.json
    • Dockerfile labels (update version in LABEL version="X.Y.Z")
  2. Rebuild the frontend with the new version:

    # Clean the frontend build directory
    rm -rf frontend/dist
    
    # Rebuild the frontend
    cd frontend && npm run build && cd ..
    
    # Verify the new version appears in the built files
    grep -r "VERSION = " frontend/dist/assets/*.js
    
  3. Test the build locally:

    # Build and run locally to verify version using dev compose file
    docker compose -f docker-compose.dev.yml up -d --build
    
    # Check the version in UI at http://localhost:7654
    # IMPORTANT: Verify the version number matches the new release version
    
  4. Once verified, commit version updates including the built frontend:

    # Add all version-related files and the built frontend
    git add frontend/src/utils/version.js package.json frontend/package.json Dockerfile frontend/dist
    
    # Commit the changes
    git commit -m "chore: bump version to X.Y.Z"
    
    # Push to main
    git push origin main
    
  5. Create and push tag:

    git tag -a vX.Y.Z -m "Release vX.Y.Z"
    git push origin vX.Y.Z
    
  6. Build and push Docker images:

    # Verify buildx setup
    docker buildx ls
    
    # Ensure using correct builder
    docker buildx use multiarch-builder
    
    # Build and push multi-architecture images
    # Note: The multi-stage Dockerfile will:
    # 1. Build frontend in isolated stage (only rebuilds on frontend changes)
    # 2. Build backend in isolated stage (only rebuilds on backend changes)
    # 3. Create minimal production image with only runtime dependencies
    docker buildx build \
      --platform linux/amd64,linux/arm64 \
      --tag rcourtman/pulse:X.X.X \
      --tag rcourtman/pulse:latest \
      --push \
      .
    
    # Verify the images and architectures
    docker buildx imagetools inspect rcourtman/pulse:X.X.X
    
  7. Create GitHub release:

    # Extract the latest version's changes from CHANGELOG.md
    awk '/^## \[.*\]/{p=NR==1}p' CHANGELOG.md > release-notes.tmp
    
    # Create the release using the extracted notes
    gh release create vX.Y.Z --title "Release vX.Y.Z" --notes-file release-notes.tmp
    
    # Clean up
    rm release-notes.tmp
    
  8. Release Verification Checklist

    • GitHub Actions:

      • All workflows completed successfully
      • No warnings or errors in logs
    • Docker Image Testing:

      • Fresh pull test:
        docker pull rcourtman/pulse:X.Y.Z
        
      • Clean installation test:
        • Create new directory with only docker-compose.yml and .env
        • Deploy using pulled image
        • Verify functionality
      • Version verification:
        • Check version in UI matches release
        • Check version in Docker labels
        • Check version in application logs
      • Multi-architecture verification:
        • Confirm both amd64 and arm64 images are available
        • Test on different architectures if possible
    • Application Functionality:

      • UI loads correctly
      • Static assets are served properly
      • Can connect to Proxmox
      • Metrics collection works
      • Charts and graphs render
      • WebSocket connection stable
      • No console errors
    • Documentation:

      • README is up to date
      • CHANGELOG reflects all changes
      • Docker Hub description is current
      • GitHub release notes are clear
    • Regression Testing:

      • Previously reported issues remain fixed
      • No new issues introduced
      • Core features working as expected

If any of these checks fail:

  1. Do not proceed with the release
  2. Document the failure
  3. Fix the issue
  4. Restart testing from the beginning

Troubleshooting

GitHub Actions Issues

  • Check workflow files in .github/workflows/
  • Ensure proper event triggers
  • Check GitHub Actions tab for errors

Docker Issues

  • Verify Docker daemon is running
  • Check Docker Hub authentication: docker login
  • Verify push permissions
  • Check multi-arch builder setup:
    # If buildx builder is missing or not working
    docker buildx create --name multiarch-builder --driver docker-container --bootstrap
    docker buildx use multiarch-builder
    docker buildx inspect --bootstrap
    
  • If build fails, try rebuilding the builder:
    docker buildx rm multiarch-builder
    docker buildx create --name multiarch-builder --driver docker-container --bootstrap
    
  • For faster builds:
    • The multi-stage Dockerfile optimizes builds by:
      • Caching frontend and backend builds separately
      • Only rebuilding stages that have changed
      • Minimizing the final image size
    • Frontend-only changes (like version updates) will only rebuild the frontend stage
    • Backend-only changes will only rebuild the backend stage
    • To force a clean build: docker buildx build --no-cache ...
    • To clean up old build cache: docker builder prune
    • To see what's using build cache: docker buildx du
    • For version updates, ensure you:
      1. Update version in all files
      2. Rebuild frontend locally and verify version
      3. Commit changes including built frontend
      4. Build and push Docker image

Version Mismatches

  • Verify all version files are updated:
    • frontend/src/utils/version.js
    • package.json
    • frontend/package.json
    • Dockerfile labels
  • Always rebuild frontend after version changes
  • Verify version in built frontend before creating Docker image
  • Test version in UI after Docker build
  • Create patch release if needed

Post-Release

  1. Verify the release is working in production
  2. Clean up any temporary files/branches
  3. Announce release to users if needed
  4. Update documentation if required
  5. Start planning next release