Skip to content

Legacy Single-Version Mode (Deprecated) ​

⚠️ DEPRECATION NOTICE

Legacy single-version mode is deprecated and will be removed in a future release. It is kept for backward compatibility during the migration period.

Recommended: Use the multi-version build system (current default). See the Architecture & Workflows documentation for details.

Overview ​

Legacy mode builds only the latest version of each application. This was the original implementation before the multi-version system was introduced.

Status ​

  • Current Default: Multi-version mode (USE_MULTI_VERSION: true)
  • Legacy Workflows Available: Yes, but not used by default
  • Removal Timeline: To be determined (likely 6+ months after multi-version stabilization)

How to Enable Legacy Mode ​

Via Manual Trigger ​

  1. Go to Actions → Global build
  2. Click Run workflow
  3. Set parameters:
    • USE_MULTI_VERSION: false
  4. Click Run workflow

Edit .github/workflows/build.yml:

yaml
env:
  USE_MULTI_VERSION: false  # Change from true to false

Legacy Workflows ​

Active Legacy Workflows ​

  • .github/workflows/mattermost.yml
  • .github/workflows/mostlymatter.yml
  • .github/workflows/outline.yml

These workflows are only called when USE_MULTI_VERSION: false.

How Legacy Mode Works ​

Build Pipeline ​

┌────────────────────────────────────────────────────────────┐
│  1. INFOS JOB: Version Detection                           │
│  ────────────────────────────────────────────────────────  │
│  • Fetch latest version from upstream                      │
│  • Check if image exists in GHCR                           │
│  • Output: tag, image-status (200/404)                     │
└─────────────────────┬──────────────────────────────────────┘
                      │
                      ▼ (only if image-status == 404)
┌────────────────────────────────────────────────────────────┐
│  2. BUILD JOB: Build Latest Version Only                   │
│  ────────────────────────────────────────────────────────  │
│  Matrix: [amd64, arm64] (static from matrix.json)          │
│                                                            │
│  • Clone source at latest version tag                      │
│  • Build for each architecture                             │
│  • Push by digest                                          │
│  • Upload digest artifact                                  │
└─────────────────────┬──────────────────────────────────────┘
                      │
                      ▼
┌────────────────────────────────────────────────────────────┐
│  3. MERGE JOB: Create Multi-Arch Manifest                  │
│  ────────────────────────────────────────────────────────  │
│  • Download digests for all architectures                  │
│  • Create multi-arch manifest                              │
│  • Tag with version + "latest"                             │
└────────────────────────────────────────────────────────────┘

Key Characteristics ​

  1. Single Version Only

    • Builds only the most recent release from upstream
    • Does not actively maintain version history (old tags persist but become stale)
    • Always tags as latest + version tag
  2. Simple Matrix

    • Static matrix from matrix.json
    • No dynamic version expansion
    • Architecture-based parallelization only
  3. Simpler Logic

    • No semantic versioning comparison
    • No multi-version coordination
    • Straightforward 3-job pipeline

Limitations of Legacy Mode ​

1. No Active Version History Management ​

  • Only builds the latest version from upstream
  • Old version tags remain in registry but aren't maintained
  • If upstream supports multiple major versions, only the newest major is mirrored
  • No automated maintenance of historical versions

Example:

bash
# Legacy mode behavior
docker pull ghcr.io/this-is-tobi/mirror/mattermost:10.3.0  # ✅ Available (built previously)
docker pull ghcr.io/this-is-tobi/mirror/mattermost:latest  # → 10.3.0

# After new release (10.3.1)
docker pull ghcr.io/this-is-tobi/mirror/mattermost:10.3.0  # ✅ Still exists (not deleted)
docker pull ghcr.io/this-is-tobi/mirror/mattermost:10.3.1  # ✅ Newly built
docker pull ghcr.io/this-is-tobi/mirror/mattermost:latest  # → 10.3.1

# However, 10.3.0 won't receive updates (security patches, rebuilds, etc.)
# And if 11.0.0 is released while 10.x is still maintained upstream:
# Legacy mode only mirrors 11.0.0, not both 10.x and 11.x branches

2. Limited Version Coverage ​

  • Only mirrors the single "latest" release
  • Doesn't track multiple maintained branches (e.g., 10.x LTS + 11.x stable)
  • Historical versions not rebuilt if base images need updates
  • Old tags exist but may become stale over time

