ADR-034: Internal Deployment Status Log

Status

Proposed

Date

2025-12-08

Deciders

Context and Problem Statement

Internal team members need visibility into deployment status across client environments. Currently, there's no centralized way to answer:

  1. What version is running on client X's PROD?
  2. Is STAGING being updated right now?
  3. Is the build still running?
  4. What changed since last deployment?

This is for internal CloudEmpiere use only - not customer-facing or compliance audit.

Decision Drivers

Considered Options

  1. Complex tracking system - Separate Build, Deployment, Environment tables with full workflow
  2. Simple status log - Single table with live status updates
  3. Query-only - Just query Jenkins/AWX APIs, no storage

Decision Outcome

Chosen option: "Simple status log", because:

Confirmation

Architecture

┌─────────────────────────────────────────────────────────────────────────────────┐
│                         DEPLOYMENT STATUS FLOW                                   │
└─────────────────────────────────────────────────────────────────────────────────┘

  Developer                Jenkins                  AWX                  iDempiere
  ─────────                ───────                  ───                  ─────────
      │                       │                      │                       │
      │── git push ──────────>│                      │                       │
      │                       │                      │                       │
      │                       │── cli deploy start ──┼──────────────────────>│
      │                       │   (BUILDING)         │                       │
      │                       │                      │                       │
      │                       │── cli deploy update ─┼──────────────────────>│
      │                       │   (progress 50%)     │                       │
      │                       │                      │                       │
      │                       │── build done ───────>│                       │
      │                       │                      │                       │
      │                       │                      │── cli deploy update ─>│
      │                       │                      │   (DEPLOYING)         │
      │                       │                      │                       │
      │                       │                      │── cli deploy complete>│
      │                       │                      │   (SUCCESS)           │
      │                       │                      │                       │
      │                       │                      │           ┌───────────┴───┐
      │                       │                      │           │ Internal user │
      │                       │                      │           │ sees status   │
      │                       │                      │           │ in window     │
      │                       │                      │           └───────────────┘

Database Schema

XX_Deploy_Log (Single Table)

┌─────────────────────────────────────────────────────────────────────────────────┐
│                           XX_Deploy_Log                                          │
│─────────────────────────────────────────────────────────────────────────────────│
│ Column           │ Type         │ Description                                   │
│──────────────────┼──────────────┼───────────────────────────────────────────────│
│ XX_Deploy_Log_ID │ ID           │ Primary key                                   │
│ XX_Deploy_Log_UU │ UUID         │ REST API identifier                           │
│ AD_Client_ID     │ TableDirect  │ Which client (multi-tenant)                   │
│ AD_Org_ID        │ TableDirect  │ Organization                                  │
│──────────────────┼──────────────┼───────────────────────────────────────────────│
│ Environment      │ List         │ PROD / STAGING / DEV                          │
│ Status           │ List         │ BUILDING / DEPLOYING / SUCCESS / FAILED       │
│ Progress         │ Integer      │ 0-100 percentage                              │
│ CurrentStep      │ String(255)  │ "Compiling..." / "Restarting..."              │
│──────────────────┼──────────────┼───────────────────────────────────────────────│
│ Version          │ String(40)   │ Target version (2.1.0)                        │
│ VersionPrevious  │ String(40)   │ Previous version (2.0.5)                      │
│ Components       │ Text         │ What's being updated (plugin list)            │
│ Changes          │ Text         │ What changed (summary)                        │
│──────────────────┼──────────────┼───────────────────────────────────────────────│
│ DateStarted      │ DateTime     │ When build/deploy started                     │
│ DateCompleted    │ DateTime     │ When finished (null if in progress)           │
│ Duration         │ Integer      │ Seconds (calculated on complete)              │
│ ErrorMessage     │ Text         │ Error details if failed                       │
│──────────────────┼──────────────┼───────────────────────────────────────────────│
│ Jenkins_BuildNo  │ String(50)   │ Jenkins build number                          │
│ Jenkins_URL      │ URL          │ Link to Jenkins job                           │
│ AWX_JobID        │ String(50)   │ AWX job ID                                    │
│ AWX_URL          │ URL          │ Link to AWX job                               │
│ DeployedBy       │ String(100)  │ Who triggered (username)                      │
│──────────────────┼──────────────┼───────────────────────────────────────────────│
│ IsActive         │ YesNo        │ Standard                                      │
│ Created          │ DateTime     │ Audit                                         │
│ CreatedBy        │ Table        │ Audit                                         │
│ Updated          │ DateTime     │ Audit                                         │
│ UpdatedBy        │ Table        │ Audit                                         │
└─────────────────────────────────────────────────────────────────────────────────┘

