Implement API file versioning system for deployment tracking #83

Closed
opened 2025-06-24 19:47:44 +02:00 by Michael · 5 comments
Michael commented 2025-06-24 19:47:44 +02:00 (Migrated from gitea.dragons-at-work.de)

Problem

Currently difficult to track which API version is running where:

  • Local development version vs walter test version
  • walter version vs aitvaras production version
  • No easy way to verify deployed API matches expected version

Requirements

  • Version info in API responses - /health endpoint shows version
  • File-based versioning - version.lua or VERSION file
  • Git-based version detection - derive from git commit/tag
  • Environment indicator - dev/test/prod in responses
  • Deployment verification - script to check remote API version

Proposed Implementation

1. Version Detection (version.lua)

return {
    version = "1.0.0",
    commit = "abc123def",  -- from git rev-parse HEAD
    environment = "development", -- from ENV variable
    build_time = "2025-06-24T18:45:00Z"
}

2. Enhanced /health endpoint

{
    "status": "healthy",
    "service": "furt-lua",
    "version": "1.0.0",
    "commit": "abc123def",
    "environment": "walter-test",
    "deployment_time": "2025-06-24T18:45:00Z"
}

3. Version check script

# scripts/check_version.sh
curl http://walter:8080/health | jq '.version'
curl http://aitvaras:8080/health | jq '.version' 

Use Cases

  • Development: Verify local API version before committing
  • Testing: Confirm walter has latest version before website testing
  • Deployment: Verify aitvaras deployment succeeded with correct version
  • Debugging: Quick identification of version mismatches

Implementation Priority

Medium - Helpful for upcoming walter deployment and production rollout.

Files to modify

  • furt-lua/src/version.lua (new)
  • furt-lua/src/main.lua (health endpoint)
  • scripts/check_version.sh (new)
  • scripts/deploy_walter.sh (version verification)
## Problem Currently difficult to track which API version is running where: - Local development version vs walter test version - walter version vs aitvaras production version - No easy way to verify deployed API matches expected version ## Requirements - [ ] **Version info in API responses** - /health endpoint shows version - [ ] **File-based versioning** - version.lua or VERSION file - [ ] **Git-based version detection** - derive from git commit/tag - [ ] **Environment indicator** - dev/test/prod in responses - [ ] **Deployment verification** - script to check remote API version ## Proposed Implementation ### 1. Version Detection (version.lua) ```lua return { version = "1.0.0", commit = "abc123def", -- from git rev-parse HEAD environment = "development", -- from ENV variable build_time = "2025-06-24T18:45:00Z" } ``` ### 2. Enhanced /health endpoint ```json { "status": "healthy", "service": "furt-lua", "version": "1.0.0", "commit": "abc123def", "environment": "walter-test", "deployment_time": "2025-06-24T18:45:00Z" } ``` ### 3. Version check script ```bash # scripts/check_version.sh curl http://walter:8080/health | jq '.version' curl http://aitvaras:8080/health | jq '.version' ``` ## Use Cases - **Development:** Verify local API version before committing - **Testing:** Confirm walter has latest version before website testing - **Deployment:** Verify aitvaras deployment succeeded with correct version - **Debugging:** Quick identification of version mismatches ## Implementation Priority Medium - Helpful for upcoming walter deployment and production rollout. ## Files to modify - furt-lua/src/version.lua (new) - furt-lua/src/main.lua (health endpoint) - scripts/check_version.sh (new) - scripts/deploy_walter.sh (version verification)
michael added this to the v0.1.2 - Gateway Basics milestone 2025-08-14 05:20:48 +02:00
Owner

SCOPE-ÄNDERUNG - Teil der Deployment-Modernisierung

