diff --git a/index.js b/index.js
index ae9a970..a682678 100644
--- a/index.js
+++ b/index.js
@@ -21,6 +21,7 @@ const camundaCloud10Rules = withConfig({
'no-propagate-all-parent-variables': 'error',
'no-task-schedule': 'error',
'no-template': 'error',
+ 'no-version-tag': 'error',
'no-zeebe-properties': 'error',
'no-zeebe-user-task': 'error',
'sequence-flow-condition': 'error',
@@ -83,7 +84,8 @@ const camundaCloud86Rules = withConfig({
'inclusive-gateway',
'no-binding-type',
'no-execution-listeners',
- 'no-priority-definition'
+ 'no-priority-definition',
+ 'no-version-tag'
]),
'duplicate-execution-listeners': 'error',
'execution-listener': 'error',
@@ -143,6 +145,7 @@ const rules = {
'no-signal-event-sub-process': './rules/camunda-cloud/no-signal-event-sub-process',
'no-task-schedule': './rules/camunda-cloud/no-task-schedule',
'no-template': './rules/camunda-cloud/no-template',
+ 'no-version-tag': './rules/camunda-cloud/no-version-tag',
'no-zeebe-properties': './rules/camunda-cloud/no-zeebe-properties',
'no-zeebe-user-task': './rules/camunda-cloud/no-zeebe-user-task',
'priority-definition': './rules/camunda-cloud/priority-definition',
diff --git a/rules/camunda-cloud/no-version-tag.js b/rules/camunda-cloud/no-version-tag.js
new file mode 100644
index 0000000..5f7c27f
--- /dev/null
+++ b/rules/camunda-cloud/no-version-tag.js
@@ -0,0 +1,63 @@
+const { is } = require('bpmnlint-utils');
+
+const { hasProperties, findExtensionElement, hasNoExtensionElement } = require('../utils/element');
+
+const { reportErrors } = require('../utils/reporter');
+
+const { skipInNonExecutableProcess } = require('../utils/rule');
+
+const allowedVersion = '8.6';
+
+module.exports = skipInNonExecutableProcess(function() {
+ function check(node, reporter) {
+ if (is(node, 'bpmn:Process')) {
+ const errors = hasNoExtensionElement(node, 'zeebe:VersionTag', node, allowedVersion);
+
+ if (errors && errors.length) {
+ reportErrors(node, reporter, errors);
+ }
+
+ return;
+ }
+
+ let extensionElement;
+
+ if (is(node, 'bpmn:BusinessRuleTask')) {
+ extensionElement = findExtensionElement(node, 'zeebe:CalledDecision');
+ } else if (is(node, 'bpmn:CallActivity')) {
+ extensionElement = findExtensionElement(node, 'zeebe:CalledElement');
+ } else if (is(node, 'bpmn:UserTask')) {
+ extensionElement = findExtensionElement(node, 'zeebe:FormDefinition');
+ }
+
+ if (extensionElement) {
+ let errors = hasProperties(extensionElement, {
+ bindingType: {
+ allowed: (value) => value !== 'versionTag',
+ allowedVersion
+ }
+ }, node);
+
+ if (errors && errors.length) {
+ reportErrors(node, reporter, errors);
+
+ return;
+ }
+
+ errors = hasProperties(extensionElement, {
+ versionTag: {
+ allowed: false,
+ allowedVersion
+ }
+ }, node);
+
+ if (errors && errors.length) {
+ reportErrors(node, reporter, errors);
+ }
+ }
+ }
+
+ return {
+ check
+ };
+});
\ No newline at end of file
diff --git a/test/camunda-cloud/integration/no-version-tag-errors.bpmn b/test/camunda-cloud/integration/no-version-tag-errors.bpmn
new file mode 100644
index 0000000..d2e71a7
--- /dev/null
+++ b/test/camunda-cloud/integration/no-version-tag-errors.bpmn
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/camunda-cloud/integration/no-version-tag-spec.js b/test/camunda-cloud/integration/no-version-tag-spec.js
new file mode 100644
index 0000000..73b30b6
--- /dev/null
+++ b/test/camunda-cloud/integration/no-version-tag-spec.js
@@ -0,0 +1,77 @@
+const { expect } = require('chai');
+
+const Linter = require('bpmnlint/lib/linter');
+
+const NodeResolver = require('bpmnlint/lib/resolver/node-resolver');
+
+const { readModdle } = require('../../helper');
+
+const versions = [
+ '1.0',
+ '1.1',
+ '1.2',
+ '1.3',
+ '8.0',
+ '8.1',
+ '8.2',
+ '8.3',
+ '8.4',
+ '8.5'
+];
+
+describe('integration - no-version-tag', function() {
+
+ versions.forEach(function(version) {
+
+ let linter;
+
+ beforeEach(function() {
+ linter = new Linter({
+ config: {
+ extends: `plugin:camunda-compat/camunda-cloud-${ version.replace('.', '-') }`
+ },
+ resolver: new NodeResolver()
+ });
+ });
+
+
+ describe(`Camunda Cloud ${ version }`, function() {
+
+ describe('no errors', function() {
+
+ it('should not have errors', async function() {
+
+ // given
+ const { root } = await readModdle('test/camunda-cloud/integration/no-version-tag.bpmn');
+
+ // when
+ const reports = await linter.lint(root);
+
+ // then
+ expect(reports[ 'camunda-compat/no-version-tag' ]).not.to.exist;
+ });
+
+ });
+
+
+ describe('errors', function() {
+
+ it('should have errors', async function() {
+
+ // given
+ const { root } = await readModdle('test/camunda-cloud/integration/no-version-tag-errors.bpmn');
+
+ // when
+ const reports = await linter.lint(root);
+
+ // then
+ expect(reports[ 'camunda-compat/no-version-tag' ]).to.exist;
+ });
+
+ });
+
+ });
+
+ });
+
+});
\ No newline at end of file
diff --git a/test/camunda-cloud/integration/no-version-tag.bpmn b/test/camunda-cloud/integration/no-version-tag.bpmn
new file mode 100644
index 0000000..29a7f78
--- /dev/null
+++ b/test/camunda-cloud/integration/no-version-tag.bpmn
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/camunda-cloud/no-version-tag.spec.js b/test/camunda-cloud/no-version-tag.spec.js
new file mode 100644
index 0000000..584cca1
--- /dev/null
+++ b/test/camunda-cloud/no-version-tag.spec.js
@@ -0,0 +1,293 @@
+const RuleTester = require('bpmnlint/lib/testers/rule-tester');
+
+const rule = require('../../rules/camunda-cloud/no-version-tag');
+
+const {
+ createDefinitions,
+ createModdle,
+ createProcess
+} = require('../helper');
+
+const { ERROR_TYPES } = require('../../rules/utils/element');
+
+const valid = [
+ {
+ name: 'process',
+ config: { version: '8.5' },
+ moddleElement: createModdle(createDefinitions(`
+
+ `))
+ },
+ {
+ name: 'business rule task',
+ moddleElement: createModdle(createProcess(`
+
+
+
+
+
+ `))
+ },
+ {
+ name: 'business rule task (version tag) (non-executable process)',
+ config: { version: '8.5' },
+ moddleElement: createModdle(createDefinitions(`
+
+
+
+
+
+
+
+ `))
+ },
+ {
+ name: 'call activity',
+ moddleElement: createModdle(createProcess(`
+
+
+
+
+
+ `))
+ },
+ {
+ name: 'call activity (version tag) (non-executable process)',
+ config: { version: '8.5' },
+ moddleElement: createModdle(createDefinitions(`
+
+
+
+
+
+
+
+ `))
+ },
+ {
+ name: 'user task',
+ moddleElement: createModdle(createProcess(`
+
+
+
+
+
+ `))
+ },
+ {
+ name: 'user task (version tag) (non-executable process)',
+ config: { version: '8.5' },
+ moddleElement: createModdle(createDefinitions(`
+
+
+
+
+
+
+
+ `))
+ }
+];
+
+const invalid = [
+ {
+ name: 'process (version tag)',
+ config: { version: '8.5' },
+ moddleElement: createModdle(createDefinitions(`
+
+
+
+
+
+ `)),
+ report: {
+ id: 'Process_1',
+ message: 'Extension element of type only allowed by Camunda 8.6',
+ path: [
+ 'extensionElements',
+ 'values',
+ 0
+ ],
+ data: {
+ type: ERROR_TYPES.EXTENSION_ELEMENT_NOT_ALLOWED,
+ node: 'Process_1',
+ parentNode: null,
+ extensionElement: 'zeebe:VersionTag',
+ allowedVersion: '8.6'
+ }
+ }
+ },
+ {
+ name: 'business rule task (binding type)',
+ config: { version: '8.5' },
+ moddleElement: createModdle(createProcess(`
+
+
+
+
+
+ `)),
+ report: {
+ id: 'BusinessRuleTask_1',
+ message: 'Property value of only allowed by Camunda 8.6 or newer',
+ path: [
+ 'extensionElements',
+ 'values',
+ 0,
+ 'bindingType'
+ ],
+ data: {
+ type: ERROR_TYPES.PROPERTY_VALUE_NOT_ALLOWED,
+ node: 'zeebe:CalledDecision',
+ parentNode: 'BusinessRuleTask_1',
+ property: 'bindingType',
+ allowedVersion: '8.6'
+ }
+ }
+ },
+ {
+ name: 'business rule task (version tag)',
+ config: { version: '8.5' },
+ moddleElement: createModdle(createProcess(`
+
+
+
+
+
+ `)),
+ report: {
+ id: 'BusinessRuleTask_1',
+ message: 'Property only allowed by Camunda 8.6 or newer',
+ path: [
+ 'extensionElements',
+ 'values',
+ 0,
+ 'versionTag'
+ ],
+ data: {
+ type: ERROR_TYPES.PROPERTY_NOT_ALLOWED,
+ node: 'zeebe:CalledDecision',
+ parentNode: 'BusinessRuleTask_1',
+ property: 'versionTag',
+ allowedVersion: '8.6'
+ }
+ }
+ },
+ {
+ name: 'call activity (binding type)',
+ config: { version: '8.5' },
+ moddleElement: createModdle(createProcess(`
+
+
+
+
+
+ `)),
+ report: {
+ id: 'CallActivity_1',
+ message: 'Property value of only allowed by Camunda 8.6 or newer',
+ path: [
+ 'extensionElements',
+ 'values',
+ 0,
+ 'bindingType'
+ ],
+ data: {
+ type: ERROR_TYPES.PROPERTY_VALUE_NOT_ALLOWED,
+ node: 'zeebe:CalledElement',
+ parentNode: 'CallActivity_1',
+ property: 'bindingType',
+ allowedVersion: '8.6'
+ }
+ }
+ },
+ {
+ name: 'call activity (version tag)',
+ config: { version: '8.5' },
+ moddleElement: createModdle(createProcess(`
+
+
+
+
+
+ `)),
+ report: {
+ id: 'CallActivity_1',
+ message: 'Property only allowed by Camunda 8.6 or newer',
+ path: [
+ 'extensionElements',
+ 'values',
+ 0,
+ 'versionTag'
+ ],
+ data: {
+ type: ERROR_TYPES.PROPERTY_NOT_ALLOWED,
+ node: 'zeebe:CalledElement',
+ parentNode: 'CallActivity_1',
+ property: 'versionTag',
+ allowedVersion: '8.6'
+ }
+ }
+ },
+ {
+ name: 'user task (binding type)',
+ config: { version: '8.5' },
+ moddleElement: createModdle(createProcess(`
+
+
+
+
+
+ `)),
+ report: {
+ id: 'UserTask_1',
+ message: 'Property value of only allowed by Camunda 8.6 or newer',
+ path: [
+ 'extensionElements',
+ 'values',
+ 0,
+ 'bindingType'
+ ],
+ data: {
+ type: ERROR_TYPES.PROPERTY_VALUE_NOT_ALLOWED,
+ node: 'zeebe:FormDefinition',
+ parentNode: 'UserTask_1',
+ property: 'bindingType',
+ allowedVersion: '8.6'
+ }
+ }
+ },
+ {
+ name: 'user task (version tag)',
+ config: { version: '8.5' },
+ moddleElement: createModdle(createProcess(`
+
+
+
+
+
+ `)),
+ report: {
+ id: 'UserTask_1',
+ message: 'Property only allowed by Camunda 8.6 or newer',
+ path: [
+ 'extensionElements',
+ 'values',
+ 0,
+ 'versionTag'
+ ],
+ data: {
+ type: ERROR_TYPES.PROPERTY_NOT_ALLOWED,
+ node: 'zeebe:FormDefinition',
+ parentNode: 'UserTask_1',
+ property: 'versionTag',
+ allowedVersion: '8.6'
+ }
+ }
+ }
+];
+
+RuleTester.verify('no-version-tag', rule, {
+ valid,
+ invalid
+});
\ No newline at end of file
diff --git a/test/config/configs.spec.js b/test/config/configs.spec.js
index f0e7e74..3b97228 100644
--- a/test/config/configs.spec.js
+++ b/test/config/configs.spec.js
@@ -22,10 +22,11 @@ describe('configs', function() {
'no-expression': [ 'error', { version: '1.0' } ],
'no-loop': [ 'error', { version: '1.0' } ],
'no-multiple-none-start-events' : [ 'error', { version: '1.0' } ],
+ 'no-priority-definition': [ 'error', { version: '1.0' } ],
'no-propagate-all-parent-variables' : [ 'error', { version: '1.0' } ],
'no-task-schedule': [ 'error', { version: '1.0' } ],
- 'no-priority-definition': [ 'error', { version: '1.0' } ],
'no-template': [ 'error', { version: '1.0' } ],
+ 'no-version-tag': [ 'error', { version: '1.0' } ],
'no-zeebe-properties': [ 'error', { version: '1.0' } ],
'no-zeebe-user-task': [ 'error', { version: '1.0' } ],
'sequence-flow-condition': [ 'error', { version: '1.0' } ],
@@ -55,10 +56,11 @@ describe('configs', function() {
'no-expression': [ 'error', { version: '1.1' } ],
'no-loop': [ 'error', { version: '1.1' } ],
'no-multiple-none-start-events' : [ 'error', { version: '1.1' } ],
+ 'no-priority-definition': [ 'error', { version: '1.1' } ],
'no-propagate-all-parent-variables' : [ 'error', { version: '1.1' } ],
'no-task-schedule': [ 'error', { version: '1.1' } ],
- 'no-priority-definition': [ 'error', { version: '1.1' } ],
'no-template': [ 'error', { version: '1.1' } ],
+ 'no-version-tag': [ 'error', { version: '1.1' } ],
'no-zeebe-properties': [ 'error', { version: '1.1' } ],
'no-zeebe-user-task': [ 'error', { version: '1.1' } ],
'sequence-flow-condition': [ 'error', { version: '1.1' } ],
@@ -88,10 +90,11 @@ describe('configs', function() {
'no-expression': [ 'error', { version: '1.2' } ],
'no-loop': [ 'error', { version: '1.2' } ],
'no-multiple-none-start-events' : [ 'error', { version: '1.2' } ],
+ 'no-priority-definition': [ 'error', { version: '1.2' } ],
'no-propagate-all-parent-variables' : [ 'error', { version: '1.2' } ],
'no-task-schedule': [ 'error', { version: '1.2' } ],
- 'no-priority-definition': [ 'error', { version: '1.2' } ],
'no-template': [ 'error', { version: '1.2' } ],
+ 'no-version-tag': [ 'error', { version: '1.2' } ],
'no-zeebe-properties': [ 'error', { version: '1.2' } ],
'no-zeebe-user-task': [ 'error', { version: '1.2' } ],
'sequence-flow-condition': [ 'error', { version: '1.2' } ],
@@ -121,10 +124,11 @@ describe('configs', function() {
'no-expression': [ 'error', { version: '1.3' } ],
'no-loop': [ 'error', { version: '1.3' } ],
'no-multiple-none-start-events' : [ 'error', { version: '1.3' } ],
+ 'no-priority-definition': [ 'error', { version: '1.3' } ],
'no-propagate-all-parent-variables' : [ 'error', { version: '1.3' } ],
'no-task-schedule': [ 'error', { version: '1.3' } ],
- 'no-priority-definition': [ 'error', { version: '1.3' } ],
'no-template': [ 'error', { version: '1.3' } ],
+ 'no-version-tag': [ 'error', { version: '1.3' } ],
'no-zeebe-properties': [ 'error', { version: '1.3' } ],
'no-zeebe-user-task': [ 'error', { version: '1.3' } ],
'sequence-flow-condition': [ 'error', { version: '1.3' } ],
@@ -155,9 +159,10 @@ describe('configs', function() {
'no-expression': [ 'error', { version: '8.0' } ],
'no-loop': [ 'error', { version: '8.0' } ],
'no-multiple-none-start-events' : [ 'error', { version: '8.0' } ],
+ 'no-priority-definition': [ 'error', { version: '8.0' } ],
'no-propagate-all-parent-variables' : [ 'error', { version: '8.0' } ],
'no-task-schedule': [ 'error', { version: '8.0' } ],
- 'no-priority-definition': [ 'error', { version: '8.0' } ],
+ 'no-version-tag': [ 'error', { version: '8.0' } ],
'no-zeebe-properties': [ 'error', { version: '8.0' } ],
'no-zeebe-user-task': [ 'error', { version: '8.0' } ],
'sequence-flow-condition': [ 'error', { version: '8.0' } ],
@@ -189,9 +194,10 @@ describe('configs', function() {
'no-expression': [ 'error', { version: '8.1' } ],
'no-loop': [ 'error', { version: '8.1' } ],
'no-multiple-none-start-events' : [ 'error', { version: '8.1' } ],
+ 'no-priority-definition': [ 'error', { version: '8.1' } ],
'no-propagate-all-parent-variables' : [ 'error', { version: '8.1' } ],
'no-task-schedule': [ 'error', { version: '8.1' } ],
- 'no-priority-definition': [ 'error', { version: '8.1' } ],
+ 'no-version-tag': [ 'error', { version: '8.1' } ],
'no-zeebe-user-task': [ 'error', { version: '8.1' } ],
'sequence-flow-condition': [ 'error', { version: '8.1' } ],
'subscription': [ 'error', { version: '8.1' } ],
@@ -224,8 +230,9 @@ describe('configs', function() {
'no-expression': [ 'error', { version: '8.2' } ],
'no-loop': [ 'error', { version: '8.2' } ],
'no-multiple-none-start-events' : [ 'error', { version: '8.2' } ],
- 'no-signal-event-sub-process': [ 'error', { version: '8.2' } ],
'no-priority-definition': [ 'error', { version: '8.2' } ],
+ 'no-signal-event-sub-process': [ 'error', { version: '8.2' } ],
+ 'no-version-tag': [ 'error', { version: '8.2' } ],
'no-zeebe-user-task': [ 'error', { version: '8.2' } ],
'sequence-flow-condition': [ 'error', { version: '8.2' } ],
'subscription': [ 'error', { version: '8.2' } ],
@@ -260,6 +267,7 @@ describe('configs', function() {
'no-loop': [ 'error', { version: '8.3' } ],
'no-multiple-none-start-events' : [ 'error', { version: '8.3' } ],
'no-priority-definition': [ 'error', { version: '8.3' } ],
+ 'no-version-tag': [ 'error', { version: '8.3' } ],
'no-zeebe-user-task': [ 'error', { version: '8.3' } ],
'secrets': [ 'warn', { version: '8.3' } ],
'sequence-flow-condition': [ 'error', { version: '8.3' } ],
@@ -295,6 +303,7 @@ describe('configs', function() {
'no-loop': [ 'error', { version: '8.4' } ],
'no-multiple-none-start-events' : [ 'error', { version: '8.4' } ],
'no-priority-definition': [ 'error', { version: '8.4' } ],
+ 'no-version-tag': [ 'error', { version: '8.4' } ],
'no-zeebe-user-task': [ 'error', { version: '8.4' } ],
'secrets': [ 'warn', { version: '8.4' } ],
'sequence-flow-condition': [ 'error', { version: '8.4' } ],
@@ -330,6 +339,7 @@ describe('configs', function() {
'no-loop': [ 'error', { version: '8.5' } ],
'no-multiple-none-start-events' : [ 'error', { version: '8.5' } ],
'no-priority-definition': [ 'error', { version: '8.5' } ],
+ 'no-version-tag': [ 'error', { version: '8.5' } ],
'secrets': [ 'warn', { version: '8.5' } ],
'sequence-flow-condition': [ 'error', { version: '8.5' } ],
'signal-reference': [ 'error', { version: '8.5' } ],
@@ -427,6 +437,7 @@ describe('configs', function() {
'no-signal-event-sub-process': 'error',
'no-task-schedule': 'error',
'no-template': 'error',
+ 'no-version-tag': 'error',
'no-zeebe-properties': 'error',
'no-zeebe-user-task': 'error',
'priority-definition': 'error',