3. Inefficient for Skipped Builds ​

  • Checks if latest exists every time
  • If exists, skips entirely (good)
  • If missing, builds from scratch (no incremental)

4. No Semantic Versioning ​

  • Uses "most recent release" as latest
  • Doesn't compare version numbers
  • Could tag older version as latest if release order is wrong

5. Rebuild Required for Rollback ​

  • Want to rollback to previous version?
  • Must manually rebuild old version
  • No guarantee old version still builds (dependencies may have changed)

Comparison: Legacy vs Multi-Version ​

FeatureLegacy ModeMulti-Version Mode
Actively MaintainedLatest version onlyLast N versions (default: 10)
Version Tags in RegistryAll built (accumulate forever)All built (accumulate forever)
Version CoverageSingle latest releaseMultiple concurrent branches
Rollback SupportOld tags available (stale)Recent versions maintained
Build FrequencyEvery 6 hoursEvery 6 hours
Incremental BuildsSkip if exists, else rebuildOnly missing versions built
Semantic VersioningNo - uses release orderYes - smart latest detection
CI ComplexitySimple (3-job pipeline)Moderate (4-job pipeline)
Storage UsageGrows over time (all versions)Grows over time (all versions)
Build TimeFast if exists, else fullOptimized (incremental)

When to Use Legacy Mode ​

Valid Use Cases (Temporary) ​

  1. Testing Issues

    • Multi-version mode has a bug
    • Need quick workaround
    • Use legacy until fix is deployed
  2. Reduced Build Activity

    • Want to minimize build frequency for a single version
    • Testing environment with minimal requirements
    • Note: Both modes accumulate storage over time (neither deletes old versions)
  3. Debugging

    • Comparing behavior between modes
    • Validating multi-version correctness
  1. Production Deployments

    • Multi-version provides better stability
    • Rollback capability is valuable
  2. Long-Term Use

    • Legacy mode will be removed
    • Migration will be required eventually
  3. New Projects

    • Start with multi-version from beginning
    • No migration burden later

Migration to Multi-Version Mode ​

Step 1: Understand the Changes ​