API-Versioning ist eng verknüpft mit DAW/furt#87 (Deployment-System-Redesign):

  • Version-Tracking → Teil des Deploy-Workflows
  • Deployment-Verification → Integration mit Config-Checks (DAW/furt#84)
  • API-Version + Config-Version = Complete Deployment-Validation

Integration in DAW/furt#87: Versioning-Komponente des neuen Deployment-Systems

**SCOPE-ÄNDERUNG - Teil der Deployment-Modernisierung** API-Versioning ist eng verknüpft mit DAW/furt#87 (Deployment-System-Redesign): - Version-Tracking → Teil des Deploy-Workflows - Deployment-Verification → Integration mit Config-Checks (DAW/furt#84) - API-Version + Config-Version = Complete Deployment-Validation **Integration in DAW/furt#87:** Versioning-Komponente des neuen Deployment-Systems
Owner

SCOPE REDUZIERT - Minimal Versioning

Einfaches datei-basiertes Versioning:

  • File: VERSION (im Repository-Root)
  • Inhalt: 0.1.1 (Versionsnummer)
  • API: /health endpoint zeigt Version
  • Schema: Ungerade = Test, Gerade = Production

Removed from scope:

Simple implementation: File lesen → API response

Ready for implementation

**SCOPE REDUZIERT - Minimal Versioning** Einfaches datei-basiertes Versioning: - **File:** VERSION (im Repository-Root) - **Inhalt:** 0.1.1 (Versionsnummer) - **API:** /health endpoint zeigt Version - **Schema:** Ungerade = Test, Gerade = Production **Removed from scope:** - Git-Integration (→ DAW/furt#90) - Deployment-Verification (→ DAW/furt#87 / DAW/furt#88) - Remote-Checks (→ Deployment-System) **Simple implementation:** File lesen → API response **Ready for implementation**
Owner

Issue completed

VERSION-based system implemented:

  • VERSION file in repository root (0.1.1)
  • read_version() function with ?.?.? fallback
  • /health endpoint shows file-based version
  • Server startup displays version

Tested: curl localhost:8080/health returns version 0.1.1

✅ **Issue completed** VERSION-based system implemented: - VERSION file in repository root (0.1.1) - read_version() function with ?.?.? fallback - /health endpoint shows file-based version - Server startup displays version Tested: curl localhost:8080/health returns version 0.1.1
michael 2025-08-15 17:01:38 +02:00
Owner

VCS-Universal Versioning System - Complete Solution

SCOPE EVOLUTION: Von simple file-based zu universal content-hash + distributed mapping

Problem Analysis

Aktuelle file-based Lösung nicht praxistauglich bei:

  1. Multi-Branch Development

    • Alle Branches zeigen gleiche VERSION (0.1.1)
    • Keine Unterscheidung welcher Branch auf walter läuft
    • Merge-Konflikte bei VERSION-Bumps in parallel branches
  2. VCS Migration Scenarios

    • Git → Mercury (wegen Google-Control per Tech-Reference)
    • Future VCS changes (Bazaar, Fossil, eigene Lösung)
    • git-spezifische Commands brechen bei VCS-Wechsel
  3. Open Source Development

    • Deploy-Logs nur lokal verfügbar
    • Andere Entwickler können Versions-Mapping nicht nachvollziehen
    • Bug-Reports referenzieren Hashes ohne Rückverfolgbarkeit
  4. Deployment Heterogenität

    • git clone (walter) vs tar.gz (aitvaras) vs Paket-Installation
    • Unterschiedliche Git-Verfügbarkeit je Deployment-Typ
    • Production-Server ohne VCS-Tools

Solution: Content-Hash + Distributed Version-Mapping

1. VCS-Agnostic Content Hashing

File: scripts/calculate_content_hash.sh

#!/bin/bash
# VCS-unabhängiger Content-Hash über tatsächlichen Code

# Relevante Dateien sammeln (reproduzierbar sortiert)
find src/ -name "*.lua" -type f | sort > /tmp/file_list
find src/ -name "*.c" -type f | sort >> /tmp/file_list

# Content-Hash berechnen (SHA256, first 8 chars)
CONTENT_HASH=$(cat /tmp/file_list | xargs cat | sha256sum | cut -d' ' -f1 | cut -c1-8)

echo $CONTENT_HASH
rm -f /tmp/file_list

Eigenschaften:

  • Gleicher Code → gleicher Hash (reproducible)
  • VCS-unabhängig (funktioniert mit Git, Mercury, tar.gz)
  • Zeigt echten Code-Zustand, nicht VCS-Metadaten

2. Universal VCS Detection System

File: scripts/vcs_utils.sh

#!/bin/bash
# Universal VCS command abstraction

detect_vcs() {
    if [ -d ".git" ]; then
        echo "git"
    elif [ -d ".hg" ]; then
        echo "mercury"
    elif [ -d ".bzr" ]; then
        echo "bazaar"
    elif [ -d ".fossil-settings" ]; then
        echo "fossil"
    else
        echo "none"
    fi
}

get_vcs_hash() {
    case $(detect_vcs) in
        git)     git rev-parse --short HEAD 2>/dev/null || echo "unknown" ;;
        mercury) hg id -i 2>/dev/null | cut -c1-8 || echo "unknown" ;;
        bazaar)  bzr revno 2>/dev/null || echo "unknown" ;;
        fossil)  fossil info | grep checkout | cut -d' ' -f2 | cut -c1-8 || echo "unknown" ;;
        *)       echo "unknown" ;;
    esac
}

