File Coverage

blib/lib/Dist/Zilla/Role/Author/CSSON/GithubActions.pm
Criterion Covered Total %
statement 74 80 92.5
branch 8 16 50.0
condition 4 6 66.6
subroutine 20 22 90.9
pod 0 4 0.0
total 106 128 82.8


line stmt bran cond sub pod time code
1 1     1   647 use 5.14.0;
  1         4  
2 1     1   6 use strict;
  1         2  
  1         26  
3 1     1   5 use warnings;
  1         2  
  1         88  
4              
5             package Dist::Zilla::Role::Author::CSSON::GithubActions;
6              
7             # ABSTRACT: Role for Github Actions workflows
8             our $AUTHORITY = 'cpan:CSSON'; # AUTHORITY
9             our $VERSION = '0.0107';
10              
11 1     1   7 use Moose::Role;
  1         3  
  1         11  
12 1     1   6133 use namespace::autoclean;
  1         3  
  1         11  
13 1     1   109 use Path::Tiny;
  1         2  
  1         72  
14 1     1   10 use Try::Tiny;
  1         3  
  1         68  
15 1     1   10 use Types::Standard qw/ArrayRef Bool Str HashRef/;
  1         2  
  1         9  
16 1     1   1330 use Types::Path::Tiny qw/Path/;
  1         25196  
  1         8  
17 1     1   933 use File::ShareDir qw/dist_dir/;
  1         18424  
  1         73  
18 1     1   11 use YAML::XS qw/Dump Load/;
  1         3  
  1         161  
19 1     1   605 use List::AllUtils qw/first/;
  1         10758  
  1         108  
20 1     1   529 use Path::Class::File;
  1         15964  
  1         33  
21 1     1   485 use Dist::Zilla::File::InMemory;
  1         95072  
  1         1110  
