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

ワークフロー API を使用する

このページの情報を使用して、ワークフローリファレンスの他のセクションで説明されていないワークフロー API の特定のエンティティを操作する方法を学習します。

これらのガイドラインに従って、課題のプロパティ、カスタムフィールドの値、課題のリンクにアクセスします。

事前定義された課題フィールド

summarydescriptionreporter のような事前定義された課題フィールドは、すべて issue エンティティのプロパティです。

const summary = issue.summary; issue.summary = "Just a bug";
カスタムフィールド値

カスタムフィールドの値への参照は、フィールドが単一の値を保存するか複数の値を保存するかによって異なります。

  • 単一の値を格納するフィールドの場合、値を直接参照できます。

    const state = issue.fields.State; issue.fields.State = ctx.State.Open; if (issue.fields.State.name === ctx.State.Fixed.name) { // Do stuff }

  • 複数の値を格納するフィールドの場合、値はセットとして格納されます。セットで使用できる操作については、次のセクションで詳しく説明します。

    const versions = issue.fields["Fix versions"]; versions.forEach(function (v) { subtask.fields["Fix versions"].add(v); });

エイリアス

requirements ステートメントでカスタムフィールドに alias プロパティを設定した場合、このエイリアスを使用してフィールドの値にもアクセスできます。例: 修正バージョンフィールドのエイリアスが FV に設定されている場合:

issue.fields.FV.forEach(function (v) { // Do stuff });
課題リンク

課題リンクタイプには、内部または外部の名前でアクセスします。例: relates to または parent for 課題リンクは常にセットとして扱われます。

const parent = issue.links["subtask of"].first(); parent.links["parent for"].add(issue);

スペースまたは他のアルファベット以外の文字を含むカスタムフィールドと課題リンクタイプは、引用符と括弧で設定する必要があることに注意してください。

セットオブジェクトの使用

複数の値(Set <value type> として返される)で実行できる操作のグループがいくつかあります。

  • それらに直接(first()last()get(index))またはイテレータ(entries()values())でアクセスします。

  • Set のすべての値を forEach(visitor) でトラバースします。

  • find(predicate) で値を探し、値が has(value) で設定されているかどうかを確認します。

  • isEmpty()isNotEmpty()size プロパティでサイズを確認してください。

  • add(element)remove(element)clear() でコンテンツを変更します。

  • addedremovedisChanged プロパティを使用して設定オブジェクトの現在の変更を取得します。

このオブジェクトの詳細な説明については、設定を参照してください。

メソッドの呼び出し

// Call entity method: const stateCF = issue.project.findFieldByName('State'); // Call static method: const p = entities.Project.findByKey('INT'); // Call issue constructor: const newIssue = new entities.Issue(ctx.currentUser, issue.project, "Subtask");

特定のエンティティを見つける

課題やユーザーなどの特定のエンティティを見つけて、ワークフロースクリプトで使用するには、次の 2 つの方法があります。

  1. 要件に追加し、コンテキストで参照します。このアプローチは最も信頼性が高いため、できるだけ頻繁に使用してください。指定されたエンティティがデータベースに見つからない場合、スクリプトは実行されません。

  2. 最初のオプションが何らかの理由で適用できない場合、ワークフロー API から findBy* および find*By* メソッドを使用します。

findBy* メソッドを使用して、特定のエンティティの単一出現箇所を検索します。

const issue = entities.Issue.findById('MP-23'); // an entities.Issue or null const projectByName = entities.Project.findByName('Music Production'); // an entities.Project or null const projectByKey = entities.Project.findByKey('MP'); // an entities.Project or null const user = entities.User.findByLogin('jane.smith'); // an entities.User or null const userGroup = entities.UserGroup.findByName('MP team'); // an entities.UserGroup or null const agiles = entities.Agile.findByName('MP Scrum'); // a Set of entities.Agile const tags = entities.IssueTag.findByName('production'); // a Set of entities.IssueTag const queries = entities.SavedQuery.findByName('MP Backlog'); // a Set of entities.SavedQuery

find*By* メソッドを使用して、子エンティティを検索します。

const sprint = agiles.first().findSprintByName('Sprint 23'); // an entities.Sprint or null const priorityField = projectByKey.findFieldByName('Priority'); // an entities.ProjectCustomField or null const major = field.findValueByName('Major'); // an entities.Field or null const critical = field.findValueByOrdinal(1); // an entities.Field or null const assigneeField = projectByKey.findFieldByName('Assignee'); const jane = assigneeField.findValueByLogin('jane.smith'); // an entities.User or null const groupField = projectByKey.findFieldByName('Requestors'); const newBand = groupField.findValueByName('New Band'); // an entities.UserGroup or null

複数の課題を見つける

場合によっては、特定の基準に一致する一連の課題を検索し、1 つのルールの範囲内で処理したい場合があります。例: 課題のリストを作成し、メールメッセージとして送信できます。このような状況では、検索 API が役に立ちます。簡単な例を次に示します。

const entities = require('@jetbrains/youtrack-scripting-api/entities'); const search = require('@jetbrains/youtrack-scripting-api/search'); const workflow = require('@jetbrains/youtrack-scripting-api/workflow'); exports.rule = entities.Issue.onChange({ title: 'Do not allow developers to have more than 1 issue in progress per project', action: (ctx) => { const issue = ctx.issue; if (issue.isReported && (issue.fields.becomes(ctx.State, ctx.State['In Progress']) || issue.fields.isChanged(ctx.Assignee)) && (issue.fields.Assignee || {}).login === ctx.currentUser.login) { // First, we build a search query that checks the project that the issue belongs to and returns all of the issues // that are assigned to current user except for this issue. const query = 'for: me State: {In Progress} issue id: -' + issue.id; const inProgress = search.search(issue.project, query, ctx.currentUser); // If any issues are found, we get the first one and warn the user. if (inProgress.isNotEmpty()) { const otherIssue = inProgress.first(); const message = 'Dear ' + ctx.currentUser.login + ', please close <a href="' + otherIssue.url + '">' + otherIssue.id + '</a> first!'; workflow.check(false, message); } } }, requirements: { State: { type: entities.State.fieldType, 'In Progress': {} }, Assignee: { type: entities.User.fieldType } } });