get_vcs_branch() {
    case $(detect_vcs) in
        git)     git branch --show-current 2>/dev/null || echo "unknown" ;;
        mercury) hg branch 2>/dev/null || echo "unknown" ;;
        bazaar)  bzr nick 2>/dev/null || echo "unknown" ;;
        fossil)  fossil branch current 2>/dev/null || echo "unknown" ;;
        *)       echo "unknown" ;;
    esac
}

get_vcs_author() {
    case $(detect_vcs) in
        git)     git config user.name 2>/dev/null || whoami ;;
        mercury) hg config ui.username 2>/dev/null | cut -d'<' -f1 | xargs || whoami ;;
        bazaar)  bzr whoami --email 2>/dev/null || whoami ;;
        fossil)  fossil user list | head -n1 || whoami ;;
        *)       whoami ;;
    esac
}

3. Distributed Version-Mapping Database

File: .version_history (committed, für alle Entwickler verfügbar)

# Format: content_hash,vcs_hash,branch,timestamp,author,vcs_type
a7f3d2e1,abc123f,main,2025-08-15T10:30:00Z,michael,git
b8e4c9f2,def456c,feature/auth,2025-08-15T11:45:00Z,sandra,git
c9f5a3d7,789xyz1,hotfix/critical,2025-08-15T14:20:00Z,contributor,mercury
d1e7b4a5,unknown,unknown,2025-08-15T16:00:00Z,deployer,none

Properties:

  • Committed ins Repository (für alle verfügbar)
  • VCS-agnostic Format
  • Automatisch gepflegt via post-commit hooks
  • Funktioniert auch bei VCS-Wechsel (History bleibt)

4. Universal Post-Commit Hook System

File: scripts/install_hooks.sh

#!/bin/bash
# Installiert VCS-spezifische Hooks für automatisches Mapping

source ./scripts/vcs_utils.sh
VCS=$(detect_vcs)

case $VCS in
    git)
        cp scripts/universal_post_commit.sh .git/hooks/post-commit
        chmod +x .git/hooks/post-commit
        echo "Git post-commit hook installed"
        ;;
    mercury)
        # Add to .hg/hgrc
        if ! grep -q "\[hooks\]" .hg/hgrc 2>/dev/null; then
            echo "[hooks]" >> .hg/hgrc
        fi
        echo "commit = ./scripts/universal_post_commit.sh" >> .hg/hgrc
        echo "Mercury commit hook installed"
        ;;
    bazaar)
        echo "post_commit = ./scripts/universal_post_commit.sh" >> .bzr/branch/branch.conf
        echo "Bazaar post-commit hook installed"
        ;;
    *)
        echo "No VCS detected - manual version tracking only"
        ;;
esac

File: scripts/universal_post_commit.sh

#!/bin/bash
# Universal post-commit hook für automatisches Version-Mapping

source ./scripts/vcs_utils.sh

# Current state detection
CONTENT_HASH=$(./scripts/calculate_content_hash.sh)
VCS_HASH=$(get_vcs_hash)
BRANCH=$(get_vcs_branch)
AUTHOR=$(get_vcs_author)
VCS_TYPE=$(detect_vcs)
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

