jira-sprinter 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -87,6 +87,7 @@ The `auto` command automates the management of split tasks based on ticket state
87
87
  - **Preliminary Testing Requested**: Scans the board for issues where Preliminary Testing is marked as "Requested" and creates the corresponding split task if one does not already exist (or was previously closed).
88
88
  - **Preliminary Testing Failed**: When testing has failed, automatically closes the linked Preliminary Testing split task.
89
89
  - **Integration without QE Task**: Finds issues in "Integration" status that lack an open QE Task and creates one automatically.
90
+ - **Release Pending with QE Task**: When an issue moves to "Release Pending" status, automatically closes the linked QE Task if it is still open.
90
91
 
91
92
  ```md
92
93
  $ jira-sprinter auto --help
package/dist/main.js CHANGED
@@ -47713,7 +47713,9 @@ var Jira = class {
47713
47713
  }
47714
47714
  async getlinkedTasks(issue2, expectedTasks) {
47715
47715
  if (this.dry) {
47716
- this.logger.log(`Would get linked tasks for issue: ${issue2}`);
47716
+ this.logger.log(
47717
+ ` ${source_default.dim(`Fetching linked tasks for ${issue2} (dry-run)`)}`
47718
+ );
47717
47719
  return [
47718
47720
  {
47719
47721
  key: "RHEL-1234",
@@ -47752,11 +47754,13 @@ var Jira = class {
47752
47754
  async createTasks(issue2, tasks) {
47753
47755
  if (this.dry) {
47754
47756
  this.logger.log(
47755
- `Would create tasks: ${tasks.join(", ")} for issue: ${issue2}`
47757
+ ` ${source_default.dim(`Creating tasks ${tasks.join(", ")} for ${issue2} (dry-run)`)}`
47756
47758
  );
47757
47759
  return;
47758
47760
  }
47759
- this.logger.log(`Creating tasks: ${tasks.join(", ")} for issue: ${issue2}`);
47761
+ this.logger.log(
47762
+ ` ${source_default.cyan(`Creating tasks ${tasks.join(", ")} for ${issue2}`)}`
47763
+ );
47760
47764
  await this.api.issues.editIssue({
47761
47765
  issueIdOrKey: issue2,
47762
47766
  fields: {
@@ -47767,10 +47771,10 @@ var Jira = class {
47767
47771
  }
47768
47772
  async closeTask(issue2) {
47769
47773
  if (this.dry) {
47770
- this.logger.log(`Would close task: ${issue2}`);
47774
+ this.logger.log(` ${source_default.dim(`Closing task ${issue2} (dry-run)`)}`);
47771
47775
  return;
47772
47776
  }
47773
- this.logger.log(`Closing task: ${issue2}`);
47777
+ this.logger.log(` ${source_default.cyan(`Closing task ${issue2}`)}`);
47774
47778
  await this.api.issues.doTransition({
47775
47779
  issueIdOrKey: issue2,
47776
47780
  transition: {
@@ -47800,7 +47804,7 @@ var Jira = class {
47800
47804
  assignee
47801
47805
  );
47802
47806
  const version2 = await instance.getVersion();
47803
- console.debug(`JIRA Version: ${version2}`);
47807
+ logger.log(source_default.dim(`JIRA v${version2}`));
47804
47808
  return instance;
47805
47809
  }
47806
47810
  };
@@ -47826,9 +47830,12 @@ var Logger = class _Logger {
47826
47830
  async function runAuto(options) {
47827
47831
  const logger = new Logger(!!options.nocolor);
47828
47832
  const jira = await Jira.getInstance(options.dry, logger, options.assignee);
47833
+ logger.log(
47834
+ `${source_default.cyan(`Verifying issues in board ${options.board} - team: ${options.team}`)}`
47835
+ );
47829
47836
  const boardIssues = await jira.getBoardIssues(
47830
47837
  options.board,
47831
- `project = RHEL and issuetype in (Bug, Story, Vulnerability) and statusCategory != Done`
47838
+ `project = RHEL and issuetype in (Bug, Story, Vulnerability) and status != Closed`
47832
47839
  );
47833
47840
  const preliminaryTestingRequested = boardIssues.filter(
47834
47841
  (issue2) => issue2.fields?.[jira.fields.preliminaryTesting]?.value === "Requested" && !issue2.fields?.issuelinks?.some(
@@ -47837,11 +47844,6 @@ async function runAuto(options) {
47837
47844
  ) && l.outwardIssue?.fields?.status.name !== "Closed"
47838
47845
  )
47839
47846
  );
47840
- if (preliminaryTestingRequested.length > 0) {
47841
- logger.log(
47842
- `${source_default.green("Preliminary Testing Requested")} - ${preliminaryTestingRequested.length}`
47843
- );
47844
- }
47845
47847
  const preliminaryTestingFailed = boardIssues.filter(
47846
47848
  (issue2) => issue2.fields?.[jira.fields.preliminaryTesting]?.value === "Fail" && issue2.fields?.issuelinks?.some(
47847
47849
  (l) => l.type?.outward === "split to" && l.outwardIssue?.fields?.summary.startsWith(
@@ -47849,25 +47851,36 @@ async function runAuto(options) {
47849
47851
  ) && l.outwardIssue?.fields?.status.name !== "Closed"
47850
47852
  )
47851
47853
  );
47852
- if (preliminaryTestingFailed.length > 0) {
47853
- logger.log(
47854
- `${source_default.red("Preliminary Testing Failed")} - ${preliminaryTestingFailed.length}`
47855
- );
47856
- }
47857
47854
  const issuesInIntegration = boardIssues.filter(
47858
47855
  (issue2) => issue2.fields?.status.name === "Integration" && !issue2.fields?.issuelinks?.some(
47859
47856
  (l) => l.type?.outward === "split to" && l.outwardIssue?.fields?.summary.startsWith(jira.qeTask.summary) && l.outwardIssue?.fields?.status.name !== "Closed"
47860
47857
  )
47861
47858
  );
47862
- if (issuesInIntegration.length > 0) {
47863
- logger.log(
47864
- `${source_default.yellow("Issues in Integration w/o QE Task")} - ${issuesInIntegration.length}`
47865
- );
47859
+ const issuesInReleasePending = boardIssues.filter(
47860
+ (issue2) => issue2.fields?.status.name === "Release Pending" && issue2.fields?.issuelinks?.some(
47861
+ (l) => l.type?.outward === "split to" && l.outwardIssue?.fields?.summary.startsWith(jira.qeTask.summary) && l.outwardIssue?.fields?.status.name !== "Closed"
47862
+ )
47863
+ );
47864
+ const summary = [
47865
+ {
47866
+ label: "Preliminary Testing Requested",
47867
+ count: preliminaryTestingRequested.length
47868
+ },
47869
+ {
47870
+ label: "Preliminary Testing Failed",
47871
+ count: preliminaryTestingFailed.length
47872
+ },
47873
+ { label: "Integration w/o QE Task", count: issuesInIntegration.length },
47874
+ {
47875
+ label: "Release Pending w/ QE Task",
47876
+ count: issuesInReleasePending.length
47877
+ }
47878
+ ].filter((entry) => entry.count > 0);
47879
+ for (const { label, count } of summary) {
47880
+ logger.log(` ${source_default.cyan(label)}: ${source_default.bold(count)}`);
47866
47881
  }
47867
- if (preliminaryTestingRequested.length > 0) {
47868
- logger.log(
47869
- `${source_default.cyan("Creating split tasks for Preliminary Testing Requested...")}`
47870
- );
47882
+ if (summary.length === 0) {
47883
+ logger.log(` ${source_default.green("Nothing to do")}`);
47871
47884
  }
47872
47885
  for (const issue2 of preliminaryTestingRequested) {
47873
47886
  if (!issue2.key) {
@@ -47875,11 +47888,6 @@ async function runAuto(options) {
47875
47888
  }
47876
47889
  await jira.createTasks(issue2.key, [jira.preliminaryTestingTask.value]);
47877
47890
  }
47878
- if (preliminaryTestingFailed.length > 0) {
47879
- logger.log(
47880
- `${source_default.red("Closing Preliminary Testing Task - Testing Failed...")}`
47881
- );
47882
- }
47883
47891
  for (const issue2 of preliminaryTestingFailed) {
47884
47892
  if (!issue2.key) {
47885
47893
  continue;
@@ -47891,23 +47899,31 @@ async function runAuto(options) {
47891
47899
  );
47892
47900
  if (!preliminaryTestingTask || !preliminaryTestingTask.outwardIssue?.key) {
47893
47901
  logger.log(
47894
- `${source_default.red("Preliminary Testing Task not found")} - ${issue2.key}`
47902
+ ` ${source_default.red("Preliminary Testing Task not found")} - ${issue2.key}`
47895
47903
  );
47896
47904
  continue;
47897
47905
  }
47898
47906
  await jira.closeTask(preliminaryTestingTask.outwardIssue?.key);
47899
47907
  }
47900
- if (issuesInIntegration.length > 0) {
47901
- logger.log(
47902
- `${source_default.cyan("Creating split tasks for Issues in Integration w/o QE Task...")}`
47903
- );
47904
- }
47905
47908
  for (const issue2 of issuesInIntegration) {
47906
47909
  if (!issue2.key) {
47907
47910
  continue;
47908
47911
  }
47909
47912
  await jira.createTasks(issue2.key, [jira.qeTask.value]);
47910
47913
  }
47914
+ for (const issue2 of issuesInReleasePending) {
47915
+ if (!issue2.key) {
47916
+ continue;
47917
+ }
47918
+ const qeTask = issue2.fields?.issuelinks?.find(
47919
+ (l) => l.type?.outward === "split to" && l.outwardIssue?.fields?.summary.startsWith(jira.qeTask.summary) && l.outwardIssue?.fields?.status.name !== "Closed"
47920
+ );
47921
+ if (!qeTask || !qeTask.outwardIssue?.key) {
47922
+ logger.log(` ${source_default.red("QE Task not found")} - ${issue2.key}`);
47923
+ continue;
47924
+ }
47925
+ await jira.closeTask(qeTask.outwardIssue?.key);
47926
+ }
47911
47927
  process.exit(0);
47912
47928
  }
47913
47929
 
@@ -48014,7 +48030,7 @@ var issueStatusSchema = external_exports.union([
48014
48030
  // src/cli.ts
48015
48031
  function cli() {
48016
48032
  const program2 = new Command();
48017
- program2.name("jira-sprinter").description("\u{1F3C3} Small CLI tool to manage sprints in JIRA Board").version("2.2.0");
48033
+ program2.name("jira-sprinter").description("\u{1F3C3} Small CLI tool to manage sprints in JIRA Board").version("2.3.0");
48018
48034
  program2.addCommand(
48019
48035
  new Command("auto").description(
48020
48036
  "Automatically manages split tasks (Preliminary Testing and QE) based on ticket state and status"
@@ -48074,7 +48090,7 @@ var runProgram = async () => {
48074
48090
  issues = await jira.getIssuesInSprint(sprintOrBacklog, options.assignee);
48075
48091
  }
48076
48092
  if (issues.length === 0) {
48077
- logger.log(`${source_default.green("No issues found")}.`);
48093
+ logger.log(source_default.green("No issues found"));
48078
48094
  process.exit(0);
48079
48095
  }
48080
48096
  for (const issue2 of issues) {
@@ -48134,7 +48150,7 @@ ${issueTypeSchema.parse(issue2.fields?.issuetype.name)} ${issue2.key} - ${source
48134
48150
  );
48135
48151
  if (Array.isArray(tasks) && tasks.length >= answer.length) break;
48136
48152
  if (attempt < 10) {
48137
- logger.log(`Waiting for tasks to be created...`);
48153
+ logger.log(source_default.dim("Waiting for tasks to be created..."));
48138
48154
  await new Promise((resolve) => setTimeout(resolve, 5e3));
48139
48155
  }
48140
48156
  }
@@ -48142,7 +48158,7 @@ ${issueTypeSchema.parse(issue2.fields?.issuetype.name)} ${issue2.key} - ${source
48142
48158
  if (task.fields.summary.includes("QE Task")) {
48143
48159
  continue;
48144
48160
  }
48145
- logger.log(`${source_default.italic(task.fields.summary)}`);
48161
+ logger.log(source_default.italic(task.fields.summary));
48146
48162
  let storyPointsAnswer;
48147
48163
  let addToSprintAnswer;
48148
48164
  if (!options.yolo) {
@@ -48197,7 +48213,7 @@ ${issueTypeSchema.parse(issue2.fields?.issuetype.name)} ${issue2.key} - ${source
48197
48213
  storyPointsAnswer = issue2.fields?.[jira.fields.storyPoints];
48198
48214
  addToSprintAnswer = sprintOrBacklog != -1;
48199
48215
  logger.log(
48200
- `Setting story points to ${colorSizeSchema.parse(storyPointsAnswer)} and adding it to the sprint.`
48216
+ ` ${source_default.cyan("Story points")}: ${colorSizeSchema.parse(storyPointsAnswer)}, ${source_default.cyan("Sprint")}: ${addToSprintAnswer ? source_default.green("yes") : source_default.red("no")}`
48201
48217
  );
48202
48218
  }
48203
48219
  await jira.setValues(task.key, {
@@ -48207,7 +48223,7 @@ ${issueTypeSchema.parse(issue2.fields?.issuetype.name)} ${issue2.key} - ${source
48207
48223
  });
48208
48224
  }
48209
48225
  logger.log(
48210
- `Dropping ${source_default.bold(issue2.key)} from sprint and setting story points to ${source_default.bold(0)}...`
48226
+ `${source_default.dim(`Resetting ${issue2.key} \u2014 story points \u2192 0, removing from sprint`)}`
48211
48227
  );
48212
48228
  await jira.setValues(issue2.key, { size: 0, sprint: null });
48213
48229
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jira-sprinter",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "Small CLI tool to manage sprints in JIRA Board",
5
5
  "main": "src/main.ts",
6
6
  "type": "commonjs",
package/src/auto.ts CHANGED
@@ -9,9 +9,13 @@ export async function runAuto(options: OptionValues): Promise<void> {
9
9
 
10
10
  const jira = await Jira.getInstance(options.dry, logger, options.assignee);
11
11
 
12
+ logger.log(
13
+ `${chalk.cyan(`Verifying issues in board ${options.board} - team: ${options.team}`)}`
14
+ );
15
+
12
16
  const boardIssues = await jira.getBoardIssues(
13
17
  options.board,
14
- `project = RHEL and issuetype in (Bug, Story, Vulnerability) and statusCategory != Done`
18
+ `project = RHEL and issuetype in (Bug, Story, Vulnerability) and status != Closed`
15
19
  );
16
20
 
17
21
  const preliminaryTestingRequested = boardIssues.filter(
@@ -26,11 +30,6 @@ export async function runAuto(options: OptionValues): Promise<void> {
26
30
  l.outwardIssue?.fields?.status.name !== 'Closed'
27
31
  )
28
32
  );
29
- if (preliminaryTestingRequested.length > 0) {
30
- logger.log(
31
- `${chalk.green('Preliminary Testing Requested')} - ${preliminaryTestingRequested.length}`
32
- );
33
- }
34
33
 
35
34
  const preliminaryTestingFailed = boardIssues.filter(
36
35
  issue =>
@@ -44,11 +43,6 @@ export async function runAuto(options: OptionValues): Promise<void> {
44
43
  l.outwardIssue?.fields?.status.name !== 'Closed'
45
44
  )
46
45
  );
47
- if (preliminaryTestingFailed.length > 0) {
48
- logger.log(
49
- `${chalk.red('Preliminary Testing Failed')} - ${preliminaryTestingFailed.length}`
50
- );
51
- }
52
46
 
53
47
  const issuesInIntegration = boardIssues.filter(
54
48
  issue =>
@@ -60,16 +54,40 @@ export async function runAuto(options: OptionValues): Promise<void> {
60
54
  l.outwardIssue?.fields?.status.name !== 'Closed'
61
55
  )
62
56
  );
63
- if (issuesInIntegration.length > 0) {
64
- logger.log(
65
- `${chalk.yellow('Issues in Integration w/o QE Task')} - ${issuesInIntegration.length}`
66
- );
57
+
58
+ const issuesInReleasePending = boardIssues.filter(
59
+ issue =>
60
+ issue.fields?.status.name === 'Release Pending' &&
61
+ issue.fields?.issuelinks?.some(
62
+ l =>
63
+ l.type?.outward === 'split to' &&
64
+ l.outwardIssue?.fields?.summary.startsWith(jira.qeTask.summary) &&
65
+ l.outwardIssue?.fields?.status.name !== 'Closed'
66
+ )
67
+ );
68
+
69
+ const summary = [
70
+ {
71
+ label: 'Preliminary Testing Requested',
72
+ count: preliminaryTestingRequested.length,
73
+ },
74
+ {
75
+ label: 'Preliminary Testing Failed',
76
+ count: preliminaryTestingFailed.length,
77
+ },
78
+ { label: 'Integration w/o QE Task', count: issuesInIntegration.length },
79
+ {
80
+ label: 'Release Pending w/ QE Task',
81
+ count: issuesInReleasePending.length,
82
+ },
83
+ ].filter(entry => entry.count > 0);
84
+
85
+ for (const { label, count } of summary) {
86
+ logger.log(` ${chalk.cyan(label)}: ${chalk.bold(count)}`);
67
87
  }
68
88
 
69
- if (preliminaryTestingRequested.length > 0) {
70
- logger.log(
71
- `${chalk.cyan('Creating split tasks for Preliminary Testing Requested...')}`
72
- );
89
+ if (summary.length === 0) {
90
+ logger.log(` ${chalk.green('Nothing to do')}`);
73
91
  }
74
92
 
75
93
  for (const issue of preliminaryTestingRequested) {
@@ -80,12 +98,6 @@ export async function runAuto(options: OptionValues): Promise<void> {
80
98
  await jira.createTasks(issue.key, [jira.preliminaryTestingTask.value]);
81
99
  }
82
100
 
83
- if (preliminaryTestingFailed.length > 0) {
84
- logger.log(
85
- `${chalk.red('Closing Preliminary Testing Task - Testing Failed...')}`
86
- );
87
- }
88
-
89
101
  for (const issue of preliminaryTestingFailed) {
90
102
  if (!issue.key) {
91
103
  continue;
@@ -102,7 +114,7 @@ export async function runAuto(options: OptionValues): Promise<void> {
102
114
 
103
115
  if (!preliminaryTestingTask || !preliminaryTestingTask.outwardIssue?.key) {
104
116
  logger.log(
105
- `${chalk.red('Preliminary Testing Task not found')} - ${issue.key}`
117
+ ` ${chalk.red('Preliminary Testing Task not found')} - ${issue.key}`
106
118
  );
107
119
  continue;
108
120
  }
@@ -110,12 +122,6 @@ export async function runAuto(options: OptionValues): Promise<void> {
110
122
  await jira.closeTask(preliminaryTestingTask.outwardIssue?.key);
111
123
  }
112
124
 
113
- if (issuesInIntegration.length > 0) {
114
- logger.log(
115
- `${chalk.cyan('Creating split tasks for Issues in Integration w/o QE Task...')}`
116
- );
117
- }
118
-
119
125
  for (const issue of issuesInIntegration) {
120
126
  if (!issue.key) {
121
127
  continue;
@@ -124,5 +130,25 @@ export async function runAuto(options: OptionValues): Promise<void> {
124
130
  await jira.createTasks(issue.key, [jira.qeTask.value]);
125
131
  }
126
132
 
133
+ for (const issue of issuesInReleasePending) {
134
+ if (!issue.key) {
135
+ continue;
136
+ }
137
+
138
+ const qeTask = issue.fields?.issuelinks?.find(
139
+ l =>
140
+ l.type?.outward === 'split to' &&
141
+ l.outwardIssue?.fields?.summary.startsWith(jira.qeTask.summary) &&
142
+ l.outwardIssue?.fields?.status.name !== 'Closed'
143
+ );
144
+
145
+ if (!qeTask || !qeTask.outwardIssue?.key) {
146
+ logger.log(` ${chalk.red('QE Task not found')} - ${issue.key}`);
147
+ continue;
148
+ }
149
+
150
+ await jira.closeTask(qeTask.outwardIssue?.key);
151
+ }
152
+
127
153
  process.exit(0);
128
154
  }
package/src/cli.ts CHANGED
@@ -24,7 +24,7 @@ export function cli(): Command {
24
24
  program
25
25
  .name('jira-sprinter')
26
26
  .description('🏃 Small CLI tool to manage sprints in JIRA Board')
27
- .version('2.2.0');
27
+ .version('2.3.0');
28
28
 
29
29
  program.addCommand(
30
30
  new Command('auto')
@@ -106,7 +106,7 @@ const runProgram = async () => {
106
106
  }
107
107
 
108
108
  if (issues.length === 0) {
109
- logger.log(`${chalk.green('No issues found')}.`);
109
+ logger.log(chalk.green('No issues found'));
110
110
  process.exit(0);
111
111
  }
112
112
 
@@ -179,7 +179,7 @@ const runProgram = async () => {
179
179
 
180
180
  if (Array.isArray(tasks) && tasks.length >= answer.length) break;
181
181
  if (attempt < 10) {
182
- logger.log(`Waiting for tasks to be created...`);
182
+ logger.log(chalk.dim('Waiting for tasks to be created...'));
183
183
  await new Promise(resolve => setTimeout(resolve, 5000));
184
184
  }
185
185
  }
@@ -190,7 +190,7 @@ const runProgram = async () => {
190
190
  continue;
191
191
  }
192
192
 
193
- logger.log(`${chalk.italic(task.fields.summary)}`);
193
+ logger.log(chalk.italic(task.fields.summary));
194
194
 
195
195
  let storyPointsAnswer: Size | undefined;
196
196
  let addToSprintAnswer: boolean | undefined;
@@ -248,7 +248,7 @@ const runProgram = async () => {
248
248
  storyPointsAnswer = issue.fields?.[jira.fields.storyPoints];
249
249
  addToSprintAnswer = sprintOrBacklog != -1;
250
250
  logger.log(
251
- `Setting story points to ${colorSizeSchema.parse(storyPointsAnswer)} and adding it to the sprint.`
251
+ ` ${chalk.cyan('Story points')}: ${colorSizeSchema.parse(storyPointsAnswer)}, ${chalk.cyan('Sprint')}: ${addToSprintAnswer ? chalk.green('yes') : chalk.red('no')}`
252
252
  );
253
253
  }
254
254
 
@@ -263,7 +263,7 @@ const runProgram = async () => {
263
263
  }
264
264
 
265
265
  logger.log(
266
- `Dropping ${chalk.bold(issue.key)} from sprint and setting story points to ${chalk.bold(0)}...`
266
+ `${chalk.dim(`Resetting ${issue.key} story points 0, removing from sprint`)}`
267
267
  );
268
268
  await jira.setValues(issue.key!, { size: 0, sprint: null });
269
269
  }
package/src/jira.ts CHANGED
@@ -2,6 +2,8 @@ import { AgileClient, Version3Client } from 'jira.js';
2
2
  import { SearchResults, Sprint } from 'jira.js/dist/esm/types/agile/models';
3
3
  import { Issue } from 'jira.js/dist/esm/types/version3/models/issue';
4
4
 
5
+ import chalk from 'chalk';
6
+
5
7
  import { raise, tokenUnavailable } from './util';
6
8
  import { Size } from './schema/jira';
7
9
  import { Logger } from './logger';
@@ -194,7 +196,9 @@ export class Jira {
194
196
 
195
197
  async getlinkedTasks(issue: string, expectedTasks: string[]) {
196
198
  if (this.dry) {
197
- this.logger.log(`Would get linked tasks for issue: ${issue}`);
199
+ this.logger.log(
200
+ ` ${chalk.dim(`Fetching linked tasks for ${issue} (dry-run)`)}`
201
+ );
198
202
  return [
199
203
  {
200
204
  key: 'RHEL-1234',
@@ -237,12 +241,14 @@ export class Jira {
237
241
  async createTasks(issue: string, tasks: string[]) {
238
242
  if (this.dry) {
239
243
  this.logger.log(
240
- `Would create tasks: ${tasks.join(', ')} for issue: ${issue}`
244
+ ` ${chalk.dim(`Creating tasks ${tasks.join(', ')} for ${issue} (dry-run)`)}`
241
245
  );
242
246
  return;
243
247
  }
244
248
 
245
- this.logger.log(`Creating tasks: ${tasks.join(', ')} for issue: ${issue}`);
249
+ this.logger.log(
250
+ ` ${chalk.cyan(`Creating tasks ${tasks.join(', ')} for ${issue}`)}`
251
+ );
246
252
  await this.api.issues.editIssue({
247
253
  issueIdOrKey: issue,
248
254
  fields: {
@@ -254,11 +260,11 @@ export class Jira {
254
260
 
255
261
  async closeTask(issue: string) {
256
262
  if (this.dry) {
257
- this.logger.log(`Would close task: ${issue}`);
263
+ this.logger.log(` ${chalk.dim(`Closing task ${issue} (dry-run)`)}`);
258
264
  return;
259
265
  }
260
266
 
261
- this.logger.log(`Closing task: ${issue}`);
267
+ this.logger.log(` ${chalk.cyan(`Closing task ${issue}`)}`);
262
268
 
263
269
  await this.api.issues.doTransition({
264
270
  issueIdOrKey: issue,
@@ -310,7 +316,7 @@ export class Jira {
310
316
  );
311
317
 
312
318
  const version = await instance.getVersion();
313
- console.debug(`JIRA Version: ${version}`);
319
+ logger.log(chalk.dim(`JIRA v${version}`));
314
320
 
315
321
  return instance;
316
322
  }