DevOps en IBM i

CI/CD, control de versiones con Git, el build tool Bob, VS Code con Code for i, testing automatizado, estrategias de deploy y el camino hacia una cultura DevOps moderna en el ecosistema IBM i.

DevOps en el mundo IBM i

DevOps en IBM i significa aplicar las mismas practicas que las organizaciones modernas usan en otras plataformas: control de versiones, builds automatizados, testing continuo y despliegues repetibles. El desafio es adaptar estas practicas a un ecosistema que historicamente ha dependido de PDM/SEU, source physical files y compilaciones manuales.

Flujo tradicional IBM i

  • Editar con SEU/PDM en pantalla verde
  • Source en QSYS (source physical files)
  • Compilacion manual con CRTBNDRPG
  • Sin control de versiones formal
  • Deploy: copiar objetos entre bibliotecas
  • Testing manual en pantalla 5250
  • Un desarrollador trabaja en un miembro a la vez

Flujo DevOps moderno en IBM i

  • Editar con VS Code + Code for i
  • Source en IFS gestionado con Git
  • Build automatizado con Bob/makefile
  • Git con branches, PRs y code review
  • Deploy: pipeline CI/CD automatizado
  • Testing automatizado con RPGUnit
  • Multiples desarrolladores en paralelo con branches

Plan

Issues en GitHub/GitLab, historias de usuario, sprints con herramientas agiles.

Code

VS Code + Code for i, Git branches, pull requests y code review.

Build & Test

Bob compila, RPGUnit ejecuta tests, pipeline valida calidad.

Deploy

Pipeline mueve objetos a QA/Prod. Rollback automatico si falla.

VS Code + Code for i

Code for IBM i es una extension de VS Code que reemplaza a PDM/SEU como entorno de desarrollo principal. Permite editar fuentes en IFS o en source physical files, compilar, depurar y navegar objetos IBM i directamente desde VS Code, con syntax highlighting, autocompletado y terminal integrada.

Instalacion

  • 1. Instalar VS Code en tu PC/Mac
  • 2. Buscar "Code for IBM i" en Extensions
  • 3. Instalar la extension (autor: Hal Dean)
  • 4. Agregar conexion al IBM i (hostname + usuario)
  • 5. Conectar via SSH (requiere SSHD activo)

Extensiones complementarias

  • RPGLE -- Syntax highlighting para RPG IV
  • CL -- Syntax highlighting para CL
  • DB2 for i -- Ejecutar SQL desde VS Code
  • IBM i Notebooks -- Notebooks interactivos
  • GitLens -- Historial Git integrado
VS Code -- Acciones disponibles con Code for i
// Desde la paleta de comandos (Ctrl+Shift+P):

IBM i: Connect to IBM i          // Conectar al sistema
IBM i: Run Action on Active File  // Compilar el archivo actual
IBM i: Create New Source Member    // Crear miembro en SPF
IBM i: Browse Object Browser       // Navegar bibliotecas/objetos
IBM i: Open Terminal               // Abrir terminal PASE SSH

// Actions personalizables (compilar desde IFS):
// Se configuran en .vscode/actions.json

// Shortcut para compilar: Ctrl+E (configurable)
// Errores aparecen en la pestana "Problems" de VS Code
.vscode/actions.json -- Acciones de compilacion personalizadas
[
  {
    "name": "Compilar RPG (CRTBNDRPG desde IFS)",
    "command": "CRTBNDRPG PGM(&CURLIB/&NAME) SRCSTMF('&FULLPATH') DBGVIEW(*SOURCE) OPTION(*SRCSTMT *NODEBUGIO)",
    "extensions": ["rpgle", "sqlrpgle"],
    "environment": "ile",
    "deployFirst": true
  },
  {
    "name": "Compilar CL (CRTBNDCL desde IFS)",
    "command": "CRTBNDCL PGM(&CURLIB/&NAME) SRCSTMF('&FULLPATH') DBGVIEW(*SOURCE)",
    "extensions": ["clle", "clp"],
    "environment": "ile",
    "deployFirst": true
  },
  {
    "name": "Compilar Display File",
    "command": "CRTDSPF FILE(&CURLIB/&NAME) SRCSTMF('&FULLPATH')",
    "extensions": ["dspf"],
    "environment": "ile",
    "deployFirst": true
  },
  {
    "name": "Compilar SQL Table",
    "command": "RUNSQLSTM SRCSTMF('&FULLPATH') COMMIT(*NONE) NAMING(*SQL)",
    "extensions": ["sql", "table", "view"],
    "environment": "ile",
    "deployFirst": true
  }
]
Deploy First: Cuando deployFirst: true esta activo, Code for i automaticamente copia el archivo local al IFS del IBM i antes de compilar. Esto permite trabajar con archivos locales (en tu PC) que se sincronizan al compilar.