# Check if content actually changed (avoid duplicate entries)
if [ -f ".version_history" ]; then
    LAST_CONTENT=$(tail -n1 .version_history 2>/dev/null | cut -d',' -f1)
    if [ "$CONTENT_HASH" = "$LAST_CONTENT" ]; then
        exit 0  # No content change, skip
    fi
fi

# Append to version history
echo "$CONTENT_HASH,$VCS_HASH,$BRANCH,$TIMESTAMP,$AUTHOR,$VCS_TYPE" >> .version_history

# VCS-specific re-commit (embed history in same commit)
case $VCS_TYPE in
    git)     
        git add .version_history
        git commit --amend --no-edit --no-verify  # --no-verify prevents hook recursion
        ;;
    mercury) 
        hg add .version_history
        hg commit --amend -m "$(hg log -r . --template '{desc}')"
        ;;
    bazaar)
        bzr add .version_history
        bzr commit --unchanged -m "$(bzr log -r -1 --line | cut -d' ' -f2-)"
        ;;
esac

5. Runtime Version Detection

File: src/version.lua (updated)

-- VCS-Universal version detection
local function read_file(filepath)
    local file = io.open(filepath, "r")
    if not file then return nil end
    local content = file:read("*a"):gsub("\n", "")
    file:close()
    return content
end

local function calculate_content_hash()
    local handle = io.popen("./scripts/calculate_content_hash.sh 2>/dev/null")
    if not handle then return "unknown" end
    
    local result = handle:read("*a"):gsub("\n", "")
    handle:close()
    
    return result ~= "" and result or "unknown"
end

local function lookup_version_mapping(content_hash)
    local file = io.open(".version_history", "r")
    if not file then return nil end
    
    for line in file:lines() do
        local c_hash, vcs_hash, branch, timestamp, author, vcs_type = 
            line:match("([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+)")
        if c_hash == content_hash then
            file:close()
            return {
                vcs_hash = vcs_hash,
                branch = branch,
                timestamp = timestamp,
                author = author,
                vcs_type = vcs_type
            }
        end
    end
    file:close()
    return nil
end

local function get_version_info()
    local base_version = read_file("VERSION") or "?.?.?"
    local content_hash = calculate_content_hash()
    local mapping = lookup_version_mapping(content_hash)
    
    local result = {
        base_version = base_version,
        content_hash = content_hash,
        full_version = base_version .. "+" .. content_hash
    }
    
    if mapping then
        result.vcs_info = mapping
        result.debug_version = base_version .. "+" .. content_hash .. " (vcs:" .. mapping.vcs_hash .. "-" .. mapping.branch .. ")"
    end
    
    return result
end

return get_version_info()

API Response Examples

Development (Git):

{
    "status": "healthy",
    "version": "0.1.1+a7f3d2e1",
    "debug_version": "0.1.1+a7f3d2e1 (vcs:abc123f-feature/auth)",
    "vcs_info": {
        "vcs_hash": "abc123f",
        "branch": "feature/auth", 
        "author": "michael",
        "vcs_type": "git"
    }
}

Production (tar.gz):

{
    "status": "healthy", 
    "version": "0.1.1+b8e4c9f2",
    "debug_version": "0.1.1+b8e4c9f2 (vcs:def456c-main)",
    "vcs_info": {
        "vcs_hash": "def456c",
        "branch": "main",
        "author": "michael", 
        "vcs_type": "git"
    }
}

Mercury Development:

{
    "status": "healthy",
    "version": "0.1.1+c9f5a3d7", 
    "debug_version": "0.1.1+c9f5a3d7 (vcs:789xyz1-default)",
    "vcs_info": {
        "vcs_hash": "789xyz1",
        "branch": "default",
        "author": "contributor",
        "vcs_type": "mercury" 
    }
}

Debugging Workflow for Open Source

User reports: "Bug in version 0.1.1+a7f3d2e1"

Any developer can trace:

# 1. Look up content hash in distributed database
grep "a7f3d2e1" .version_history
# → a7f3d2e1,abc123f,feature/auth,2025-08-15T11:45:00Z,sandra,git