What Changes:

  • Registry will have multiple version tags
  • latest tag behavior remains the same
  • Old version tags persist (don't disappear)

What Doesn't Change:

  • Build schedule (still every 6 hours)
  • Image quality and architecture support
  • Registry location and namespace

Step 2: Test Multi-Version Mode ​

bash
# Trigger manual build with multi-version
# Actions → Global build → Run workflow
#   USE_MULTI_VERSION: true
#   MAX_VERSIONS: 3  (start small)

Verify:

bash
# Check multiple versions exist
docker pull ghcr.io/this-is-tobi/mirror/mattermost:10.3.1
docker pull ghcr.io/this-is-tobi/mirror/mattermost:10.3.0
docker pull ghcr.io/this-is-tobi/mirror/mattermost:10.2.1

# Verify latest points to highest version
docker manifest inspect ghcr.io/this-is-tobi/mirror/mattermost:latest

Step 3: Update Deployments (Optional) ​

If you use latest tag, no changes needed. For version pinning:

Before (Legacy):

yaml
image: ghcr.io/this-is-tobi/mirror/mattermost:latest

After (Multi-Version):

yaml
# Option 1: Continue using latest (recommended for most)
image: ghcr.io/this-is-tobi/mirror/mattermost:latest

# Option 2: Pin to specific version (for stability)
image: ghcr.io/this-is-tobi/mirror/mattermost:10.3.1

# Option 3: Pin to major.minor (track patches)
image: ghcr.io/this-is-tobi/mirror/mattermost:10.3

Step 4: Enable Multi-Version by Default ​

Once validated, multi-version mode is already the default:

yaml
# .github/workflows/build.yml (already set)
env:
  USE_MULTI_VERSION: true  # Default

Step 5: Monitor First Runs ​

  • Check GitHub Actions logs
  • Verify all versions build successfully
  • Confirm latest tag points to correct version
  • Test rollback by pulling older version

Troubleshooting Legacy Mode ​

Issue: Image Not Building ​

Symptom: Workflow completes but image doesn't update

Cause: Image already exists (status 200)

Solution:

bash
# Check image status in workflow logs
# Look for: "Status code of mirror image: 200"

# If you need to force rebuild:
# 1. Delete image from GHCR (manual)
# 2. Re-run workflow

Issue: Wrong Version Built ​

Symptom: Expected version X, got version Y

Cause: Upstream API returned different "latest"

Solution:

bash
# Check what upstream reports as latest:
# For Mattermost:
curl -s https://api.github.com/repos/mattermost/mattermost/releases/latest \
  | jq -r '.tag_name'

# For Mostlymatter:
curl -s "https://framagit.org/api/v4/projects/12345/repository/tags" \
  | jq -r '[.[] | select(.name | test("^v[0-9]+\\.[0-9]+\\.[0-9]+-limitless$"))] | .[0].name'

# For Outline:
curl -s https://api.github.com/repos/outline/outline/releases/latest \
  | jq -r '.tag_name'

Legacy Workflow Structure ​

Example: mattermost.yml (Legacy) ​

yaml
name: Mattermost

on:
  workflow_call:
    inputs:
      REGISTRY: ...
      NAMESPACE: ...

jobs:
  infos:
    runs-on: ubuntu-latest
    outputs:
      tag: ${{ steps.infos.outputs.TAG }}
      build-matrix: ${{ steps.infos.outputs.BUILD_MATRIX }}
      image-status: ${{ steps.infos.outputs.IMAGE_STATUS }}
    steps:
      - name: Get latest version
        run: |
          # Fetch latest release
          TAG=$(curl ... | jq -r '.tag_name')
          
          # Check if exists
          IMAGE_STATUS=$(curl --head ... | grep HTTP)
          
          echo "TAG=$TAG" >> $GITHUB_OUTPUT
          echo "IMAGE_STATUS=$IMAGE_STATUS" >> $GITHUB_OUTPUT

  build:
    if: ${{ needs.infos.outputs.image-status == '404' }}
    needs: infos
    matrix:
      runners: [ubuntu-24.04, ubuntu-24.04-arm]
      images: ${{ fromJSON(needs.infos.outputs.build-matrix) }}
    steps:
      # Build for single version, multiple architectures
      
  merge:
    if: ${{ needs.infos.outputs.image-status == '404' }}
    needs: [infos, build]
    steps:
      # Create multi-arch manifest
      # Tag with version + latest

Key Differences from Multi-Version:

  • Simple outputs: just tag, build-matrix, image-status
  • Single version check
  • Static matrix from JSON file
  • Condition: image-status == '404' (not has-builds == 'true')

Timeline & Removal Plan ​

Phase 1: Multi-Version Introduction (Current) ​

  • [x] Multi-version workflows created
  • [x] Set as default mode
  • [x] Legacy workflows kept for compatibility
  • [x] Documentation updated

Phase 2: Stabilization ​

  • [ ] Monitor multi-version mode in production
  • [ ] Fix any issues that arise
  • [ ] Gather user feedback
  • [ ] Validate storage and performance

Phase 3: Deprecation Notice ​

  • [ ] Add deprecation warnings to legacy workflows
  • [ ] Update documentation with removal timeline
  • [ ] Notify users via README

Phase 4: Removal ​

  • [ ] Remove legacy workflow files
  • [ ] Remove USE_MULTI_VERSION toggle from build.yml
  • [ ] Update documentation (remove legacy docs)
  • [ ] Clean up orchestrator workflow

FAQ ​

Q: Can I use both modes simultaneously? ​

A: No. The orchestrator (build.yml) uses USE_MULTI_VERSION toggle to select one mode:

  • true → Calls multi-version workflows
  • false → Calls legacy workflows

Q: What happens to existing images when switching? ​

A: Nothing! Images in GHCR persist. Switching modes only affects future builds.

Q: Can I switch back to legacy mode after testing multi-version? ​

A: Yes, simply set USE_MULTI_VERSION: false. However, multi-version images remain in registry.

Q: Will legacy mode receive bug fixes? ​

A: Critical security fixes only. New features and improvements will be multi-version only.

Q: How long will legacy mode be supported? ​

A: At least 6-12 months after multi-version stabilization. A deprecation notice will be issued with specific timeline.

Q: What if I have custom workflows based on legacy mode? ​

A: You'll need to migrate to multi-version approach or maintain your custom workflows independently.

Getting Help ​

If you need assistance with legacy mode:

  1. Check Documentation: This guide and the Troubleshooting section
  2. Review Workflow Logs: GitHub Actions → Workflow runs
  3. Compare with Multi-Version: See the Architecture & Workflows documentation
  4. Open Issue: If you find bugs or need help migrating