Bob: Better Object Builder

Bob (Better Object Builder) es una herramienta open source de build para IBM i que funciona como un "make" especializado. Lee archivos de configuracion que definen como compilar cada fuente y ejecuta las compilaciones respetando dependencias. Es la pieza clave para automatizar builds en pipelines CI/CD.

Shell -- Instalar Bob
// Bob se instala via yum en PASE
$ yum install bob

// Verificar instalacion
$ makei --version
Bob (Better Object Builder) v2.4.2

// Bob se ejecuta con el comando 'makei'
// desde el directorio raiz del proyecto
$ cd /home/MIUSER/repos/mi-proyecto
$ makei build
iproj.json -- Configuracion del proyecto IBM i
{
  "version": "0.0.1",
  "description": "Sistema de Gestion de Clientes",
  "objlib": "MILIB",
  "curlib": "MILIB",
  "includePath": [
    "/QSYS.LIB/MILIB.LIB/QRPGLESRC.FILE",
    "/home/MIUSER/repos/mi-proyecto/headers"
  ],
  "preUsrlibl": ["MILIB", "UTILLIB"],
  "postUsrlibl": ["QTEMP"],
  "setIBMiEnvCmd": [],
  "repository": "https://github.com/empresa/mi-proyecto",
  "license": "MIT"
}
Rules.mk -- Reglas de compilacion Bob
# Rules.mk - Reglas de compilacion para Bob
# Este archivo define COMO compilar cada tipo de fuente

# Variables globales
OBJLIB := MILIB
TGTCCSID := *JOB

# Regla para programas RPG (*.rpgle)
%.rpgle:
	system -q "CRTBNDRPG PGM($(OBJLIB)/$*) 		SRCSTMF('$<') 		DBGVIEW(*SOURCE) 		OPTION(*SRCSTMT *NODEBUGIO) 		TGTRLS(*CURRENT)"

# Regla para programas SQL RPG (*.sqlrpgle)
%.sqlrpgle:
	system -q "CRTSQLRPGI OBJ($(OBJLIB)/$*) 		SRCSTMF('$<') 		DBGVIEW(*SOURCE) 		OPTION(*SRCSTMT) 		COMMIT(*NONE)"

# Regla para programas CL (*.clle)
%.clle:
	system -q "CRTBNDCL PGM($(OBJLIB)/$*) 		SRCSTMF('$<') 		DBGVIEW(*SOURCE)"

# Regla para display files (*.dspf)
%.dspf:
	system -q "CRTDSPF FILE($(OBJLIB)/$*) 		SRCSTMF('$<')"

# Regla para tablas SQL (*.sql)
%.sql:
	system -q "RUNSQLSTM SRCSTMF('$<') 		COMMIT(*NONE) NAMING(*SQL)"

# Regla para service programs
%.rpgle.srvpgm:
	system -q "CRTRPGMOD MODULE($(OBJLIB)/$*) 		SRCSTMF('$<') 		DBGVIEW(*SOURCE)"
	system -q "CRTSRVPGM SRVPGM($(OBJLIB)/$*) 		MODULE($(OBJLIB)/$*) 		EXPORT(*ALL)"
Shell -- Ejecutar build con Bob
// Build completo del proyecto
$ cd /home/MIUSER/repos/mi-proyecto
$ makei build
Building GESTCLI.rpgle -> MILIB/GESTCLI *PGM ... OK
Building VALCLI.rpgle  -> MILIB/VALCLI  *PGM ... OK
Building CLIENTES.sql  -> MILIB/CLIENTES *FILE ... OK
Building MENU.dspf     -> MILIB/MENU *FILE ... OK
Build complete: 4 objects, 0 errors

// Build de un objeto especifico
$ makei build GESTCLI.rpgle

// Build con logging detallado
$ makei build -v

// Limpiar objetos compilados
$ makei clean

// Ver que se compilaria sin ejecutar
$ makei build --dry-run
Ventaja de Bob: Bob detecta automaticamente que archivos cambiaron desde el ultimo build (usando timestamps o integracion con Git) y solo recompila lo necesario. Esto reduce drasticamente el tiempo de build en proyectos grandes.

