Skip to content

Commit

Permalink
feat(cloud/linting): verify template compatibility
Browse files Browse the repository at this point in the history
Clean up linting and add a new rule for element template compatibility.
  • Loading branch information
nikku authored and jarekdanielak committed Dec 12, 2024
1 parent f9b46bc commit eec50e9
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 43 deletions.
33 changes: 29 additions & 4 deletions src/cloud-element-templates/linting/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,29 @@
export {
elementTemplateLintRule,
ElementTemplateLinterPlugin
} from './LinterPlugin';
/**
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership.
*
* Camunda licenses this file to you under the MIT; you may not use this file
* except in compliance with the MIT License.
*/

import StaticResolver from 'bpmnlint/lib/resolver/static-resolver';

import validate from './rules/element-templates-validate';
import compatibility from './rules/element-templates-compatibility';

export const ElementTemplateLinterPlugin = function(templates) {
return {
config: {
rules: {
'element-templates/validate': [ 'error', { templates } ],
'element-templates/compatibility': [ 'warn', { templates } ]
}
},
resolver: new StaticResolver({
'rule:bpmnlint-plugin-element-templates/validate': validate,
'rule:bpmnlint-plugin-element-templates/compatibility': compatibility
})
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/**
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership.
*
* Camunda licenses this file to you under the MIT; you may not use this file
* except in compliance with the MIT License.
*/

import ElementTemplates from '../../ElementTemplates';
import EventBus from 'diagram-js/lib/core/EventBus';

import BpmnModdle from 'bpmn-moddle';
import { is } from 'bpmn-js/lib/util/ModelUtil';

import zeebeModdle from 'zeebe-bpmn-moddle/resources/zeebe';

import { Validator } from '../../Validator';

export default function({ templates = [] }) {
const moddle = new BpmnModdle({ zeebe: zeebeModdle });

const validator = new Validator(moddle).addAll(templates);
const validTemplates = validator.getValidTemplates();

// We use the ElementTemplates Module without the required bpmn-js modules
// As we only use it to facilitate template ID and version lookup,
// access to commandstack etc. is not required
const eventBus = new EventBus();
const elementTemplates = new ElementTemplates(null, null, eventBus, null, null);

elementTemplates.set(validTemplates);

function isUpdateAvailable(template) {

const latestTemplate = elementTemplates.getLatest(template.id, { deprecated: true })[0];

if (latestTemplate && latestTemplate !== template) {
return true;
}

return false;
}

function check(node, reporter) {

if (is(node, 'bpmn:Definitions')) {
elementTemplates.setEngines(getEnginesConfig(node));
}

if (!is(node, 'bpmn:FlowElement')) {
return;
}

let template = elementTemplates.get(node);

if (!template) {
return;
}

// Check compatibility
if (template.engines) {
const incomp = elementTemplates.getIncompatibleEngines(template);
Object.keys(incomp).forEach((engine) => {
reporter.report(
node.id,
getIncompatibilityText(engine, incomp[engine], isUpdateAvailable(template)),
{
name: node.name
}
);
});
}
}

return {
check
};

};

// helpers //////////////////////

function getEnginesConfig(definitions) {
const {
exporter,
exporterVersion
} = definitions;

const engines = {};

const executionPlatform = definitions.get('modeler:executionPlatform');
const executionPlatformVersion = definitions.get('modeler:executionPlatformVersion');

if (executionPlatform === 'Camunda Cloud' && executionPlatformVersion) {
engines.camunda = executionPlatformVersion;
}

if (exporter === 'Camunda Modeler' && exporterVersion) {
engines.camundaDesktopModeler = exporterVersion;
}

return engines;
}


function getIncompatibilityText(engine, { actual, required }, updateAvailable) {
const message =
`Element template incompatible with current <${engine}> environment. ` +
`Requires '${engine} ${required}'; found '${actual}'. ` +
`${updateAvailable ? 'Update available.' : ''}`;

return message.trim();
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,21 @@
* except in compliance with the MIT License.
*/

import StaticResolver from 'bpmnlint/lib/resolver/static-resolver';
import ElementTemplates from '../ElementTemplates';
import ElementTemplates from '../../ElementTemplates';
import EventBus from 'diagram-js/lib/core/EventBus';

import { getPropertyValue, validateProperty } from '../util/propertyUtil';
import { getPropertyValue, validateProperty } from '../../util/propertyUtil';

import { applyConditions } from '../Condition';
import { applyConditions } from '../../Condition';

import BpmnModdle from 'bpmn-moddle';
import { is } from 'bpmn-js/lib/util/ModelUtil';

import zeebeModdle from 'zeebe-bpmn-moddle/resources/zeebe';

import { Validator } from '../Validator';
import { Validator } from '../../Validator';

export const elementTemplateLintRule = ({ templates = [] }) => {
export default function({ templates = [] }) {
const moddle = new BpmnModdle({ zeebe: zeebeModdle });

const validator = new Validator(moddle).addAll(templates);
Expand Down Expand Up @@ -93,21 +92,6 @@ export const elementTemplateLintRule = ({ templates = [] }) => {

};


export const ElementTemplateLinterPlugin = function(templates) {
return {
config: {
rules: {
'element-templates/validate': [ 'error', { templates } ]
}
},
resolver: new StaticResolver({
'rule:bpmnlint-plugin-element-templates/validate': elementTemplateLintRule
})
};
};


// helpers //////////////////////

function getEntryId(property, template) {
Expand All @@ -123,4 +107,4 @@ function getEntryId(property, template) {

path.push(index);
return path.join('-');
}
}
50 changes: 50 additions & 0 deletions test/spec/cloud-element-templates/linting/LinterPlugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -216,5 +216,55 @@
"feel": "optional"
}
]
},
{
"$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json",
"name": "compatible",
"id": "compatible",
"appliesTo": [
"bpmn:Task"
],
"engines": {
"camunda": ">1.0"
},
"properties": []
},
{
"$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json",
"name": "incompatible",
"id": "incompatible",
"appliesTo": [
"bpmn:Task"
],
"engines": {
"camunda": "0"
},
"properties": []
},
{
"$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json",
"name": "incompatible-updatable",
"id": "incompatible-updatable",
"version": 1,
"appliesTo": [
"bpmn:Task"
],
"engines": {
"camunda": "0"
},
"properties": []
},
{
"$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json",
"name": "incompatible-updatable",
"id": "incompatible-updatable",
"version": 2,
"appliesTo": [
"bpmn:Task"
],
"engines": {
"camunda": "^8.5"
},
"properties": []
}
]
Loading

0 comments on commit eec50e9

Please sign in to comment.