YouTrack および Hub ヘルプの開発者ポータル

重複

このワークフローは、重複する課題を管理するためのいくつかのオプションを提供します。

ユースケース

このワークフローは、重複する課題を自動的に処理するのに役立ついくつかの異なるユースケースをサポートしています。

  • ユーザーが複製状態の課題から重複リンクを削除できないようにします。

  • 複製状態のすべての課題が重複した課題にリンクされていることを確認してください。

  • 重複リンクが追加されたときに、課題の状態を複製に自動的に変更します。

  • 重複リンクが追加されたときに課題の優先度を上げます。

  • 重複する課題の重複を作成する代わりに、重複するリンクを単一の課題に添付します。

モジュール

このワークフローには、重複する課題を管理するために適用できるいくつかの異なるルールが含まれています。

重複したリンクを単一の重複した課題に添付する

最初のルールは、重複する課題を 1 つの課題に自動的に添付します。これにより、ユーザーは重複の「ツリー」を作成できなくなり、すべての重複リンクが 1 つの課題に統合されます。

const workflow = require('@jetbrains/youtrack-scripting-api/workflow'); const entities = require('@jetbrains/youtrack-scripting-api/entities'); exports.rule = entities.Issue.onChange({ title: 'Attach duplicate links to single duplicated issue', guard: (ctx) => { const issue = ctx.issue; return issue.links.duplicates.isChanged || issue.links['is duplicated by'].isChanged || issue.isChanged('duplicateCluster'); }, action: (ctx) => { const issue = ctx.issue; const duplicateRoot = issue.duplicateRoot; if (duplicateRoot !== null && duplicateRoot.id !== (issue.links.duplicates.first() || {}).id) { workflow.message('Link was reattached to {0}', duplicateRoot.id); issue.links.duplicates.clear(); if (issue.id !== duplicateRoot.id) { issue.links.duplicates.add(duplicateRoot); duplicateRoot.links.duplicates.clear(); } } }, requirements: { Duplicate: { type: entities.IssueLinkPrototype, outward: 'is duplicated by', inward: 'duplicates' } } });

課題が別の課題と重複する場合に優先度を上げる

次のルールは、1 つ以上の課題によって重複している課題の優先度を上げようとします。重複する課題の優先度がそれよりも高い場合、元の課題の優先度が上がります。

const entities = require('@jetbrains/youtrack-scripting-api/entities'); exports.rule = entities.Issue.onChange({ title: 'Raise priority when issue is duplicated by another issue', guard: function (ctx) { return ctx.issue.links['is duplicated by'].added.isNotEmpty() && ctx.issue.fields.Priority; }, action: function (ctx) { const issue = ctx.issue; let currentPriorityOrdinal = issue.fields.Priority.ordinal; issue.links['is duplicated by'].added.forEach(function (added) { if (added.project.key !== issue.project.key) { const anotherProjectField = added.project.findFieldByName(ctx.Priority.name); const bundlesAreEqual = function () { const set1 = anotherProjectField.values.entries(); const set2 = ctx.Priority.values.entries(); for (let next1 = set1.next(), next2 = set2.next(); ; next1 = set1.next(), next2 = set2.next()) { if (next1.done !== next2.done || (next1.value || {}).name !== (next2.value || {}).name) { return false; } if (next1.done || next2.done) { return true; } } }; if (!anotherProjectField || !bundlesAreEqual()) { console.trace('Can not copy priority of a duplicate as there\'s no respective state in project ' + added.project.key + ' or value sets are not identical'); return; } } if (added.fields.Priority && added.fields.Priority.ordinal < currentPriorityOrdinal) { issue.fields.Priority = added.fields.Priority.name; // need to use .name here as issues can belong to different projects currentPriorityOrdinal = issue.fields.Priority.ordinal; } }); }, requirements: { Priority: { type: entities.EnumField.fieldType }, Duplicate: { type: entities.IssueLinkPrototype, outward: 'is duplicated by', inward: 'duplicates' } } });

すべての重複リンクが削除されたときに課題を再度開く

次のルールは、課題に重複するリンクが添付されていない場合、課題の状態を複製からオープンに自動的に変更します。

const entities = require('@jetbrains/youtrack-scripting-api/entities'); exports.rule = entities.Issue.onChange({ title: 'Reopen issue when all duplicates links are removed', guard: (ctx) => { const issue = ctx.issue; return issue.fields.is(ctx.State, ctx.State.Duplicate) && issue.links.duplicates.removed.isNotEmpty() && issue.links.duplicates.isEmpty(); }, action: (ctx) => { ctx.issue.fields.State = ctx.State.Open; }, requirements: { State: { type: entities.State.fieldType, Duplicate: {}, Open: {} }, Duplicate: { type: entities.IssueLinkPrototype, outward: 'is duplicated by', inward: 'duplicates' } } });

重複リンクが課題に追加された場合、状態を「重複」に設定する

次のルールは、ユーザーが重複リンクを追加すると、発行状態を複製に自動的に変更します。

課題が更新されると、このルールは重複としてリンクされている課題のリストが空でないこと、およびこの課題の状態が複製ではないことを確認します。重複リンクが追加され、課題の状態が複製ではない場合、このルールはユーザーに状態フィールドを更新する権限があることを確認します。ユーザーに十分な権限がある場合、課題の状態は複製に設定されます。

const entities = require('@jetbrains/youtrack-scripting-api/entities'); exports.rule = entities.Issue.onChange({ title: 'Set state to "Duplicate" when duplicates link is added to issue', guard: (ctx) => { return ctx.issue.links.duplicates.added.isNotEmpty() && !ctx.issue.fields.is(ctx.State, ctx.State.Duplicate); }, action: (ctx) => { if (ctx.issue.canBeWrittenBy(ctx.State.name, ctx.currentUser)) { ctx.issue.fields.State = ctx.State.Duplicate; } }, requirements: { State: { type: entities.State.fieldType, Duplicate: {} }, Duplicate: { type: entities.IssueLinkPrototype, outward: 'is duplicated by', inward: 'duplicates' } } });

次のルールでは、ユーザーが課題の状態を複製に変更するときに、重複した課題へのリンクをユーザーに強制します。

課題が更新されると、このルールは課題の状態が複製に変更されたことを確認します。状態が複製に変更され、重複タイプのリンクのリストが空の場合、重複した課題にリンクを追加するようユーザーに通知されます。

const workflow = require('@jetbrains/youtrack-scripting-api/workflow'); const entities = require('@jetbrains/youtrack-scripting-api/entities'); exports.rule = entities.Issue.onChange({ title: 'Require links to duplicate issue when state becomes "Duplicate"', guard: (ctx) => { return ctx.issue.fields.becomes(ctx.State, ctx.State.Duplicate); }, action: (ctx) => { ctx.issue.required('duplicates', 'Add link to duplicate issue.'); }, requirements: { State: { type: entities.State.fieldType, Duplicate: {} }, Duplicate: { type: entities.IssueLinkPrototype, outward: 'is duplicated by', inward: 'duplicates' } } });
2026 年 9 月 10 日