Reference Lists

XX_DeployEnvironment:

Value Name
PROD Production
STAGING Staging
DEV Development

XX_DeployStatus:

Value Name Description
B Building Jenkins is building artifacts
D Deploying AWX is deploying to server
S Success Completed successfully
F Failed Something went wrong
R Rolled Back Reverted to previous version

Status Lifecycle

    BUILDING ──────────► DEPLOYING ──────────► SUCCESS
        │                    │
        │                    │
        ▼                    ▼
      FAILED               FAILED
                             │
                             ▼
                        ROLLED_BACK

CLI Commands

# ─────────────────────────────────────────────────────────────────────────────────
# START: Create new deployment record (Jenkins calls at build start)
# ─────────────────────────────────────────────────────────────────────────────────

idempiere-cli env deploy start \
    --env STAGING \
    --version "2.2.0" \
    --components "org.idempiere.invoice, org.idempiere.report" \
    --jenkins-build "567" \
    --jenkins-url "https://jenkins.example.com/job/plugins/567"

# Returns: XX_Deploy_Log_ID for subsequent updates


# ─────────────────────────────────────────────────────────────────────────────────
# UPDATE: Update progress during build/deploy (Jenkins/AWX call periodically)
# ─────────────────────────────────────────────────────────────────────────────────

idempiere-cli env deploy update \
    --id 1000042 \
    --progress 50 \
    --step "Running tests..."

idempiere-cli env deploy update \
    --id 1000042 \
    --status DEPLOYING \
    --progress 0 \
    --step "Copying artifacts to server..."

idempiere-cli env deploy update \
    --id 1000042 \
    --progress 75 \
    --step "Restarting iDempiere service..."


# ─────────────────────────────────────────────────────────────────────────────────
# COMPLETE: Mark deployment finished (AWX calls at end)
# ─────────────────────────────────────────────────────────────────────────────────

# Success
idempiere-cli env deploy complete \
    --id 1000042 \
    --status SUCCESS \
    --changes "Invoice tax fix, new Sales by Region report"

# Failed
idempiere-cli env deploy complete \
    --id 1000042 \
    --status FAILED \
    --error "Database migration failed: column already exists"


# ─────────────────────────────────────────────────────────────────────────────────
# QUERY: View status and history
# ─────────────────────────────────────────────────────────────────────────────────

# Current status per environment
idempiere-cli env deploy status
idempiere-cli env deploy status PROD
idempiere-cli env deploy status --client 1000014

# History
idempiere-cli env deploy history
idempiere-cli env deploy history --env PROD --since "2024-12-01"
idempiere-cli env deploy history --status FAILED

CLI Output Examples

Status View

$ idempiere-cli env deploy status

Client: Acme Corp (1000014)

┌───────────┬──────────┬──────────┬─────────────────────┬────────────────────────┐
│ Env       │ Version  │ Status   │ Progress            │ Current Step           │
├───────────┼──────────┼──────────┼─────────────────────┼────────────────────────┤
│ PROD      │ 2.1.0    │ ✅ OK    │ ████████████ 100%   │ Deployed Dec 8, 10:30  │
│ STAGING   │ 2.2.0    │ 🔄 DEPLOY│ ██████░░░░░░  50%   │ Restarting service...  │
│ DEV       │ 2.2.1    │ 🔨 BUILD │ ████░░░░░░░░  30%   │ Running tests...       │
└───────────┴──────────┴──────────┴─────────────────────┴────────────────────────┘

History View

$ idempiere-cli env deploy history --env PROD --limit 5

┌─────────────────────┬──────────┬──────────┬────────────────────────────────────┐
│ Date                │ Version  │ Status   │ Changes                            │
├─────────────────────┼──────────┼──────────┼────────────────────────────────────┤
│ 2024-12-08 10:30    │ 2.1.0    │ ✅ OK    │ Invoice tax fix                    │
│ 2024-12-05 14:00    │ 2.0.5    │ ✅ OK    │ Hotfix for report                  │
│ 2024-12-01 09:00    │ 2.0.4    │ ❌ FAIL  │ Migration failed (rolled back)     │
│ 2024-11-28 16:00    │ 2.0.4    │ ✅ OK    │ New dashboard feature              │
│ 2024-11-25 11:00    │ 2.0.3    │ ✅ OK    │ Performance improvements           │
└─────────────────────┴──────────┴──────────┴────────────────────────────────────┘