# 2. Find original commit (if using Git)
git log --oneline | grep abc123f
# → abc123f Implement API authentication

# 3. Checkout exact state for debugging
git checkout abc123f

Works across VCS migrations:

# Even if project switched Git → Mercury
# .version_history still contains Git mapping
grep "a7f3d2e1" .version_history  
# → Still works! Historical data preserved

Implementation Priority & Phases

Phase 1: Content-Hash Foundation (Immediate)

  • Implement calculate_content_hash.sh
  • Update version.lua for content-hash detection
  • Test with current simple VERSION file

Phase 2: VCS-Universal Detection (Week 2)

  • Implement vcs_utils.sh
  • Add .version_history manual tracking
  • Test across Git/Mercury environments

Phase 3: Automated Hooks (Week 3)

  • Implement universal post-commit hooks
  • Test hook installation across VCS types
  • Validate automatic mapping generation

Phase 4: Full Integration (Week 4)

  • Integration with deployment scripts
  • API response enhancement with vcs_info
  • Documentation and contributor onboarding

Benefits of This Solution

  1. VCS Sovereignty: Works with Git, Mercury, Bazaar, Fossil, or no VCS
  2. True Code Tracking: Content-hash reflects actual running code
  3. Open Source Friendly: Distributed mapping available to all developers
  4. Deployment Agnostic: Works with git clone, tar.gz, packages
  5. Migration Safe: VCS changes don't break version tracking
  6. Debug Friendly: Clear path from runtime version to source code
  7. Future Proof: Extensible to new VCS systems

Status: Complete solution designed - ready for phased implementation

Files to create:

  • scripts/calculate_content_hash.sh
  • scripts/vcs_utils.sh
  • scripts/install_hooks.sh
  • scripts/universal_post_commit.sh
  • Update: src/version.lua

Integration points:

  • Deployment scripts (walter, aitvaras)
  • API health endpoint enhancement
  • Development workflow documentation