Git workflows para IBM i

Adoptar Git para IBM i requiere definir un flujo de trabajo (workflow) que se adapte a las particularidades de la plataforma: bibliotecas por desarrollador, compilacion en el sistema destino y promover objetos entre entornos.

Git Flow adaptado a IBM i
main (produccion)
  |
  +-- develop (integracion / QA)
       |
       +-- feature/nueva-validacion    (dev: DEVLIB01)
       +-- feature/reporte-ventas      (dev: DEVLIB02)
       +-- bugfix/calculo-iva          (dev: DEVLIB03)

Flujo:
1. Developer crea branch desde 'develop'
2. Trabaja en VS Code, compila en su biblioteca DEVLIB##
3. Hace commits y push al branch
4. Crea Pull Request hacia 'develop'
5. Code review por otro developer
6. Merge a 'develop' -> CI/CD compila en QALIB (QA)
7. QA aprueba -> merge a 'main'
8. CI/CD compila en PRODLIB (produccion)
BranchBiblioteca IBM iPropositoQuien compila
feature/*DEVLIB01-09Desarrollo individualDeveloper manual
developQALIBIntegracion y QAPipeline CI/CD
release/*STGLIBPre-produccion / stagingPipeline CI/CD
mainPRODLIBProduccionPipeline CI/CD
hotfix/*HFXLIBFix urgente en produccionPipeline CI/CD
Shell -- Flujo diario de un developer
// 1. Actualizar develop local
$ cd /home/MIUSER/repos/mi-proyecto
$ git checkout develop
$ git pull origin develop

// 2. Crear branch de feature
$ git checkout -b feature/validacion-email

// 3. Editar en VS Code (los archivos estan en IFS)
//    ... modificar qrpglesrc/gestcli.rpgle ...

// 4. Compilar y probar (en biblioteca de desarrollo)
$ makei build GESTCLI.rpgle
// O desde VS Code: Ctrl+E -> Compilar RPG

// 5. Commit y push
$ git add qrpglesrc/gestcli.rpgle
$ git commit -m "feat(gestcli): agregar validacion de email"
$ git push origin feature/validacion-email

// 6. Crear Pull Request en GitHub/GitLab
//    (desde la interfaz web o CLI)
$ gh pr create --base develop   --title "feat: validacion de email en GESTCLI"   --body "Agrega validacion de formato de email..."

// 7. Despues del code review, merge a develop
$ gh pr merge --squash

CI/CD pipelines

Un pipeline CI/CD para IBM i automatiza la secuencia: checkout del codigo, copia al IFS, compilacion con Bob, ejecucion de tests y deploy a la biblioteca destino. Se puede implementar con GitHub Actions, GitLab CI, Jenkins o Azure DevOps, conectandose al IBM i via SSH.

.github/workflows/build.yml -- GitHub Actions para IBM i
name: IBM i Build & Deploy
on:
  push:
    branches: [develop, main]
  pull_request:
    branches: [develop]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout codigo
        uses: actions/checkout@v4

      - name: Copiar fuentes al IBM i via SSH
        uses: appleboy/scp-action@v0.1.7
        with:
          host: ${{ secrets.IBMI_HOST }}
          username: ${{ secrets.IBMI_USER }}
          key: ${{ secrets.IBMI_SSH_KEY }}
          source: "qrpglesrc/,qclsrc/,qddssrc/,qsqlsrc/"
          target: "/home/cicd/builds/${{ github.sha }}"

      - name: Build con Bob
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.IBMI_HOST }}
          username: ${{ secrets.IBMI_USER }}
          key: ${{ secrets.IBMI_SSH_KEY }}
          script: |
            cd /home/cicd/builds/${{ github.sha }}
            export PATH=/QOpenSys/pkgs/bin:$PATH
            makei build 2>&1
            if [ $? -ne 0 ]; then
              echo "BUILD FAILED"
              exit 1
            fi

      - name: Ejecutar tests RPGUnit
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.IBMI_HOST }}
          username: ${{ secrets.IBMI_USER }}
          key: ${{ secrets.IBMI_SSH_KEY }}
          script: |
            export PATH=/QOpenSys/pkgs/bin:$PATH
            system "RUCALLTST TSTPRC(QALIB/TESTGESTCLI)"
            system "RUCALLTST TSTPRC(QALIB/TESTVALCLI)"

  deploy-qa:
    needs: build
    if: github.ref == 'refs/heads/develop'
    runs-on: ubuntu-latest
    steps:
      - name: Deploy a QA
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.IBMI_HOST }}
          username: ${{ secrets.IBMI_USER }}
          key: ${{ secrets.IBMI_SSH_KEY }}
          script: |
            export PATH=/QOpenSys/pkgs/bin:$PATH
            # Copiar objetos de DEVLIB a QALIB
            system "CRTDUPOBJ OBJ(GESTCLI) FROMLIB(DEVLIB)               OBJTYPE(*PGM) TOLIB(QALIB) NEWOBJ(*SAME)               DATA(*YES)"

  deploy-prod:
    needs: build
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production
    steps:
      - name: Deploy a Produccion
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.IBMI_HOST }}
          username: ${{ secrets.IBMI_USER }}
          key: ${{ secrets.IBMI_SSH_KEY }}
          script: |
            export PATH=/QOpenSys/pkgs/bin:$PATH
            # Backup antes de deploy
            system "SAVOBJ OBJ(GESTCLI) LIB(PRODLIB)               DEV(*SAVF) SAVF(PRODLIB/BKP$(date +%Y%m%d))"
            # Deploy
            system "CRTDUPOBJ OBJ(GESTCLI) FROMLIB(QALIB)               OBJTYPE(*PGM) TOLIB(PRODLIB) NEWOBJ(*SAME)               DATA(*YES)"
Jenkinsfile -- Pipeline Jenkins alternativo
pipeline {
    agent any

    environment {
        IBMI_HOST = credentials('ibmi-host')
        IBMI_CREDS = credentials('ibmi-ssh-key')
    }

    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Sync to IBM i') {
            steps {
                sh """
                    rsync -avz --delete \
                      -e "ssh -i ${IBMI_CREDS}" \
                      ./qrpglesrc/ ./qclsrc/ ./qddssrc/ \
                      ${IBMI_HOST}:/home/cicd/builds/${BUILD_NUMBER}/
                """
            }
        }

        stage('Build') {
            steps {
                sh """
                    ssh -i ${IBMI_CREDS} ${IBMI_HOST} \
                      "cd /home/cicd/builds/${BUILD_NUMBER} && makei build"
                """
            }
        }

        stage('Test') {
            steps {
                sh """
                    ssh -i ${IBMI_CREDS} ${IBMI_HOST} \
                      "system 'RUCALLTST TSTPRC(QALIB/TESTALL)'"
                """
            }
        }

        stage('Deploy QA') {
            when { branch 'develop' }
            steps {
                sh """
                    ssh -i ${IBMI_CREDS} ${IBMI_HOST} \
                      "/home/cicd/scripts/deploy.sh QALIB"
                """
            }
        }
    }
}
Secretos: Nunca guardar credenciales en el repositorio. Usar los mecanismos de secrets de cada plataforma: GitHub Secrets, Jenkins Credentials, GitLab CI Variables. La conexion SSH con clave publica es el metodo mas seguro.

Testing y calidad

RPGUnit es el framework de testing unitario mas utilizado para RPG. Permite escribir tests automatizados para procedimientos y programas, ejecutarlos desde linea de comandos y generar reportes de resultados para integracion con pipelines CI/CD.

TESTGESTCLI.RPGLE -- Tests unitarios con RPGUnit
**free
// ---------------------------------------------------------------
// TESTGESTCLI: Tests unitarios para el modulo GESTCLI
// Framework: RPGUnit v3+
// ---------------------------------------------------------------
ctl-opt dftactgrp(*no) actgrp(*caller);
ctl-opt bnddir('RPGUNIT');

/include RPGUNIT/QRPGLESRC,TESTCASE

// Prototipo del programa a testear
dcl-pr altaCliente char(1);
  id      packed(7:0) const;
  nombre  varchar(100) const;
  email   varchar(200) const;
end-pr;

dcl-pr consCliente char(1);
  id      packed(7:0) const;
  nombre  varchar(100);
  email   varchar(200);
end-pr;

// ---------------------------------------------------------------
// Test: Alta de cliente exitosa
// ---------------------------------------------------------------
dcl-proc test_altaCliente_exitosa export;
  dcl-s resultado char(1);

  resultado = altaCliente(99999 : 'Test User' : 'test@test.com');

  aEqual('S' : resultado : 'Alta deberia retornar S');
end-proc;

// ---------------------------------------------------------------
// Test: Consulta de cliente existente
// ---------------------------------------------------------------
dcl-proc test_consultaCliente_existe export;
  dcl-s resultado char(1);
  dcl-s nombre varchar(100);
  dcl-s email varchar(200);

  // Primero crear el cliente de prueba
  altaCliente(99998 : 'Consulta Test' : 'consulta@test.com');

  // Consultar
  resultado = consCliente(99998 : nombre : email);

  aEqual('S' : resultado : 'Consulta deberia retornar S');
  aEqual('Consulta Test' : %trim(nombre) : 'Nombre incorrecto');
  aEqual('consulta@test.com' : %trim(email) : 'Email incorrecto');
end-proc;

// ---------------------------------------------------------------
// Test: Consulta de cliente inexistente
// ---------------------------------------------------------------
dcl-proc test_consultaCliente_noExiste export;
  dcl-s resultado char(1);
  dcl-s nombre varchar(100);
  dcl-s email varchar(200);

  resultado = consCliente(00001 : nombre : email);

  aEqual('N' : resultado : 'Consulta no existente debe dar N');
end-proc;

// ---------------------------------------------------------------
// Cleanup: eliminar datos de prueba
// ---------------------------------------------------------------
dcl-proc tearDown export;
  exec sql DELETE FROM MILIB.CLIENTES
            WHERE CLI_ID IN (99999, 99998);
end-proc;
CL -- Ejecutar tests RPGUnit
// Compilar el test
CRTBNDRPG PGM(QALIB/TESTGESTCLI)
          SRCSTMF('/home/dev/repos/tests/testgestcli.rpgle')
          BNDDIR(RPGUNIT)
          DBGVIEW(*SOURCE)

// Ejecutar todos los tests de un programa
RUCALLTST TSTPRC(QALIB/TESTGESTCLI)

// Ejecutar un test especifico
RUCALLTST TSTPRC(QALIB/TESTGESTCLI)
          TSTPRC(test_altaCliente_exitosa)

// Ver resultados en formato texto
RUCALLTST TSTPRC(QALIB/TESTGESTCLI) OUTPUT(*PRINT)

// Ejecutar todos los tests del proyecto
RUCALLTST TSTPRC(QALIB/TESTGESTCLI)
RUCALLTST TSTPRC(QALIB/TESTVALCLI)
RUCALLTST TSTPRC(QALIB/TESTREPORTES)
aEqual

Verifica que dos valores alfanumericos son iguales

iEqual

Verifica que dos valores enteros son iguales

nEqual

Verifica que dos valores numericos (packed/zoned) son iguales

assert

Verifica que una condicion booleana es verdadera

fail

Fuerza la falla del test con un mensaje personalizado

assertJobLogContains

Verifica que el job log contiene un mensaje

Estrategias de deploy

El despliegue en IBM i tipicamente involucra mover objetos compilados entre bibliotecas (DEV, QA, PROD). Un buen pipeline automatiza este proceso y agrega validaciones, backups y la posibilidad de rollback.

deploy.sh -- Script de deploy automatizado
#!/QOpenSys/pkgs/bin/bash
# deploy.sh - Script de deploy para pipeline CI/CD
# Uso: ./deploy.sh FROMLIB TOLIB [objetos...]

FROMLIB=$1
TOLIB=$2
shift 2
OBJETOS=("$@")

FECHA=$(date +%Y%m%d_%H%M%S)
LOGFILE="/home/cicd/logs/deploy_${FECHA}.log"
SAVF="${TOLIB}/BKP${FECHA}"

echo "=== Deploy: ${FROMLIB} -> ${TOLIB} ===" | tee $LOGFILE
echo "Fecha: ${FECHA}" | tee -a $LOGFILE

# 1. Crear save file de backup
system "CRTSAVF FILE(${SAVF})" 2>/dev/null

# 2. Backup de objetos existentes en destino
for OBJ in "${OBJETOS[@]}"; do
  OBJ_NAME=$(echo $OBJ | cut -d. -f1)
  OBJ_TYPE=$(echo $OBJ | cut -d. -f2)

  echo "Backup: ${TOLIB}/${OBJ_NAME} *${OBJ_TYPE}" | tee -a $LOGFILE
  system "SAVOBJ OBJ(${OBJ_NAME}) LIB(${TOLIB}) \
    DEV(*SAVF) SAVF(${SAVF}) \
    OBJTYPE(*${OBJ_TYPE})" 2>&1 | tee -a $LOGFILE
done

# 3. Copiar objetos nuevos al destino
for OBJ in "${OBJETOS[@]}"; do
  OBJ_NAME=$(echo $OBJ | cut -d. -f1)
  OBJ_TYPE=$(echo $OBJ | cut -d. -f2)

  echo "Deploy: ${OBJ_NAME} *${OBJ_TYPE}" | tee -a $LOGFILE
  system "CRTDUPOBJ OBJ(${OBJ_NAME}) FROMLIB(${FROMLIB}) \
    OBJTYPE(*${OBJ_TYPE}) TOLIB(${TOLIB}) \
    NEWOBJ(*SAME) DATA(*YES)" 2>&1 | tee -a $LOGFILE

  if [ $? -ne 0 ]; then
    echo "ERROR en deploy de ${OBJ_NAME}" | tee -a $LOGFILE
    echo "Iniciando rollback..." | tee -a $LOGFILE
    # Rollback desde backup
    system "RSTOBJ OBJ(*ALL) SAVLIB(${TOLIB}) \
      DEV(*SAVF) SAVF(${SAVF})" 2>&1 | tee -a $LOGFILE
    exit 1
  fi
done

echo "=== Deploy completado exitosamente ===" | tee -a $LOGFILE
EntornoBibliotecaTrigger de deploy
DesarrolloDEVLIB01-09Manual (cada developer compila en su lib)
IntegracionINTLIBMerge a develop (pipeline automatico)
QA / TestQALIBPipeline CI/CD tras build exitoso
StagingSTGLIBRelease branch o tag
ProduccionPRODLIBMerge a main (con aprobacion)

iProjects y estructura

Un iProject es la forma estandar de organizar fuentes IBM i en el IFS para que herramientas como Bob, Code for i y pipelines CI/CD puedan trabajar de forma consistente. La estructura sigue convenciones que mapean directorios a tipos de fuente IBM i.

Estructura recomendada de iProject
mi-proyecto/
|-- iproj.json              # Configuracion del proyecto
|-- Rules.mk                # Reglas de compilacion Bob
|-- .gitignore              # Archivos a ignorar en Git
|-- .vscode/
|   |-- actions.json        # Acciones de compilacion VS Code
|   +-- settings.json       # Config Code for i
|-- qrpglesrc/              # Fuentes RPG IV
|   |-- gestcli.rpgle
|   |-- valcli.rpgle
|   +-- utillib.rpgle
|-- qsqlrpgle/              # Fuentes SQL RPG
|   +-- rptventas.sqlrpgle
|-- qclsrc/                 # Fuentes CL
|   |-- strsys.clle
|   +-- bkplib.clle
|-- qddssrc/                # Display files y printer files
|   |-- menuppal.dspf
|   +-- rptcli.prtf
|-- qsqlsrc/                # Scripts SQL (DDL)
|   |-- clientes.sql
|   +-- pedidos.sql
|-- qcmdsrc/                # Definiciones de comandos
|   +-- gestcli.cmd
|-- qsrvsrc/                # Binder source (service programs)
|   +-- utillib.bnd
|-- headers/                # Copy files / includes
|   |-- constantes.rpgleinc
|   +-- prototipos.rpgleinc
|-- tests/                  # Tests RPGUnit
|   |-- testgestcli.rpgle
|   +-- testvalcli.rpgle
|-- scripts/                # Scripts de automatizacion
|   |-- deploy.sh
|   +-- setup-devlib.sh
+-- docs/                   # Documentacion del proyecto
    +-- api.md
.gitignore -- Archivos a excluir del repositorio
# Objetos compilados (no se versionan)
*.pgm
*.srvpgm
*.module
*.bnddir

# Logs y temporales
*.log
*.tmp
*.joblog

# Archivos de save
*.savf

# Directorios de IDE
.theia/
.che/

# Credenciales (nunca subir)
.env
credentials.json
*.pem

# OS files
.DS_Store
Thumbs.db

Herramientas complementarias

Arcad iNside

Suite completa de ALM (Application Lifecycle Management) para IBM i. Incluye source control, analisis de impacto, deployment automatizado y audit trail.

Remain API Studio

Herramienta visual para crear APIs REST desde programas RPG. Genera documentacion OpenAPI y maneja autenticacion sin codigo.

MDCMS

Change Management System open source para IBM i. Maneja promocion de objetos entre entornos con historial y aprobaciones.

RDi (Rational Developer for i)

IDE basado en Eclipse de IBM. Alternativa a VS Code con debugger integrado, profiler y analisis estatico de codigo RPG.

SonarQube + RPG plugin

Analisis estatico de codigo RPG. Detecta code smells, complejidad ciclomatica, codigo muerto y vulnerabilidades.

Eradani Connect

Middleware que expone programas RPG como APIs REST, microservicios y conectores. Alternativa comercial a IWS.

Roadmap de adopcion

La adopcion de DevOps en IBM i es un proceso gradual. No es necesario (ni recomendable) implementar todo de una vez. Este roadmap sugiere un orden incremental basado en la experiencia de la comunidad.

Fase 1: Fundamentos (semanas 1-4)

  • 1.Instalar open source (yum) y configurar SSH
  • 2.Instalar VS Code + Code for i en cada developer
  • 3.Migrar fuentes de SPF a IFS manteniendo copia en QSYS
  • 4.Inicializar repositorio Git con estructura iProject
  • 5.Capacitar al equipo en Git basico (clone, commit, push, pull)

Fase 2: Versionado (semanas 5-8)

  • 1.Definir Git workflow (feature branches + develop + main)
  • 2.Establecer convencion de commit messages
  • 3.Configurar pull requests y code review
  • 4.Migrar desarrollo activo a VS Code + Git como primario
  • 5.Instalar Bob y crear Rules.mk para el proyecto

Fase 3: Automatizacion (semanas 9-12)

  • 1.Crear pipeline CI basico (build automatico en push)
  • 2.Escribir primeros tests RPGUnit para modulos criticos
  • 3.Integrar tests en el pipeline CI
  • 4.Automatizar deploy a QA tras merge a develop
  • 5.Documentar proceso y crear runbooks

Fase 4: Madurez (mes 4+)

  • 1.Agregar analisis estatico (SonarQube o similar)
  • 2.Implementar deploy automatico a produccion con approval gate
  • 3.Metricas: lead time, deployment frequency, MTTR
  • 4.Expandir cobertura de tests unitarios
  • 5.Explorar feature flags y canary deployments
Clave del exito: El mayor desafio de DevOps en IBM i no es tecnico sino cultural. Involucrar al equipo desde el inicio, demostrar las ventajas con quick wins (VS Code, Git) y avanzar de forma incremental genera mucho mejor resultado que intentar una transformacion completa de un dia para otro.

VS Code for i actualizado (7.6)

Code for IBM i es la extension principal de VS Code para desarrollo en IBM i. Con IBM i 7.6, recibe actualizaciones importantes para alinearse con las nuevas capacidades del sistema.

Novedades relevantes

  • Soporte MFA: cuando MFA esta habilitado en el sistema, la extension soporta el flujo de autenticacion con segundo factor
  • Extensiones recomendadas: Db2 for i (SQL), RPGLE (syntax + lint), COBOL, CL y SELF integration
  • Remote debugging: mejoras en el debugger integrado para RPGLE y COBOL
  • IFS navigation: exploracion mejorada del sistema de archivos integrado

Requisitos

  • VS Code 1.70 o superior
  • Conexion SSH al sistema IBM i
  • Open Source Package Management instalado en el IBM i

Merlin: IDE cloud-based

IBM Wazi for i (Merlin) es un entorno de desarrollo cloud-based que corre en contenedores (OpenShift). Provee un IDE completo accesible desde el browser con compilacion, debug y CI/CD integrados.

Capacidades

  • Editor de codigo basado en Eclipse Theia (similar a VS Code en el browser)
  • Compilacion y debug remoto contra un IBM i
  • CI/CD integrado con pipelines definidos graficamente
  • Gestion de proyectos con repositorios Git
  • Ejecutar en OpenShift on-prem o en IBM Cloud

Cuando usar Merlin vs VS Code

VS Code + Code for i

  • IDE local, mas rapido
  • Gratis (extension open source)
  • Requiere SSH directo al IBM i
  • Configuracion manual de build
  • Ideal para equipos chicos

Merlin (IBM Wazi for i)

  • IDE en el browser, centralizado
  • Licencia IBM (producto comercial)
  • Corre en OpenShift contenedores
  • CI/CD integrado graficamente
  • Ideal para equipos grandes/enterprise