iDempiere Window

┌─────────────────────────────────────────────────────────────────────────────────┐
│  Window: Deployment Status                                              [?] [X] │
│─────────────────────────────────────────────────────────────────────────────────│
│                                                                                  │
│  [Tab: Current Status] [Tab: History]                                           │
│                                                                                  │
│  ┌─ Current Status ────────────────────────────────────────────────────────────┐│
│  │                                                                             ││
│  │  Environment: [STAGING ▼]     Status: 🔄 Deploying                         ││
│  │  Version:     2.2.0           Progress: [██████░░░░░░] 50%                 ││
│  │  Current Step: Restarting iDempiere service...                             ││
│  │                                                                             ││
│  │  Started:     2024-12-08 14:30                                             ││
│  │  Jenkins:     #567 (link)                                                  ││
│  │  AWX Job:     #1234 (link)                                                 ││
│  │  Triggered By: john.doe                                                    ││
│  │                                                                             ││
│  │  Components:                                                               ││
│  │  • org.idempiere.invoice (2.0.5 → 2.1.0)                                  ││
│  │  • org.idempiere.report (1.4.2 → 1.5.0)                                   ││
│  │                                                                             ││
│  └─────────────────────────────────────────────────────────────────────────────┘│
│                                                                                  │
│  [Refresh]                                                                      │
│                                                                                  │
└─────────────────────────────────────────────────────────────────────────────────┘

Integration Examples

Jenkins Pipeline

pipeline {
    stages {
        stage('Build') {
            steps {
                script {
                    // Start tracking
                    def deployId = sh(
                        script: '''
                            idempiere-cli env deploy start \
                                --env STAGING \
                                --version "${VERSION}" \
                                --jenkins-build "${BUILD_NUMBER}" \
                                --jenkins-url "${BUILD_URL}" \
                                --json | jq -r '.id'
                        ''',
                        returnStdout: true
                    ).trim()
                    env.DEPLOY_ID = deployId
                }

                // Build steps with progress updates
                sh "idempiere-cli env deploy update --id ${DEPLOY_ID} --progress 25 --step 'Compiling...'"
                sh "mvn compile"

                sh "idempiere-cli env deploy update --id ${DEPLOY_ID} --progress 50 --step 'Running tests...'"
                sh "mvn test"

                sh "idempiere-cli env deploy update --id ${DEPLOY_ID} --progress 75 --step 'Packaging...'"
                sh "mvn package"

                sh "idempiere-cli env deploy update --id ${DEPLOY_ID} --progress 100 --step 'Build complete'"
            }
        }
    }
    post {
        failure {
            sh '''
                idempiere-cli env deploy complete \
                    --id ${DEPLOY_ID} \
                    --status FAILED \
                    --error "Build failed: ${BUILD_URL}console"
            '''
        }
    }
}

AWX/Ansible Playbook

# deploy-plugins.yml

- name: Update status - Deploying
  command: >
    idempiere-cli env deploy update
    --id {{ deploy_id }}
    --status DEPLOYING
    --progress 0
    --step "Starting deployment..."
  delegate_to: localhost

- name: Copy plugins to server
  copy:
    src: "{{ item }}"
    dest: /opt/idempiere/plugins/
  loop: "{{ plugin_files }}"

- name: Update progress
  command: >
    idempiere-cli env deploy update
    --id {{ deploy_id }}
    --progress 50
    --step "Restarting iDempiere..."
  delegate_to: localhost

- name: Restart iDempiere
  service:
    name: idempiere
    state: restarted

- name: Complete deployment
  command: >
    idempiere-cli env deploy complete
    --id {{ deploy_id }}
    --status SUCCESS
    --changes "{{ release_notes }}"
  delegate_to: localhost

REST API

Uses iDempiere REST Web Services:

# Create deployment record
POST /api/v1/models/xx_deploy_log
{
  "Environment": "STAGING",
  "Status": "B",
  "Version": "2.2.0",
  "DateStarted": "2024-12-08T14:30:00Z"
}

# Update progress
PATCH /api/v1/models/xx_deploy_log/1000042
{
  "Progress": 50,
  "CurrentStep": "Running tests..."
}

# Query current status
GET /api/v1/models/xx_deploy_log?$filter=DateCompleted eq null&$orderby=DateStarted desc

What This Is NOT

What This IS

References

Path: /docs/developers/architecture/idempiere-hub/034-deployment-history-tracking