File Coverage

blib/lib/GitHub/Actions.pm
Criterion Covered Total %
statement 55 56 98.2
branch 7 12 58.3
condition 4 4 100.0
subroutine 19 20 95.0
pod 12 12 100.0
total 97 104 93.2


line stmt bran cond sub pod time code
1             package GitHub::Actions;
2              
3 5     5   346270 use Exporter 'import'; # needed to use @EXPORT
  5         58  
  5         177  
4 5     5   25 use warnings;
  5         8  
  5         126  
5 5     5   26 use strict;
  5         9  
  5         104  
6 5     5   27 use Carp;
  5         8  
  5         316  
7              
8 5     5   107 use v5.14;
  5         16  
9              
10             # Module implementation here
11             our %github;
12             our $EXIT_CODE = 0;
13              
14             our @EXPORT = qw(
15             %github set_output set_env debug error warning
16             set_failed error_on_file warning_on_file
17             start_group end_group exit_action
18             );
19              
20             BEGIN {
21 5     5   87 for my $k ( keys(%ENV) ) {
22 174 100       374 if ( $k =~ /^GITHUB_/ ) {
23 4         14 my ($nogithub) = ( $k =~ /^GITHUB_(\w+)/ );
24 4         14 $github{$nogithub} = $ENV{$k} ;
25             }
26             }
27             }
28              
29 5     5   2256 use version; our $VERSION = qv('0.1.2');
  5         9802  
  5         32  
