javascriptyoutrack

How to set Youtrack issues state on Pull Requests update via JS workflows


I need to put a Youtrack issue into a Done state when the corresponding Pull Request is merged. I am using Javascript workflows and listening for issue changes.

Expected and Actual

I expected to be able to know which Pull Request was added, its current state (OPEN, MERGED, DECLINED) and its state before the current transaction.

But I see that every item in ctx.issue.pullRequests has isNew=false no matter what I do. Contrary to what it says in documentation

I tried

My temporary solution

So the only solution I have is to get the last fetched PR when updating the list of issue PRs and check if its state is MERGED.

Here is my code:

const entities = require('@jetbrains/youtrack-scripting-api/entities');

exports.rule = entities.Issue.onChange({
  title: 'Move task to "Done" when PR merged',
  guard: (ctx) => {
    if (ctx.issue.isChanged('pullRequests')) {

      const pullRequests = [];
      ctx.issue.pullRequests.forEach((pullRequest) => pullRequests.push(pullRequest));
      
      pullRequests.sort((a, b) => b.fetched - a.fetched);

      return pullRequests[pullRequests.length - 1].state.name == 'MERGED';
    } else {
      return false;
    }
  },
  action: (ctx) => {
    if (ctx.issue.fields.State && !ctx.issue.fields.State.is(ctx.State.Done)) {
      ctx.issue.fields.State = ctx.State.Done;
    }
  },
  requirements: {
    State: {
      type: entities.State.fieldType,
      name: 'State',
      Done: {}
    }
  }
});

I also can't figure out what the ctx.issue.pullRequests object represents. I can only call .forEach() on it.


Solution

  • I checked Youtrack's team own youtrack issue board and found answer here)

    And here is my final solution:

    const entities = require('@jetbrains/youtrack-scripting-api/entities');
    
    const DONE_STATE = 'Done';
    
    exports.rule = entities.Issue.onChange({
      title: 'Move task to "Done" when PR merged',
      guard: (ctx) => {
        return ctx.issue.pullRequests?.added?.isNotEmpty() && ctx.issue.pullRequests.added.last().state.name === 'MERGED';
      },
      action: (ctx) => {
        if (ctx.issue.fields.State && ctx.issue.fields.State.name !== DONE_STATE) {
          ctx.issue.fields.State = ctx.State.findValueByName(DONE_STATE);
        }
      },
      requirements: {
        State: {
          type: entities.State.fieldType,
          name: 'State',
          [DONE_STATE]: {}
        }
      }
    });