Este blog es parte de una serie de blogs, por lo que puede encontrar la primera página aquí (https://blogs.sap.com/2023/02/02/sap-cpi-ci-cd-from-from-zero-to-hero/). Esta es la agenda que estamos siguiendo:
Uno de los aspectos clave de nuestras interfaces es la calidad y consistencia del código. Dado que tenemos muchas interfaces, debemos asegurarnos de que todas sigan nuestro marco de pautas de desarrollo. Después de investigar un poco, encontré CPI Lint, un github de código abierto para traer pelusa a CPI desde @mortenw
Creo que el código es excelente, así que un agradecimiento especial a Morten por proporcionar esta herramienta. Más detalles sobre CPI Lint en su github https://github.com/mwittrock/cpilint y también en este blog de savia https://blogs.sap.com/2019/02/01/meet-cpilint/
A pesar de que Morten lanzó la versión 1.0.4, actualmente estamos usando la versión 1.0.3 y estoy en proceso de migrarla a la 1.0.4. En resumen, la herramienta actual es capaz de leer el código de un flujo de integración y compararlo con las reglas definidas en un archivo xml.
Todas estas reglas se pueden combinar con las regulares proporcionadas por el código base de cpilint.
Ejemplo de un archivo rules.xml válido que contiene tanto reglas estándar cpi lint como reglas personalizadas.
<?xml version="1.0"?>
<cpilint>
<rules>
<default-names-not-allowed-rule>
<exclude>Exception Subprocess</exclude>
</default-names-not-allowed-rule>
<iflow-matches-name>
<naming-pattern>FER_(S2P|F2I|M2C|Common|InterfaceName|MessageMappingsUnitTest|)(.*)(Publish|Subscribe|MAIN)$</naming-pattern>
</iflow-matches-name>
<disallowed-scripting-languages>
<disallow>javascript</disallow>
</disallowed-scripting-languages>
<cleartext-basic-auth-not-allowed/>
<!-- <matching-process-direct-channels-required/> We can't use this since we have cross package references and cpilint runs on a package basis -->
<disallowed-receiver-adapters>
<disallow>facebook</disallow>
<disallow>ftp</disallow>
<disallow>twitter</disallow>
</disallowed-receiver-adapters>
<disallowed-sender-adapters>
<disallow>ftp</disallow>
</disallowed-sender-adapters>
<unencrypted-data-store-write-not-allowed/>
<unencrypted-endpoints-not-allowed/>
<csrf-protection-required-with-exclude>
<exclude>FER_DUMMYVALUE_MAIN</exclude>
<exclude>FER_DUMMYVALUE_MAIN2</exclude>
</csrf-protection-required-with-exclude>
<iflow-description-required/>
<unused-parameters-rule/>
<allowed-headers-empty><include>(.*)(Publish|Subscribe)$</include></allowed-headers-empty>
<response-headers-allowed><exclude>\*</exclude></response-headers-allowed>
<undeclared-data-type/>
</rules>
</cpilint>
Para ejecutarlo, puede ir al directorio jenkins donde se extrajeron y ejecutaron los archivos zip para los flujos de flujo:
def call(String packageId, String reponame, boolean changesDone){
script {
dir("./IntegrationContent"){
def localPackage = packageId.startsWith('Test')
if(!localPackage)
{
def files = findFiles glob: "**/*.zip"
boolean exists = files.length > 0
if(exists)
{
catchError(buildResult: 'UNSTABLE', stageResult: 'UNSTABLE') {
bat 'cpilint -rules %CPILINT_HOME%rules.xml -directory ./'
}
}
}
}
}
}
En nuestro caso, este archivo se almacena dentro de la carpeta vars del repositorio git de Jenkins y se interpreta como una biblioteca compartida en Jenkins.
Para registrar bibliotecas compartidas personalizadas en jenkins, debe ir a la página de inicio de jenkins->Administrar Jenkins->Configurar sistema
Si alguna de las reglas falla, finalizamos la canalización del paquete con una advertencia y notificamos al desarrollador responsable.
Actualmente estoy en conversaciones con Morten (que actualmente está trabajando en CPILint 1.0.5), así que una vez que esté disponible, también planeo migrar estas reglas personalizadas a la nueva versión.
Además de estas comprobaciones, también estamos comprobando (fuera de esta herramienta):
def packageInfo = readFile(file: 'resources.cnt')
def slurper = new JsonSlurper().parseText(new String(packageInfo.decodeBase64()))
def documentationUrl=""
def hasCustomTags = false
slurper.resources.each
{
if(it.resourceType=="Url" && (it.name=="YOURPREDETERMINEDNAME" || it.displayName=="YOURPREDETERMINEDNAME"))
{
try{
documentationUrl = it.additionalAttributes.url.attributeValues[0]
}
catch(Exception e)
{
error("Error while reading documentation: ${e}")
}
}
}
if(it.resourceType=="ContentPackage")
{
List<String> raiseErrorTags = [];
def customAttribute = it.additionalAttributes.LineOfBusiness;
if(customAttribute!=null)
{
def list = customAttribute.attributeValues;
def hasValues = false;
for(int i=0;i<list.size();i++)
{
if(list[i]!="")
{
hasValues=true
}
}
if(!hasValues)
{
raiseErrorTags.push("LineOfBusiness");
}
}
else
{
raiseErrorTags.push("LineOfBusiness");
}
}
En este tema, presentamos la herramienta principal que usamos para verificar problemas de código (CPILint), así como verificaciones adicionales realizadas para asegurarnos de que la documentación y las etiquetas se mantuvieran correctamente.
Te invito a compartir algunos comentarios o pensamientos en las secciones de comentarios. Estoy seguro de que todavía hay mejoras o ideas para nuevas reglas que beneficiarían a toda la comunidad. Siempre puede obtener más información sobre la integración de la nube en el página de tema para el producto
Calle Eloy Gonzalo, 27
Madrid, Madrid.
Código Postal 28010
Paseo de la Reforma 26
Colonia Juárez, Cuauhtémoc
Ciudad de México 06600
Real Cariari
Autopista General Cañas,
San José, SJ 40104
Av. Jorge Basadre 349
San Isidro
Lima, LIM 15073