Codebase list libjira-rest-perl / fe9048f
Update upstream source from tag 'upstream/0.019' Update to upstream version '0.019' with Debian dir 25dcdd40ec1dd507bc30c6e68f636e9bf2dc9003 gregor herrmann 5 years ago
17 changed file(s) with 638 addition(s) and 78 deletion(s). Raw diff Collapse all Expand all
00 Revision history for perl module JIRA-REST. -*- text -*-
1
2 0.019 2018-07-28 18:00:17-03:00 America/Sao_Paulo
3
4 [Changes]
5
6 - JIRA::REST now requires at least Perl 5.10. Previously it required Perl
7 5.8. A new section in the documentation explains our Perl and Jira
8 compatibility Policy.
9
10 [Fixes]
11
12 - William Carr fixed the sub_error routine teaching it yet another way Jira
13 can pass error messages back.
14
15 [Documentation]
16
17 - Lisa Hare graciously contributed some example scripts which can be found on
18 the 'examples' directory.
19
20 - All mentions of 'JIRA' were changed to 'Jira', following the change
21 Atlassian made in all of its site and documentation.
122
223 0.018 2017-05-30 09:38:37-03:00 America/Sao_Paulo
324
0 This software is copyright (c) 2017 by CPqD <www.cpqd.com.br>.
0 This software is copyright (c) 2018 by CPqD <www.cpqd.com.br>.
11
22 This is free software; you can redistribute it and/or modify it under
33 the same terms as the Perl 5 programming language system itself.
1111
1212 --- The GNU General Public License, Version 1, February 1989 ---
1313
14 This software is Copyright (c) 2017 by CPqD <www.cpqd.com.br>.
14 This software is Copyright (c) 2018 by CPqD <www.cpqd.com.br>.
1515
1616 This is free software, licensed under:
1717
271271
272272 --- The Artistic License 1.0 ---
273273
274 This software is Copyright (c) 2017 by CPqD <www.cpqd.com.br>.
274 This software is Copyright (c) 2018 by CPqD <www.cpqd.com.br>.
275275
276276 This is free software, licensed under:
277277
0 # This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.043.
0 # This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.009.
11 Changes
22 LICENSE
33 MANIFEST
66 Makefile.PL
77 README.pod
88 dist.ini
9 examples/create_issue.pl
10 examples/edit_issue.pl
11 examples/lib/JIRACLI.pm
12 examples/search.pl
13 examples/transition.pl
914 lib/JIRA/REST.pm
1015 t/00-load.t
1116 t/01-atlassian.t
00 {
1 "abstract" : "Thin wrapper around JIRA's REST API",
1 "abstract" : "Thin wrapper around Jira's REST API",
22 "author" : [
33 "Gustavo L. de M. Chaves <gnustavo@cpan.org>"
44 ],
55 "dynamic_config" : 0,
6 "generated_by" : "Dist::Zilla version 5.043, CPAN::Meta::Converter version 2.150001",
6 "generated_by" : "Dist::Zilla version 6.009, CPAN::Meta::Converter version 2.150010",
77 "license" : [
88 "perl_5"
99 ],
3434 "requires" : {
3535 "Carp" : "0",
3636 "Config::Identity" : "0.0019",
37 "Encode" : "0",
3738 "HTML::TreeBuilder" : "0",
3839 "HTTP::Status" : "0",
39 "JSON" : "0",
40 "JSON" : "2.23",
4041 "MIME::Base64" : "0",
4142 "Net::Netrc" : "0",
4243 "REST::Client" : "0",
4344 "URI" : "0",
4445 "URI::Escape" : "0",
45 "perl" : "5.008_008",
46 "perl" : "5.010",
4647 "strict" : "0",
4748 "utf8" : "0",
4849 "warnings" : "0"
6465 "web" : "https://github.com/gnustavo/jira-rest"
6566 }
6667 },
67 "version" : "0.018"
68 "version" : "0.019",
69 "x_serialization_backend" : "Cpanel::JSON::XS version 4.02"
6870 }
6971
00 ---
1 abstract: "Thin wrapper around JIRA's REST API"
1 abstract: "Thin wrapper around Jira's REST API"
22 author:
33 - 'Gustavo L. de M. Chaves <gnustavo@cpan.org>'
44 build_requires:
77 configure_requires:
88 ExtUtils::MakeMaker: '0'
99 dynamic_config: 0
10 generated_by: 'Dist::Zilla version 5.043, CPAN::Meta::Converter version 2.150001'
10 generated_by: 'Dist::Zilla version 6.009, CPAN::Meta::Converter version 2.150010'
1111 license: perl
1212 meta-spec:
1313 url: http://module-build.sourceforge.net/META-spec-v1.4.html
1919 requires:
2020 Carp: '0'
2121 Config::Identity: '0.0019'
22 Encode: '0'
2223 HTML::TreeBuilder: '0'
2324 HTTP::Status: '0'
24 JSON: '0'
25 JSON: '2.23'
2526 MIME::Base64: '0'
2627 Net::Netrc: '0'
2728 REST::Client: '0'
2829 URI: '0'
2930 URI::Escape: '0'
30 perl: 5.008_008
31 perl: '5.010'
3132 strict: '0'
3233 utf8: '0'
3334 warnings: '0'
3435 resources:
3536 homepage: https://metacpan.org/module/JIRA::REST
3637 repository: https://github.com/gnustavo/JIRA-REST.git
37 version: '0.018'
38 version: '0.019'
39 x_serialization_backend: 'YAML::Tiny version 1.70'
0 # This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.043.
0 # This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.009.
11 use strict;
22 use warnings;
33
4 use 5.008_008;
4 use 5.010;
55
66 use ExtUtils::MakeMaker;
77
88 my %WriteMakefileArgs = (
9 "ABSTRACT" => "Thin wrapper around JIRA's REST API",
9 "ABSTRACT" => "Thin wrapper around Jira's REST API",
1010 "AUTHOR" => "Gustavo L. de M. Chaves <gnustavo\@cpan.org>",
1111 "CONFIGURE_REQUIRES" => {
1212 "ExtUtils::MakeMaker" => 0
1313 },
1414 "DISTNAME" => "JIRA-REST",
1515 "LICENSE" => "perl",
16 "MIN_PERL_VERSION" => "5.008_008",
16 "MIN_PERL_VERSION" => "5.010",
1717 "NAME" => "JIRA::REST",
1818 "PREREQ_PM" => {
1919 "Carp" => 0,
2020 "Config::Identity" => "0.0019",
21 "Encode" => 0,
2122 "HTML::TreeBuilder" => 0,
2223 "HTTP::Status" => 0,
23 "JSON" => 0,
24 "JSON" => "2.23",
2425 "MIME::Base64" => 0,
2526 "Net::Netrc" => 0,
2627 "REST::Client" => 0,
3435 "Test::More" => 0,
3536 "lib" => 0
3637 },
37 "VERSION" => "0.018",
38 "VERSION" => "0.019",
3839 "test" => {
3940 "TESTS" => "t/*.t"
4041 }
4445 my %FallbackPrereqs = (
4546 "Carp" => 0,
4647 "Config::Identity" => "0.0019",
48 "Encode" => 0,
4749 "HTML::TreeBuilder" => 0,
4850 "HTTP::Status" => 0,
49 "JSON" => 0,
51 "JSON" => "2.23",
5052 "MIME::Base64" => 0,
5153 "Net::Netrc" => 0,
5254 "REST::Client" => 0,
00 =pod
11
2 JIRA::REST - Thin wrapper around JIRA's REST APIs
2 JIRA::REST - Thin wrapper around Jira's REST APIs
33
4 L<JIRA|http://www.atlassian.com/software/jira> is a proprietary bug
4 L<Jira|http://www.atlassian.com/software/jira> is a proprietary bug
55 tracking system from
66 L<Atlassian|http://www.atlassian.com/software/jira/>.
77
8 This module implements a thin wrapper around JIRA's REST APIs:
8 This module implements a thin wrapper around Jira's REST APIs:
99
1010 =over
1111
12 =item * L<JIRA Core REST API|https://docs.atlassian.com/jira/REST/server/>
12 =item * L<Jira Core REST API|https://docs.atlassian.com/jira/REST/server/>
1313
14 This rich API superseded the old L<JIRA SOAP
14 This rich API superseded the old L<Jira SOAP
1515 API|http://docs.atlassian.com/software/jira/docs/api/rpc-jira-plugin/latest/com/atlassian/jira/rpc/soap/JiraSoapService.html>
16 which isn't supported anymore as of JIRA version 7.
16 which isn't supported anymore as of Jira version 7.
1717
18 =item * L<JIRA Service Desk REST API|https://docs.atlassian.com/jira-servicedesk/REST/server/>
18 =item * L<Jira Service Desk REST API|https://docs.atlassian.com/jira-servicedesk/REST/server/>
1919
20 This API deals with the objects of the JIRA Service Desk application.
20 This API deals with the objects of the Jira Service Desk application.
2121
22 =item * L<JIRA Software REST API|https://docs.atlassian.com/jira-software/REST/server/>
22 =item * L<Jira Software REST API|https://docs.atlassian.com/jira-software/REST/server/>
2323
24 This API deals with the objects of the JIRA Software application.
24 This API deals with the objects of the Jira Software application.
2525
2626 =back
2727
28 Copyright (c) 2013-2016 by CPqD (http://www.cpqd.com.br/)
28 Copyright (c) 2013-2018 by CPqD (http://www.cpqd.com.br/)
2929
3030 This is free software; you can redistribute it and/or modify it under
3131 the same terms as the Perl 5 programming language system itself.
0 #!/usr/bin/env perl
1
2 use 5.010;
3 use utf8;
4 use strict;
5 use warnings;
6 use FindBin;
7 use lib "$FindBin::Bin/lib";
8 use Getopt::Long::Descriptive;
9 use JIRACLI qw/get_credentials/;
10
11 my ($opt, $usage) = describe_options(
12 '%c %o',
13 ['jiraurl=s', "JIRA server base URL", {default => 'https://jira.cpqd.com.br'}],
14 ['project|p=s', "Project to create issue under", {required => 1}],
15 ['summary|s=s', "Issue summary", {required => 1}],
16 ['description|d=s', "Issue description", {required => 1}],
17 ['help|h', "Print usage message and exit"],
18 {show_defaults => 1},
19 );
20
21 if ($opt->help) {
22 print $usage->text;
23 exit 0;
24 }
25
26 my $jira = JIRA::REST->new(
27 $opt->jiraurl,
28 get_credentials(),
29 );
30
31 my $data = {
32 fields => {
33 project => {
34 key => $opt->project
35 },
36 summary => $opt->summary,
37 description => $opt->description,
38 issuetype => {
39 name => 'Bug'
40 }
41 }
42 };
43
44 my $res = $jira->POST('/issue', undef, $data);
45
46 print "Issue created ID: $res->{id}\n";
47
48 __END__
49 =encoding utf8
50
51 =head1 NAME
52
53 create_issue.pl - Creates an issue
54
55 =head1 SYNOPSIS
56
57 create_issue.pl [-hn] [long options...]
58 --jiraurl STR JIRA server base URL
59 (default value: https://jira.cpqd.com.br)
60 --project STR The project key
61 --summary STR Issue Summary
62 --description Issue Description
63 -h --help Print usage message and exit
64
65 =head1 DESCRIPTION
66
67 This script creates an issue
68
69 =back
70
71 =head1 ENVIRONMENT
72
73 See the L<JIRACLI> documentation.
74
75 =head1 COPYRIGHT
76
77 Copyright 2016 CPqD.
78
79 This program is free software; you can redistribute it and/or modify
80 it under the same terms as Perl itself.
81
82 =head1 AUTHOR
83
84 Lisa Hare <lharey@gmail.com>
0 #!/usr/bin/env perl
1
2 use 5.010;
3 use utf8;
4 use strict;
5 use warnings;
6 use FindBin;
7 use lib "$FindBin::Bin/lib";
8 use Getopt::Long::Descriptive;
9 use JIRACLI qw/get_credentials/;
10
11 my ($opt, $usage) = describe_options(
12 '%c %o',
13 ['jiraurl=s', "JIRA server base URL", {default => 'https://jira.cpqd.com.br'}],
14 ['issue|i=s', "Key of the issue to progress", {required => 1}],
15 ['assign|a=s@', "Set of KEY[.ATTR]=VALUE assignments to perform", { required => 1 }],
16 ['nonotify', "Supress email notification about the change."],
17 ['help|h', "Print usage message and exit"],
18 {show_defaults => 1},
19 );
20
21 if ($opt->help) {
22 print $usage->text;
23 exit 0;
24 }
25
26 my $jira = JIRA::REST->new(
27 $opt->jiraurl,
28 get_credentials(),
29 );
30
31 my %assignments;
32 foreach my $assign (@{$opt->assign}) {
33 if (my ($key, $value) = ($assign =~ /(.+?)=(.+)/)) {
34 if (my ($kkey, $attr) = ($key =~ /(.+?)\.(.+)/)) {
35 if (!$assignments{$kkey}) {
36 $assignments{$kkey} = {};
37 }
38 $assignments{$kkey}{$attr} = $value;
39 } else {
40 $assignments{$key} = $value;
41 }
42 } else {
43 die "Invalid assignment specification: $assign";
44 }
45 }
46
47 my $data = { fields => \%assignments };
48 $data->{notifyUsers} = 'false' if $opt->nonotify;
49
50 $jira->PUT("/issue/@{[$opt->issue]}", undef, $data);
51
52 __END__
53 =encoding utf8
54
55 =head1 NAME
56
57 edit_issue.pl - Edit a JIRA issue
58
59 =head1 SYNOPSIS
60
61 edit.pl [-h] [long options...]
62 --jiraurl STR JIRA server base URL
63 (default value: https://jira.cpqd.com.br)
64 --issue STR Key of the issue to progress
65 --assign STR... Set of KEY[.ATTR]=VALUE assignments to perform
66 --nonotify Supress email notification about the change.
67 -h --help Print usage message and exit
68
69 =head1 DESCRIPTION
70
71 This script edits a JIRA issue, changing its fields.
72
73 =head1 OPTIONS
74
75 Common options are specified in the L<JIRACLI> documentation. Specific
76 options are defined below:
77
78 =over
79
80 =item * B<--issue STR>
81
82 Specifies the issue by its key (e.g. HD-1234).
83
84 =item * B<--assign STR...>
85
86 This multi-valued option specifies which fields are to be changed.
87
88 Numeric, date, or string fields can be specified like this:
89
90 --assign="summary=New summary"
91 --assign="duedate=2017-01-01"
92
93 Structured fields may need the name of an attribute to be assigned:
94
95 --assign="assignee.name=gustavo"
96 --assign="assignee.emailAddress=gustavo@cpqd.com.br"
97
98 =item * B<--nonotify>
99
100 By default JIRA sends email notifications to all parties involved in an
101 issue when it's changed. This option supresses those notifications. However,
102 admin or project admin permissions are required to disable the notification.
103
104 =back
105
106 =head1 ENVIRONMENT
107
108 See the L<JIRACLI> documentation.
109
110 =head1 COPYRIGHT
111
112 Copyright 2016 CPqD.
113
114 This program is free software; you can redistribute it and/or modify
115 it under the same terms as Perl itself.
116
117 =head1 AUTHOR
118
119 Gustavo Chaves <gustavo@cpqd.com.br>
120 Lisa Hare <lharey@gmail.com>
0 #!/usr/bin/env perl
1
2 use 5.010;
3 use utf8;
4 use strict;
5 use warnings;
6
7 package JIRACLI;
8
9 use JIRA::REST;
10
11 use vars qw($VERSION @ISA @EXPORT_OK);
12
13 require Exporter;
14
15 @ISA = qw(Exporter);
16 @EXPORT_OK = qw(get_credentials);
17 $VERSION = '0.01';
18
19 sub get_credentials {
20
21 my ($user, $pass) = @ENV{'jirauser', 'jirapass'};
22
23 return ($user, $pass) if defined $user && defined $pass;
24
25 if (! -t STDIN) {
26 die "Cannot prompt user for credentials because STDIN isn't a terminal. Please set environment variables jirauser and jirapass\n";
27 }
28
29 require Term::Prompt;
30 Term::Prompt->import();
31
32 if (!defined $user) {
33 $user = prompt('x', "Enter Username: ", '', '');
34 }
35
36 if (! defined $pass) {
37 $pass = prompt('p', "Enter Password: ", '', '');
38 print "\n";
39 }
40
41 return ($user, $pass);
42 }
43
44 1;
45 __END__
46 =encoding utf8
47
48 =head1 NAME
49
50 JIRACLI - Common utilities for all JIRA CLI examples
51
52 =head1 SYNOPSIS
53
54 use lib $FindBin::Bin;
55 use JIRACLI;
56
57 =head1 DESCRIPTION
58
59 This module contains a few functions used by most of the JIRA CLI examples
60
61 =head1 FUNCTIONS
62
63 =head2 get_credentials
64
65 my ($user, $pass) = get_credentials();
66
67 This function will first check for user and password specified in the
68 environment variables jirauser and jirpass.
69
70 If no environment variables set will prompt interactively for entry of user and password
71
72 =over
73
74 =head1 COPYRIGHT
75
76 Copyright 2016 CPqD.
77
78 This program is free software; you can redistribute it and/or modify
79 it under the same terms as Perl itself.
80
81 =head1 AUTHOR
82
83 Gustavo Chaves <gustavo@cpqd.com.br>
0 #!/usr/bin/env perl
1
2 # perl -Ilib examples/search.pl --jiraurl https://lharey.atlassian.net --jql "assignee = 'Lisa Hare'"
3
4 use 5.010;
5 use strict;
6 use warnings;
7 use FindBin;
8 use lib "$FindBin::Bin/lib";
9 use Getopt::Long::Descriptive;
10 use JIRACLI qw/get_credentials/;
11
12
13 my ($opt, $usage) = describe_options(
14 '%c %o',
15 ['jiraurl=s', "JIRA server base URL", {default => 'https://jira.cpqd.com.br'}],
16 ['jql=s', "JQL query expression", {required => 1}],
17 ['help|h', "Print usage message and exit"],
18 {show_defaults => 1},
19 );
20
21 if ($opt->help) {
22 print $usage->text;
23 exit 0;
24 }
25
26 my $jira = JIRA::REST->new(
27 $opt->jiraurl,
28 get_credentials(),
29 );
30
31 $jira->set_search_iterator({
32 jql => $opt->jql,
33 fields => [qw/summary issuetype status priority assignee reporter/],
34 });
35
36 while (my $issue = $jira->next_issue) {
37 my $fields = $issue->{fields};
38 print "ID: $issue->{id}\n";
39 print "Summary: $fields->{summary}\n";
40 print "Type: $fields->{issuetype}{name}\n";
41 print "Status: $fields->{status}{name}\n";
42 print "Priority: $fields->{priority}{name}\n";
43 print "Assignee: $fields->{assignee}{name}\n";
44 print "Reporter: $fields->{reporter}{name}\n\n";
45 }
46
47 __END__
48
49 =head1 NAME
50
51 search.pl - Search JIRA issues by a JQL filter
52
53 =head1 SYNOPSIS
54
55 search.pl [-hn] [long options...]
56 --jiraurl STR JIRA server base URL
57 (default value: https://jira.cpqd.com.br)
58 --jql STR JQL query expression
59 -h --help Print usage message and exit
60
61 =head1 DESCRIPTION
62
63 This script searches JIRA issues by a JQL filter, printing their keys on
64 STDOUT, one per line, or more information about them, depending on the
65 options given.
66
67 =head1 OPTIONS
68
69 =over
70
71 =item * B<--jql STR>
72
73 Specifies the L<JQL
74 expression|https://confluence.atlassian.com/jirasoftwareserver072/advanced-searching-829057400.html>
75 used to search for issues.
76
77 =item * B<--jiraurl STR>
78
79 The JIRA server base url
80
81 =back
82
83 =head1 ENVIRONMENT
84
85 See the L<JIRACLI> documentation.
86
87 =head1 COPYRIGHT
88
89 Copyright 2016 CPqD.
90
91 This program is free software; you can redistribute it and/or modify
92 it under the same terms as Perl itself.
93
94 =head1 AUTHOR
95
96 Gustavo Chaves <gustavo@cpqd.com.br>
97 Lisa Hare <lharey@gmail.com>
0 #!/usr/bin/env perl
1
2 use 5.010;
3 use utf8;
4 use strict;
5 use autodie;
6 use warnings;
7 use FindBin;
8 use lib "$FindBin::Bin/lib";
9 use Getopt::Long::Descriptive;
10 use JIRACLI qw/get_credentials/;
11
12 my ($opt, $usage) = describe_options(
13 '%c %o',
14 ['jiraurl=s', "JIRA server base URL", {default => 'https://jira.cpqd.com.br'}],
15 ['issue|i=s', "Key of the issue to progress", {required => 1}],
16 ['transition-id|t=i', "ID of the transition to make", {required => 1}],
17 ['resolution|r=s', "Resolution name to set"],
18 ['comment|c=s', "Comment string to insert during transition"],
19 ['help|h', "Print usage message and exit"],
20 {show_defaults => 1},
21 );
22
23 if ($opt->help) {
24 print $usage->text;
25 exit 0;
26 }
27
28 my $jira = JIRA::REST->new(
29 $opt->jiraurl,
30 get_credentials(),
31 );
32
33 my $data = {
34 transition => { id => $opt->transition_id },
35 };
36
37 $data->{fields}{resolution} = { name => $opt->resolution } if $opt->resolution;
38 $data->{update}{comment} = [{ add => { body => $opt->comment }}] if $opt->comment;
39
40 $jira->POST("/issue/@{[$opt->issue]}/transitions", undef, $data);
41
42
43 __END__
44 =encoding utf8
45
46 =head1 NAME
47
48 transition.pl - Make a transition in a JIRA issue
49
50 =head1 SYNOPSIS
51
52 transition.pl [-hn] [long options...]
53 --jiraurl STR JIRA server base URL
54 (default value: https://jira.cpqd.com.br)
55 --issue STR Key of the issue to progress
56 --transition-id INT ID of the transition to make
57 --resolution STR Resolution name to set
58 --comment STR Comment string to insert during transition
59 -n --dont Do not change anything
60 -h --help Print usage message and exit
61
62 =head1 DESCRIPTION
63
64 This script makes a JIRA issue transition through its workflow.
65
66 =head1 OPTIONS
67
68 Common options are specified in the L<JIRACLI> documentation. Specific
69 options are defined below:
70
71 =over
72
73 =item * B<--issue STR>
74
75 Specifies the issue by its key (e.g. HD-1234).
76
77 =item * B<--transition-id INT>
78
79 Specifies the transition that should be performed by its numeric ID. You can
80 grok it by hovering the mouse over the transition button and looking for the
81 C<action=N> part in its URL.
82
83 =item * B<--resolution STR>
84
85 If the transition leads to a terminal state you can specify a Resolution to
86 be set.
87
88 =item * B<--comment STR>
89
90 Specifies a comment to be added to the issue during the transition. Note
91 that the comment will not be added if the transition doesn't have a screen
92 associated with it.
93
94 =back
95
96 =head1 ENVIRONMENT
97
98 See the L<JIRACLI> documentation.
99
100 =head1 COPYRIGHT
101
102 Copyright 2016 CPqD.
103
104 This program is free software; you can redistribute it and/or modify
105 it under the same terms as Perl itself.
106
107 =head1 AUTHOR
108
109 Gustavo Chaves <gustavo@cpqd.com.br>
110 Lisa Hare <lharey@gmail.com>
00 package JIRA::REST;
1 # ABSTRACT: Thin wrapper around JIRA's REST API
2 $JIRA::REST::VERSION = '0.018';
3 use 5.008_008;
1 # ABSTRACT: Thin wrapper around Jira's REST API
2 $JIRA::REST::VERSION = '0.019';
3 use 5.010;
44 use utf8;
55 use strict;
66 use warnings;
77
88 use Carp;
99 use URI;
10 use Encode;
1011 use MIME::Base64;
1112 use URI::Escape;
12 use JSON;
13 use JSON 2.23;
1314 use REST::Client;
1415
1516 sub new {
6566 }
6667
6768 for ($args{rest_client_config}) {
68 $_ = {} unless defined;
69 $_ //= {};
6970 croak __PACKAGE__ . "::new: 'rest_client_config' argument must be a hash reference.\n"
7071 unless defined && ref && ref eq 'HASH';
7172 }
7475 # This is deprecated since v0.017
7576 if (my $proxy = delete $args{rest_client_config}{proxy}) {
7677 carp __PACKAGE__ . "::new: passing 'proxy' in the 'rest_client_config' hash is deprecated. Please, use the corresponding argument instead.\n";
77 $args{proxy} = $proxy unless defined $args{proxy};
78 $args{proxy} //= $proxy;
7879 }
7980
8081 my $rest = REST::Client->new($args{rest_client_config});
8586 # Follow redirects/authentication by default
8687 $rest->setFollow(1);
8788
88 # Since JIRA doesn't send an authentication challenge, we force the
89 # Since Jira doesn't send an authentication challenge, we force the
8990 # sending of the authentication header.
9091 $rest->addHeader(Authorization => 'Basic ' . encode_base64("$args{username}:$args{password}"))
9192 unless $args{anonymous};
178179 } elsif ($type =~ m:application/json:) {
179180 my $error = $self->{json}->decode($content);
180181 if (ref $error eq 'HASH') {
181 # JIRA errors may be laid out in all sorts of ways. You have to
182 # Jira errors may be laid out in all sorts of ways. You have to
182183 # look them up from the scant documentation at
183184 # https://docs.atlassian.com/jira/REST/latest/.
184185
195196 if (my $errors = $error->{errors}) {
196197 $msg .= "- [$_] $errors->{$_}\n" foreach sort keys %$errors;
197198 }
199
200 # some give us a single message in 'errorMessage'
201 $msg .= $error->{errorMessage} . qq{\n} if $error->{errorMessage};
198202 } else {
199203 $msg .= $content;
200204 }
274278 $path = $self->_build_path($path, $query);
275279
276280 $headers ||= {};
277 $headers->{'Content-Type'} = 'application/json;charset=UTF-8'
278 unless defined $headers->{'Content-Type'};
281 $headers->{'Content-Type'} //= 'application/json;charset=UTF-8';
279282
280283 $self->{rest}->PUT($path, $self->{json}->encode($value), $headers);
281284
291294 $path = $self->_build_path($path, $query);
292295
293296 $headers ||= {};
294 $headers->{'Content-Type'} = 'application/json;charset=UTF-8'
295 unless defined $headers->{'Content-Type'};
297 $headers->{'Content-Type'} //= 'application/json;charset=UTF-8';
296298
297299 $self->{rest}->POST($path, $self->{json}->encode($value), $headers);
298300
354356 %{$rest->{_headers}},
355357 'X-Atlassian-Token' => 'nocheck',
356358 'Content-Type' => 'form-data',
357 'Content' => [ file => [$file, Encode::encode_utf8( $file )] ],
359 'Content' => [ file => [$file, encode_utf8( $file )] ],
358360 );
359361
360362 $response->is_success
372374
373375 =head1 NAME
374376
375 JIRA::REST - Thin wrapper around JIRA's REST API
377 JIRA::REST - Thin wrapper around Jira's REST API
376378
377379 =head1 VERSION
378380
379 version 0.018
381 version 0.019
380382
381383 =head1 SYNOPSIS
382384
429431
430432 =head1 DESCRIPTION
431433
432 L<JIRA|http://www.atlassian.com/software/jira/> is a proprietary bug
434 L<Jira|http://www.atlassian.com/software/jira/> is a proprietary bug
433435 tracking system from Atlassian.
434436
435 This module implements a very thin wrapper around JIRA's REST APIs:
437 This module implements a very thin wrapper around Jira's REST APIs:
436438
437439 =over
438440
439 =item * L<JIRA Core REST API|https://docs.atlassian.com/jira/REST/server/>
440
441 This rich API superseded the old L<JIRA SOAP
441 =item * L<Jira Core REST API|https://docs.atlassian.com/jira/REST/server/>
442
443 This rich API superseded the old L<Jira SOAP
442444 API|http://docs.atlassian.com/software/jira/docs/api/rpc-jira-plugin/latest/com/atlassian/jira/rpc/soap/JiraSoapService.html>
443 which isn't supported anymore as of JIRA version 7.
445 which isn't supported anymore as of Jira version 7.
444446
445447 The endpoints of this API have a path prefix of C</rest/api/VERSION>.
446448
447 =item * L<JIRA Service Desk REST API|https://docs.atlassian.com/jira-servicedesk/REST/server/>
448
449 This API deals with the objects of the JIRA Service Desk application. Its
449 =item * L<Jira Service Desk REST API|https://docs.atlassian.com/jira-servicedesk/REST/server/>
450
451 This API deals with the objects of the Jira Service Desk application. Its
450452 endpoints have a path prefix of C</rest/servicedeskapi>.
451453
452 =item * L<JIRA Software REST API|https://docs.atlassian.com/jira-software/REST/server/>
453
454 This API deals with the objects of the JIRA Software application. Its
454 =item * L<Jira Software REST API|https://docs.atlassian.com/jira-software/REST/server/>
455
456 This API deals with the objects of the Jira Software application. Its
455457 endpoints have a path prefix of C</rest/agile/VERSION>.
456458
457459 =back
475477
476478 =item * B<url>
477479
478 A string or a URI object denoting the base URL of the JIRA server. This is a
480 A string or a URI object denoting the base URL of the Jira server. This is a
479481 required argument.
480482
481483 The REST methods described below all accept as a first argument the
503505
504506 =item * B<password>
505507
506 The username and password of a JIRA user to use for authentication.
508 The username and password of a Jira user to use for authentication.
507509
508510 If B<anonymous> is false then, if either B<username> or B<password> isn't
509511 defined the module looks them up in either the C<.netrc> file or via
535537
536538 Sets the C<SSL_verify_mode> and C<verify_hostname ssl> options on the
537539 underlying L<REST::Client>'s user agent to 0, thus disabling them. This
538 allows access to JIRA servers that have self-signed certificates that don't
540 allows access to Jira servers that have self-signed certificates that don't
539541 pass L<LWP::UserAgent>'s verification methods.
540542
541543 =item * B<anonymous>
542544
543 Tells the module that you want to connect to the specified JIRA server with
544 no username or password. This way you can access public JIRA servers
545 Tells the module that you want to connect to the specified Jira server with
546 no username or password. This way you can access public Jira servers
545547 without needing to authenticate.
546548
547549 =back
548550
549551 =head1 REST METHODS
550552
551 JIRA's REST API documentation lists dozens of "resources" which can be
553 Jira's REST API documentation lists dozens of "resources" which can be
552554 operated via the standard HTTP requests: GET, DELETE, PUT, and
553555 POST. JIRA::REST objects implement four methods called GET, DELETE,
554 PUT, and POST to make it easier to invoke and get results from JIRA's
556 PUT, and POST to make it easier to invoke and get results from Jira's
555557 REST endpoints.
556558
557559 All four methods need two arguments:
565567 information about an issue you pass
566568 C</rest/servicedeskapi/request/$key/sla>.
567569
568 If you're using a method form JIRA Core REST API you may omit the prefix
570 If you're using a method form Jira Core REST API you may omit the prefix
569571 C</rest/api/VERSION>. For example, to GET the list of all fields you may
570572 pass just C</field>.
571573
597599 L<JSON|http://www.json.org/> string using the C<JSON::encode> method
598600 and sent with a Content-Type of C<application/json>.
599601
600 It's usually easy to infer from the JIRA REST API documentation which
602 It's usually easy to infer from the Jira REST API documentation which
601603 kind of value you should pass to each resource.
602604
603605 This argument is required.
670672 It must be called before calls to B<next_issue>.
671673
672674 PARAMS must conform with the query parameters allowed for the
673 C</rest/api/2/search> JIRA REST endpoint.
675 C</rest/api/2/search> Jira REST endpoint.
674676
675677 =head2 B<next_issue>
676678
690692 just the C<REST::Client> interface. This utility method offers an easier
691693 interface to attach files to issues.
692694
695 =head1 PERL AND JIRA COMPATIBILITY POLICY
696
697 Currently L<JIRA::REST> requires Perl 5.10 and supports Jira 7.0.
698
699 We try to be compatible with the Perl native packages of the oldest L<Ubuntu
700 LTS|https://www.ubuntu.com/info/release-end-of-life> and
701 L<CentOS|https://wiki.centos.org/About/Product> Linux distributions still
702 getting maintainance updates.
703
704 +-----------------------+------+-------------+
705 | Distro | Perl | End of Life |
706 +-----------------------+------+-------------+
707 | Ubuntu 14.04 (trusty) | 5.18 | 2019-04 |
708 | Ubuntu 16.04 (xenial) | 5.22 | 2021-04 |
709 | Ubuntu 18.04 (bionic) | 5.26 | 2023-04 |
710 | CentOS 6 | 5.10 | 2020-12 |
711 | CentOS 7 | 5.16 | 2024-07 |
712 +-----------------------+------+-------------+
713
714 As you can see, we're kept behind mostly by the slow pace of CentOS (actually,
715 RHEL) releases.
716
717 As for Jira, the policy is very lax. I (the author) only test L<JIRA::REST> on
718 the Jira server installed in the company I work for, which is usually (but not
719 always) at most one year older than the newest released version. I don't have
720 yet an easy way to test it on different versions.
721
693722 =head1 SEE ALSO
694723
695724 =over
700729
701730 =item * C<JIRA::Client::REST>
702731
703 This is another module implementing JIRA's REST API using
732 This is another module implementing Jira's REST API using
704733 L<SPORE|https://github.com/SPORE/specifications/blob/master/spore_description.pod>.
705734 I got a message from the author saying that he doesn't intend to keep
706735 it going.
717746
718747 =head1 COPYRIGHT AND LICENSE
719748
720 This software is copyright (c) 2017 by CPqD <www.cpqd.com.br>.
749 This software is copyright (c) 2018 by CPqD <www.cpqd.com.br>.
721750
722751 This is free software; you can redistribute it and/or modify it under
723752 the same terms as the Perl 5 programming language system itself.
2828 }
2929
3030 for my $info (eval {$jira->GET('/serverInfo')}) {
31 ok(defined $info && $info->{serverTitle} eq 'Atlassian JIRA', 'GET /serverInfo');
31 ok(defined $info && $info->{serverTitle} =~ /Atlassian/, 'GET /serverInfo');
3232 }
3333
3434 $jira->set_search_iterator({
11
22 BEGIN {
33 unless ($ENV{AUTHOR_TESTING}) {
4 require Test::More;
5 Test::More::plan(skip_all => 'these tests are for testing by the author');
4 print qq{1..0 # SKIP these tests are for testing by the author\n};
5 exit
66 }
77 }
88
11
22 BEGIN {
33 unless ($ENV{AUTHOR_TESTING}) {
4 require Test::More;
5 Test::More::plan(skip_all => 'these tests are for testing by the author');
4 print qq{1..0 # SKIP these tests are for testing by the author\n};
5 exit
66 }
77 }
88
00
11 BEGIN {
22 unless ($ENV{RELEASE_TESTING}) {
3 require Test::More;
4 Test::More::plan(skip_all => 'these tests are for release candidate testing');
3 print qq{1..0 # SKIP these tests are for release candidate testing\n};
4 exit
55 }
66 }
77