## VCS-Universal Versioning System - Complete Solution **SCOPE EVOLUTION:** Von simple file-based zu universal content-hash + distributed mapping ### Problem Analysis **Aktuelle file-based Lösung nicht praxistauglich bei:** 1. **Multi-Branch Development** - Alle Branches zeigen gleiche VERSION (0.1.1) - Keine Unterscheidung welcher Branch auf walter läuft - Merge-Konflikte bei VERSION-Bumps in parallel branches 2. **VCS Migration Scenarios** - Git → Mercury (wegen Google-Control per Tech-Reference) - Future VCS changes (Bazaar, Fossil, eigene Lösung) - git-spezifische Commands brechen bei VCS-Wechsel 3. **Open Source Development** - Deploy-Logs nur lokal verfügbar - Andere Entwickler können Versions-Mapping nicht nachvollziehen - Bug-Reports referenzieren Hashes ohne Rückverfolgbarkeit 4. **Deployment Heterogenität** - git clone (walter) vs tar.gz (aitvaras) vs Paket-Installation - Unterschiedliche Git-Verfügbarkeit je Deployment-Typ - Production-Server ohne VCS-Tools ### Solution: Content-Hash + Distributed Version-Mapping #### 1. VCS-Agnostic Content Hashing **File:** `scripts/calculate_content_hash.sh` ```bash #!/bin/bash # VCS-unabhängiger Content-Hash über tatsächlichen Code # Relevante Dateien sammeln (reproduzierbar sortiert) find src/ -name "*.lua" -type f | sort > /tmp/file_list find src/ -name "*.c" -type f | sort >> /tmp/file_list # Content-Hash berechnen (SHA256, first 8 chars) CONTENT_HASH=$(cat /tmp/file_list | xargs cat | sha256sum | cut -d' ' -f1 | cut -c1-8) echo $CONTENT_HASH rm -f /tmp/file_list ``` **Eigenschaften:** - Gleicher Code → gleicher Hash (reproducible) - VCS-unabhängig (funktioniert mit Git, Mercury, tar.gz) - Zeigt echten Code-Zustand, nicht VCS-Metadaten #### 2. Universal VCS Detection System **File:** `scripts/vcs_utils.sh` ```bash #!/bin/bash # Universal VCS command abstraction detect_vcs() { if [ -d ".git" ]; then echo "git" elif [ -d ".hg" ]; then echo "mercury" elif [ -d ".bzr" ]; then echo "bazaar" elif [ -d ".fossil-settings" ]; then echo "fossil" else echo "none" fi } get_vcs_hash() { case $(detect_vcs) in git) git rev-parse --short HEAD 2>/dev/null || echo "unknown" ;; mercury) hg id -i 2>/dev/null | cut -c1-8 || echo "unknown" ;; bazaar) bzr revno 2>/dev/null || echo "unknown" ;; fossil) fossil info | grep checkout | cut -d' ' -f2 | cut -c1-8 || echo "unknown" ;; *) echo "unknown" ;; esac } get_vcs_branch() { case $(detect_vcs) in git) git branch --show-current 2>/dev/null || echo "unknown" ;; mercury) hg branch 2>/dev/null || echo "unknown" ;; bazaar) bzr nick 2>/dev/null || echo "unknown" ;; fossil) fossil branch current 2>/dev/null || echo "unknown" ;; *) echo "unknown" ;; esac } get_vcs_author() { case $(detect_vcs) in git) git config user.name 2>/dev/null || whoami ;; mercury) hg config ui.username 2>/dev/null | cut -d'<' -f1 | xargs || whoami ;; bazaar) bzr whoami --email 2>/dev/null || whoami ;; fossil) fossil user list | head -n1 || whoami ;; *) whoami ;; esac } ``` #### 3. Distributed Version-Mapping Database **File:** `.version_history` (committed, für alle Entwickler verfügbar) ``` # Format: content_hash,vcs_hash,branch,timestamp,author,vcs_type a7f3d2e1,abc123f,main,2025-08-15T10:30:00Z,michael,git b8e4c9f2,def456c,feature/auth,2025-08-15T11:45:00Z,sandra,git c9f5a3d7,789xyz1,hotfix/critical,2025-08-15T14:20:00Z,contributor,mercury d1e7b4a5,unknown,unknown,2025-08-15T16:00:00Z,deployer,none ``` **Properties:** - Committed ins Repository (für alle verfügbar) - VCS-agnostic Format - Automatisch gepflegt via post-commit hooks - Funktioniert auch bei VCS-Wechsel (History bleibt) #### 4. Universal Post-Commit Hook System **File:** `scripts/install_hooks.sh` ```bash #!/bin/bash # Installiert VCS-spezifische Hooks für automatisches Mapping source ./scripts/vcs_utils.sh VCS=$(detect_vcs) case $VCS in git) cp scripts/universal_post_commit.sh .git/hooks/post-commit chmod +x .git/hooks/post-commit echo "Git post-commit hook installed" ;; mercury) # Add to .hg/hgrc if ! grep -q "\[hooks\]" .hg/hgrc 2>/dev/null; then echo "[hooks]" >> .hg/hgrc fi echo "commit = ./scripts/universal_post_commit.sh" >> .hg/hgrc echo "Mercury commit hook installed" ;; bazaar) echo "post_commit = ./scripts/universal_post_commit.sh" >> .bzr/branch/branch.conf echo "Bazaar post-commit hook installed" ;; *) echo "No VCS detected - manual version tracking only" ;; esac ``` **File:** `scripts/universal_post_commit.sh` ```bash #!/bin/bash # Universal post-commit hook für automatisches Version-Mapping source ./scripts/vcs_utils.sh # Current state detection CONTENT_HASH=$(./scripts/calculate_content_hash.sh) VCS_HASH=$(get_vcs_hash) BRANCH=$(get_vcs_branch) AUTHOR=$(get_vcs_author) VCS_TYPE=$(detect_vcs) TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") # Check if content actually changed (avoid duplicate entries) if [ -f ".version_history" ]; then LAST_CONTENT=$(tail -n1 .version_history 2>/dev/null | cut -d',' -f1) if [ "$CONTENT_HASH" = "$LAST_CONTENT" ]; then exit 0 # No content change, skip fi fi # Append to version history echo "$CONTENT_HASH,$VCS_HASH,$BRANCH,$TIMESTAMP,$AUTHOR,$VCS_TYPE" >> .version_history # VCS-specific re-commit (embed history in same commit) case $VCS_TYPE in git) git add .version_history git commit --amend --no-edit --no-verify # --no-verify prevents hook recursion ;; mercury) hg add .version_history hg commit --amend -m "$(hg log -r . --template '{desc}')" ;; bazaar) bzr add .version_history bzr commit --unchanged -m "$(bzr log -r -1 --line | cut -d' ' -f2-)" ;; esac ``` #### 5. Runtime Version Detection **File:** `src/version.lua` (updated) ```lua -- VCS-Universal version detection local function read_file(filepath) local file = io.open(filepath, "r") if not file then return nil end local content = file:read("*a"):gsub("\n", "") file:close() return content end local function calculate_content_hash() local handle = io.popen("./scripts/calculate_content_hash.sh 2>/dev/null") if not handle then return "unknown" end local result = handle:read("*a"):gsub("\n", "") handle:close() return result ~= "" and result or "unknown" end local function lookup_version_mapping(content_hash) local file = io.open(".version_history", "r") if not file then return nil end for line in file:lines() do local c_hash, vcs_hash, branch, timestamp, author, vcs_type = line:match("([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+)") if c_hash == content_hash then file:close() return { vcs_hash = vcs_hash, branch = branch, timestamp = timestamp, author = author, vcs_type = vcs_type } end end file:close() return nil end local function get_version_info() local base_version = read_file("VERSION") or "?.?.?" local content_hash = calculate_content_hash() local mapping = lookup_version_mapping(content_hash) local result = { base_version = base_version, content_hash = content_hash, full_version = base_version .. "+" .. content_hash } if mapping then result.vcs_info = mapping result.debug_version = base_version .. "+" .. content_hash .. " (vcs:" .. mapping.vcs_hash .. "-" .. mapping.branch .. ")" end return result end return get_version_info() ``` ### API Response Examples **Development (Git):** ```json { "status": "healthy", "version": "0.1.1+a7f3d2e1", "debug_version": "0.1.1+a7f3d2e1 (vcs:abc123f-feature/auth)", "vcs_info": { "vcs_hash": "abc123f", "branch": "feature/auth", "author": "michael", "vcs_type": "git" } } ``` **Production (tar.gz):** ```json { "status": "healthy", "version": "0.1.1+b8e4c9f2", "debug_version": "0.1.1+b8e4c9f2 (vcs:def456c-main)", "vcs_info": { "vcs_hash": "def456c", "branch": "main", "author": "michael", "vcs_type": "git" } } ``` **Mercury Development:** ```json { "status": "healthy", "version": "0.1.1+c9f5a3d7", "debug_version": "0.1.1+c9f5a3d7 (vcs:789xyz1-default)", "vcs_info": { "vcs_hash": "789xyz1", "branch": "default", "author": "contributor", "vcs_type": "mercury" } } ``` ### Debugging Workflow for Open Source **User reports:** "Bug in version 0.1.1+a7f3d2e1" **Any developer can trace:** ```bash # 1. Look up content hash in distributed database grep "a7f3d2e1" .version_history # → a7f3d2e1,abc123f,feature/auth,2025-08-15T11:45:00Z,sandra,git # 2. Find original commit (if using Git) git log --oneline | grep abc123f # → abc123f Implement API authentication # 3. Checkout exact state for debugging git checkout abc123f ``` **Works across VCS migrations:** ```bash # Even if project switched Git → Mercury # .version_history still contains Git mapping grep "a7f3d2e1" .version_history # → Still works! Historical data preserved ``` ### Implementation Priority & Phases **Phase 1: Content-Hash Foundation (Immediate)** - Implement calculate_content_hash.sh - Update version.lua for content-hash detection - Test with current simple VERSION file **Phase 2: VCS-Universal Detection (Week 2)** - Implement vcs_utils.sh - Add .version_history manual tracking - Test across Git/Mercury environments **Phase 3: Automated Hooks (Week 3)** - Implement universal post-commit hooks - Test hook installation across VCS types - Validate automatic mapping generation **Phase 4: Full Integration (Week 4)** - Integration with deployment scripts - API response enhancement with vcs_info - Documentation and contributor onboarding ### Benefits of This Solution 1. **VCS Sovereignty:** Works with Git, Mercury, Bazaar, Fossil, or no VCS 2. **True Code Tracking:** Content-hash reflects actual running code 3. **Open Source Friendly:** Distributed mapping available to all developers 4. **Deployment Agnostic:** Works with git clone, tar.gz, packages 5. **Migration Safe:** VCS changes don't break version tracking 6. **Debug Friendly:** Clear path from runtime version to source code 7. **Future Proof:** Extensible to new VCS systems **Status:** Complete solution designed - ready for phased implementation **Files to create:** - scripts/calculate_content_hash.sh - scripts/vcs_utils.sh - scripts/install_hooks.sh - scripts/universal_post_commit.sh - Update: src/version.lua **Integration points:** - Deployment scripts (walter, aitvaras) - API health endpoint enhancement - Development workflow documentation
michael reopened this issue 2025-08-19 06:07:16 +02:00
Owner