30              
31             sub _write_to_github_file {
32 4     4   9 my ($github_var, $content) = @_;
33 4 50       325 open(my $fh, '>>', $github{$github_var}) or die "Could not open file ". $github{$github_var} ." $!";
34 4         54 say $fh $content;
35 4         170 close $fh;
36             }
37              
38             sub set_output {
39 2 50   2 1 741 carp "Need name and value" unless @_;
40 2         6 my ($output_name, $output_value) = @_;
41 2   100     9 $output_value ||=1;
42 2         8 _write_to_github_file( 'OUTPUT', "$output_name=$output_value" );
43             }
44              
45             sub set_env {
46 2     2 1 839 my ($env_var_name, $env_var_value) = @_;
47 2   100     9 $env_var_value ||='1';
48 2         20 _write_to_github_file( 'ENV', "$env_var_name=$env_var_value" );
49             }
50              
51             sub debug {
52 1     1 1 1432 my $debug_message = shift;
53 1         81 say "::debug::$debug_message";
54             }
55              
56             sub error {
57 2     2 1 1843 my $error_message = shift;
58 2         6 $EXIT_CODE = 1;
59 2         124 say "::error::$error_message"
60             }
61              
62             sub warning {
63 2     2 1 1411 my $warning = shift;
64 2         49 say "::warning::$warning"
65             }
66              
67             sub error_on_file {
68 1     1 1 1439 command_on_file( "::error", @_ );
69             }
70              
71             sub warning_on_file {
72 1     1 1 1459 command_on_file( "::warning", @_ );
73             }
74              
75             sub command_on_file {
76 2     2 1 4 my $command = shift;
77 2         4 my $message = shift;
78 2         4 my ($file, $line, $col ) = @_;
79 2 50       14 if ( $file ) {
80 2         5 my @data;
81 2         7 push( @data, "file=$file");
82 2 50       5 push( @data, "line=$line") if $line;
83 2 50       6 push( @data, "col=$col") if $col;
84 2         7 $command .= " ".join(",", @data );
85             }
86 2         73 say $command."::$message"
87             }
88              
89             sub start_group {
90 1     1 1 1417 say "::group::" . shift;
91             }
92              
93             sub end_group {
94 1     1 1 21 say "::endgroup::";
95             }
96              
97             sub set_failed {
98 1     1 1 1390 error( @_ );
99 1         11 exit( 1);
100             }
101              
102             sub exit_action {
103 0     0 1   exit( $EXIT_CODE );
104             }
105              
106             "Action!"; # Magic true value required at end of module
107             __END__
108              
109             =head1 NAME
110              
111             GitHub::Actions - Work in GitHub Actions using Perl
112              
113              
114             =head1 VERSION
115              
116             This document describes GitHub::Actions version 0.1.1.1
117              
118              
119             =head1 SYNOPSIS
120              
121             use GitHub::Actions;
122             use v5.14;
123              
124             # Imported %github contains all GITHUB_* environment variables
125             for my $g (keys %github ) {
126             say "GITHUB_$g -> ", $github{$g}
127             }
128              
129             # Set step output
130             set_output("FOO", "BAR");
131              
132             # Set environment variable value
133             set_env("FOO", "BAR");
134              
135             # Produces an error and sets exit code to 1
136             error( "FOO has happened" );
137              
138             # Error/warning with information on file
139             error_on_file( "There's foo", $file, $line, $col );
140             warning_on_file( "There's bar", $file, $line, $col );
141              
142             # Debugging messages and warnings
143             debug( "Value of FOO is $bar" );
144             warning( "Value of FOO is $bar" );
145              
146             # Start and end group
147             start_group( "Foo" );
148             # do stuff
149             end_group;
150              
151             # Exits with error if that's the case
152             exit_action();
153              
154             # Errors and exits
155             set_failed( "We're doomed" );
156              
157             Install this module within a GitHub action
158              
159             . name: "Install GitHub::Actions"
160             run: sudo cpan GitHub::Actions
161              
162             (we need C<sudo> since we're using the system Perl)
163              
164             You can use this as a C<step>
165              
166             - name: Test env variables
167             shell: perl {0}
168             run: |
169             use GitHub::Actions;
170             set_env( 'FOO', 'BAR');
171              
172             In most cases, you'll want to just have it installed locally and fatpack it to
173             upload it to the repository.
174              
175             =head1 DESCRIPTION
176              
177             GitHub Actions include by default, at least in its Linux runners, a
178             system Perl which you can use directly in your GitHub actions. This here is
179             a (for the time being) minimalistic module that tries to help a bit
180             with that, by defining a few functions that will be useful when
181             performing GitHub actions. Besides the system Perl, you can use any of
182             L<the modules
183             installed|https://gist.github.com/JJ/edf3a39d68525439978da2a02763d42b>. You
184             can install other modules via cpan or, preferably for speed, via the
185             Ubuntu package (or equivalent)
186              
187             Check out an example of using it in the L<repository|https://github.com/JJ/perl-GitHub-Actions/blob/main/.github/workflows/self-test.yml>
188              
189             =head1 INTERFACE
190              
191             =head2 set_env( $env_var_name, $env_var_value)
192              
193             This is equivalent to
194             L<setting an environment variable|https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable>
195              
196             =head2 set_output( $output_name, $output_value)
197              
198             Equivalent to L<C<set_output>|https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-output-parameter>
199              
200             =head2 debug( $debug_message )
201              
202             Equivalent to L<C<debug>|https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-a-debug-message>
203              
204             =head2 error( $error_message )
205              
206             Equivalent to
207             L<C<error>|https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-error-message>,
208             prints an error message. Remember to call L<exit_action()> to make the step fail
209             if there's been some error.
210              
211             =head2 warning( $warning_message )
212              
213             Equivalent to L<C<warning>|https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message>, simply prints a warning.
214              
215             =head2 command_on_file( $error_message, $file, $line, $col )
216              
217             Common code for L<error_on_file> and L<warning_on_file>. Can be used for any future commands.
218              
219             =head2 error_on_file( $error_message, $file, $line, $col )
220              
221             Equivalent to L<C<error>|https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-error-message>, prints an error message with file and line info
222              
223             =head2 warning_on_file( $warning_message, $file, $line, $col )
224              
225             Equivalent to L<C<warning>|https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message>, prints an warning with file and line info.
226              
227             =head2 set_failed( $error_message )
228              
229             Exits with an error status of 1 after setting the error message.
230              
231             =head2 start_group( $group_name )
232              
233             Starts a group in the logs, grouping the following messages. Corresponds to
234             L<C<group>|https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#grouping-log-lines>.
235              
236             =head2 end_group
237              
238             Ends current log grouping.
239              
240             =head2 exit_action
241              
242             Exits with the exit code generated during run, that is, 1 if there's been any
243             error reported.
244              
245             =head1 CONFIGURATION AND ENVIRONMENT
246              
247             GitHub::Actions requires no configuration files or environment
248             variables. Those set by GitHub Actions will only be available there,
249             or if you set them explicitly. Remember that they will need to be set
250             during the C<BEGIN> phase to be available when this module loads.
251              
252             BEGIN {
253             $ENV{'GITHUB_FOO'} = 'foo';
254             $ENV{'GITHUB_BAR'} = 'bar';
255             }
256              
257              
258             =head1 DEPENDENCIES
259              
260             Intentionally, no dependencies are included.
261              
262              
263             =head1 INCOMPATIBILITIES
264              
265             None reported.
266              
267              
268             =head1 BUGS AND LIMITATIONS
269              
270             No bugs have been reported.
271              
272             Please report any bugs or feature requests to L<https://github.com/JJ/perl-GitHub-Actions/issues>.
273              
274              
275             =head1 AUTHOR
276              
277             JJ Merelo C<< <jmerelo@CPAN.org> >>. Many thanks to RENEEB and Gabor Szabo for their help with test and metadata.
278              
279              
280             =head1 LICENCE AND COPYRIGHT
281              
282             Copyright (c) 2021, JJ Merelo C<< <jmerelo@CPAN.org> >>. All rights reserved.
283              
284             This module is free software; you can redistribute it and/or
285             modify it under the same terms as Perl itself. See L<perlartistic>.
286              
287              
288             =head1 DISCLAIMER OF WARRANTY
289              
290             BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
291             FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
292             OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
293             PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
294             EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
295             WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
296             ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
297             YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
298             NECESSARY SERVICING, REPAIR, OR CORRECTION.
299              
300             IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
301             WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
302             REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
303             LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
304             OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
305             THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
306             RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
307             FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
308             SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
309             SUCH DAMAGES.