22              
23             with qw/
24             Dist::Zilla::Role::Plugin
25             Dist::Zilla::Role::FileGatherer
26             Dist::Zilla::Role::FilePruner
27             /;
28              
29             requires 'workflow_filename';
30              
31             around mvp_multivalue_args => sub {
32             my $orig = shift;
33             my $self = shift;
34              
35             return $self->$orig(), qw/
36             on_push_branches
37             on_pull_request_branches
38             matrix_os
39             perl_versions
40             /;
41             };
42              
43             has clear_on_push_branches => (
44             is => 'ro',
45             isa => Bool,
46             default => sub { 0 },
47             documentation => q{Clears the on.push.branches setting from the base workflow (if that setting is used in the config)},
48             );
49             has clear_on_pull_request_branches => (
50             is => 'ro',
51             isa => Bool,
52             default => sub { 0 },
53             documentation => q{Clears the on.pull_request.branches setting from the base workflow (if that setting is used in the config)},
54             );
55              
56             for my $setting (qw/on_push_branches on_pull_request_branches/) {
57             has $setting => (
58             is => 'ro',
59             isa => ArrayRef,
60             default => sub { [] },
61             traits => ['Array'],
62             documentation => q{Add more branches to on.push.branches *or* on.pull_request.branches},
63             handles => {
64             "all_$setting" => 'elements',
65             "has_$setting" => 'count',
66             },
67             );
68             }
69             has matrix_os => (
70             is => 'ro',
71             isa => ArrayRef,
72             default => sub { [] },
73             documentation => q{If defined, replaces the matrix.os setting},
74             );
75             has perl_version => (
76             is => 'ro',
77             isa => ArrayRef,
78             default => sub { [] },
79             documentation => q{If defined, replaces the matrix.perl-version setting},
80             );
81             has filename => (
82             is => 'rw',
83             isa => Str,
84             documentation => q{If defined, the filename of the generated workflow file},
85             predicate => 'has_filename',
86             );
87              
88              
89              
90             has generated_filepath => (
91             is => 'rw',
92             isa => Path,
93             predicate => 'has_generated_filename',
94             );
95             has generated_yaml => (
96             is => 'rw',
97             isa => HashRef,
98             );
99              
100             # Override this in the Workflow if needed
101       0 0   sub parse_custom_parameters { }
102              
103             sub distribution_name {
104 0     0 0 0 my $self = shift;
105 0         0 my $name = $self->meta->name;
106 0         0 $name =~ s/::/-/g;
107 0         0 return $name;
108             }
109              
110             sub _prepare {
111 6     6   18 my $self = shift;
112              
113             # Read the workflow file
114 6         38 my $package = $self->distribution_name;
115              
116 6         49 my $dir = path('.');
117             try {
118 6     6   600 $dir = path(dist_dir($package));
119             }
120 6     6   248 finally { };
121              
122 6         106 my $workflow_path = $dir->child($self->workflow_filename);
123              
124             # Read YAML from the included workflow file, and modify that YAML from the dist.ini configuration
125 6         282 my $yaml = Load($workflow_path->slurp);
126              
127 6 50 66     2962 if ($self->clear_on_push_branches && exists $yaml->{'on'}{'push'}{'branches'}) {
128 1         5 $yaml->{'on'}{'push'}{'branches'} = [];
129             }
130 6 50 66     313 if ($self->clear_on_pull_request_branches && exists $yaml->{'on'}{'pull_request'}{'branches'}) {
131 2         9 $yaml->{'on'}{'pull_request'}{'branches'} = [];
132             }
133              
134 6 50       345 if ($self->has_on_push_branches) {
135 0         0 push @{ $yaml->{'on'}{'push'}{'branches'} } => $self->all_on_push_branches;
  0         0  
136             }
137 6 100       354 if ($self->has_on_pull_request_branches) {
138 2         8 push @{ $yaml->{'on'}{'pull_request'}{'branches'} } => $self->all_on_pull_request_branches;
  2         188  
139             }
140              
141             my $generated_filename = $self->has_filename ? $self->filename
142 6 0       322 : exists $yaml->{'filename'} ? delete $yaml->{'filename'}
    50          
143             : $self->workflow_filename;
144              
145 6         47 $yaml = $self->parse_custom_parameters($yaml);
146 6         294 $self->generated_yaml($yaml);
147              
148             # Prepare the path where the generated workflow file will be saved (.github/workflows/...)
149 6 50       209 my $path = path($self->zilla->built_in ? $self->zilla->built_in : (), '.github', 'workflows', $generated_filename);
150 6         535 $path->touchpath;
151 6         4214 $self->generated_filepath($path);
152 6         27 return $self;
153              
154             }
155              
156             sub gather_files {
157 6     6 0 310844 my $self = shift;
158 6         38 $self->_prepare;
159              
160 6         283 my $rendered_yaml = Dump($self->generated_yaml);
161 6         367 $self->generated_filepath->spew($rendered_yaml);
162              
163 6         3458 my $generated_file = Dist::Zilla::File::InMemory->new({
164             name => $self->generated_filepath->stringify,
165             content => Dump($rendered_yaml),
166             });
167 6         3078 $self->add_file($generated_file);
168              
169             }
170              
171             sub prune_files {
172 6     6 0 70595 my $self = shift;
173              
174 6     6   39 my $file = first { $_->name eq $self->generated_filepath } @{ $self->zilla->files };
  6         239  
  6         246  
175              
176 6 50       257 $self->zilla->prune_file($file) if $file;
177             }
178              
179             1;
180              
181             __END__
182              
183             =pod
184              
185             =encoding UTF-8
186              
187             =head1 NAME
188              
189             Dist::Zilla::Role::Author::CSSON::GithubActions - Role for Github Actions workflows
190              
191             =head1 VERSION
192              
193             Version 0.0107, released 2020-12-30.
194              
195             =head1 SYNOPSIS
196              
197             In dist.ini:
198              
199             [MyWorkflow]
200             ; set on.push.branches to an empty list
201             clear_on_push_branches = 1
202              
203             ; set on.pull_request.branches to an empty list
204             clear_on_pull_request_branches = 1
205              
206             ; add branches to on.push.branches
207             on_pull_request_branches = 'this-branch'
208             on_pull_request_branches = 'that-other-branch'
209              
210             ; add branches to on.pull_request.branches
211             on_pull_request_branches = 'my-pr-branch'
212             on_pull_request_branches = 'feature-branch'
213              
214             ; replace jobs.perl-job.strategy.matrix.os
215             matrix_os = ubuntu-latest
216             matrix_os = ubuntu-16.04
217              
218             ; replace jobs.perl-job.strategy.matrix.perl-version
219             perl_version = 5.32
220             perl_version = 5.24
221             perl_version = 5.18
222              
223             =head1 DESCRIPTION
224              
225             This role exposes some parameters creates a Github Actions workflow file in C<.github/workflows>.
226              
227             Note that, if you plan to use the customizations shown above, the following settings in the workflow YAML file are expected to be defined as lists and not strings:
228              
229             =over 4
230              
231             =item *
232              
233             C<on.push.branches>
234              
235             =item *
236              
237             C<on.pull_request.branches>
238              
239             =item *
240              
241             C<jobs.perl-job.strategy.matrix.os>
242              
243             =item *
244              
245             C<jobs.perl-job.strategy.matrix.perl-version>
246              
247             =back
248              
249             Also, it is assumed that the step where the distribution is tested is named C<perl-job>.
250              
251             The generated workflow file will be created in C<.github/workflows>. The filename will be (in order of priority):
252              
253             =over 4
254              
255             =item *
256              
257             The value of the C<filename> parameter in C<dist.ini>
258              
259             =item *
260              
261             The value of the C<filename> key in the C<$workflow.yml> file
262              
263             =item *
264              
265             The name of the C<$workflow.yml> file
266              
267             =back
268              
269             See L<Dist::Zilla::Plugin::Author::CSSON::GithubActions::Workflow::TestWithMakefile> for an example workflow.
270              
271             =head1 SOURCE
272              
273             L<https://github.com/Csson/p5-Dist-Zilla-Plugin-Author-CSSON-GithubActions>
274              
275             =head1 HOMEPAGE
276              
277             L<https://metacpan.org/release/Dist-Zilla-Plugin-Author-CSSON-GithubActions>
278              
279             =head1 AUTHOR
280              
281             Erik Carlsson <info@code301.com>
282              
283             =head1 COPYRIGHT AND LICENSE
284              
285             This software is copyright (c) 2020 by Erik Carlsson.
286              
287             This is free software; you can redistribute it and/or modify it under
288             the same terms as the Perl 5 programming language system itself.
289              
290             =cut