Issue #83 RESOLVED: VERSION → merkwerk Migration Complete

Migration Summary

Successfully migrated furt health endpoint from static VERSION file reading to dynamic merkwerk integration.

Implementation Details

  • Replaced: read_version()get_version_info() with merkwerk API
  • Enhanced Health Endpoint: Now returns rich metadata
  • lua51 Compatible: Works with OpenBSD standard packages
  • Backward Compatible: Maintains version field for existing clients

New Health Endpoint Response

{
  "status": "healthy",
  "service": "furt",
  "version": "0.1.1+7e41647c-dirty",
  "content_hash": "7e41647c-dirty",
  "vcs_info": {
    "type": "git",
    "hash": "7053af3", 
    "branch": "main"
  },
  "source": "merkwerk",
  "features": {
    "merkwerk_integrated": true
  }
}

Benefits Achieved

  • Rich Debugging Data: Content-hash, VCS info, source tracking
  • Automatic Updates: Version reflects real code state
  • OpenBSD Ready: lua51 compatibility confirmed
  • Feature Detection: merkwerk_integrated flag for clients
  • No Disruption: Existing monitoring continues working

Testing Completed

  • lua51 integration tested and working
  • Health endpoint returns complete merkwerk data
  • Startup logs show enhanced version information
  • Cross-project integration validated

