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 +1 -0
- package/dist/main.js +58 -42
- package/package.json +1 -1
- package/src/auto.ts +58 -32
- package/src/cli.ts +6 -6
- package/src/jira.ts +12 -6
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(
|
|
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
|
-
`
|
|
47757
|
+
` ${source_default.dim(`Creating tasks ${tasks.join(", ")} for ${issue2} (dry-run)`)}`
|
|
47756
47758
|
);
|
|
47757
47759
|
return;
|
|
47758
47760
|
}
|
|
47759
|
-
this.logger.log(
|
|
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(`
|
|
47774
|
+
this.logger.log(` ${source_default.dim(`Closing task ${issue2} (dry-run)`)}`);
|
|
47771
47775
|
return;
|
|
47772
47776
|
}
|
|
47773
|
-
this.logger.log(`Closing task
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
47863
|
-
|
|
47864
|
-
|
|
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 (
|
|
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
|
-
|
|
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.
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
`
|
|
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
|
-
`
|
|
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
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
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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 (
|
|
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
|
-
|
|
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.
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
`
|
|
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
|
-
`
|
|
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(
|
|
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
|
-
`
|
|
244
|
+
` ${chalk.dim(`Creating tasks ${tasks.join(', ')} for ${issue} (dry-run)`)}`
|
|
241
245
|
);
|
|
242
246
|
return;
|
|
243
247
|
}
|
|
244
248
|
|
|
245
|
-
this.logger.log(
|
|
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(`
|
|
263
|
+
this.logger.log(` ${chalk.dim(`Closing task ${issue} (dry-run)`)}`);
|
|
258
264
|
return;
|
|
259
265
|
}
|
|
260
266
|
|
|
261
|
-
this.logger.log(`Closing task
|
|
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
|
-
|
|
319
|
+
logger.log(chalk.dim(`JIRA v${version}`));
|
|
314
320
|
|
|
315
321
|
return instance;
|
|
316
322
|
}
|