Status: Production-ready 🚀

## ✅ **Issue #83 RESOLVED: VERSION → merkwerk Migration Complete** ### **Migration Summary** Successfully migrated furt health endpoint from static VERSION file reading to dynamic merkwerk integration. ### **Implementation Details** - **Replaced:** `read_version()` → `get_version_info()` with merkwerk API - **Enhanced Health Endpoint:** Now returns rich metadata - **lua51 Compatible:** Works with OpenBSD standard packages - **Backward Compatible:** Maintains `version` field for existing clients ### **New Health Endpoint Response** ```json { "status": "healthy", "service": "furt", "version": "0.1.1+7e41647c-dirty", "content_hash": "7e41647c-dirty", "vcs_info": { "type": "git", "hash": "7053af3", "branch": "main" }, "source": "merkwerk", "features": { "merkwerk_integrated": true } } ``` ### **Benefits Achieved** - ✅ **Rich Debugging Data:** Content-hash, VCS info, source tracking - ✅ **Automatic Updates:** Version reflects real code state - ✅ **OpenBSD Ready:** lua51 compatibility confirmed - ✅ **Feature Detection:** `merkwerk_integrated` flag for clients - ✅ **No Disruption:** Existing monitoring continues working ### **Testing Completed** - lua51 integration tested and working - Health endpoint returns complete merkwerk data - Startup logs show enhanced version information - Cross-project integration validated **Status: Production-ready** 🚀
Sign in to join this conversation.
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: DAW/furt#83
No description provided.