Devel-Cover-Report-Coveralls
view release on metacpan or search on metacpan
lib/Devel/Cover/Report/Coveralls.pm view on Meta::CPAN
};
}
sub git_log {
my $format = shift;
my $text = '';
my $command = "git log -1 --encoding=UTF-8 --pretty=format:'$format'";
if (open(my $fh, '-|:encoding(UTF-8)', $command)) {
$text = do { local $/; <$fh> };
close $fh;
}
return $text;
}
sub get_git_info {
my $git = {
head => {
id => git_log('%H'),
author_name => git_log('%aN'),
author_email => git_log('%ae'),
committer_name => git_log('%cN'),
committer_email => git_log('%ce'),
message => git_log('%s')
},
remotes => [
map {
my ( $name, $url ) = split( " ", $_ );
+{ name => $name, url => $url }
} split( "\n", `git remote -v` )
],
};
my ($branch,) = grep { /^\* / } split( "\n", `git branch` );
$branch =~ s/^\* //;
$git->{branch} = $branch;
if ($ENV{GITHUB_REF} && $ENV{GITHUB_REF} =~ m![^/]+/[^/]+/(.+)$!) {
$git->{branch} = $1;
} elsif ($ENV{BUILD_SOURCEBRANCHNAME}) {
$git->{branch} = $ENV{BUILD_SOURCEBRANCHNAME};
}
return $git;
}
sub get_config {
my $config = {};
if (-f $CONFIG_FILE) {
$config = YAML::LoadFile($CONFIG_FILE);
}
my $json = {};
$json->{repo_token} = $config->{repo_token} if $config->{repo_token};
$json->{repo_token} = $ENV{COVERALLS_REPO_TOKEN} if $ENV{COVERALLS_REPO_TOKEN};
$json->{flag_name} = $ENV{COVERALLS_FLAG_NAME} if $ENV{COVERALLS_FLAG_NAME};
$json->{parallel} = \1 if $ENV{COVERALLS_PARALLEL};
my $is_travis;
my $endpoint = ($ENV{COVERALLS_ENDPOINT} || $API_ENDPOINT) . $API_ENDPOINT_STEM;
if ($ENV{TRAVIS}) {
$is_travis = 1;
$json->{service_name} = $config->{service_name} || 'travis-ci';
$json->{service_job_id} = $ENV{TRAVIS_JOB_ID};
if($ENV{TRAVIS_PULL_REQUEST} && $ENV{TRAVIS_PULL_REQUEST} ne 'false'){
$json->{service_pull_request} = $ENV{TRAVIS_PULL_REQUEST};
}
} elsif ($ENV{CIRCLECI}) {
$json->{service_name} = 'circleci';
$json->{service_number} = $ENV{CIRCLE_WORKFLOW_ID};
# Unfortunately, circle-ci reports the url to PR..
} elsif($ENV{DRONE}) {
$json->{service_name} = 'drone';
$json->{service_number} = $ENV{DRONE_BUILD_NUMBER};
$json->{service_pull_request} = $ENV{DRONE_PULL_REQUEST} if $ENV{DRONE_PULL_REQUEST};
} elsif ($ENV{SEMAPHORE}) {
$json->{service_name} = 'semaphore';
$json->{service_number} = $ENV{SEMAPHORE_BUILD_NUMBER} if $ENV{SEMAPHORE_BUILD_NUMBER};
# Also support semaphore 2.x
$json->{service_number} = $ENV{SEMAPHORE_WORKFLOW_ID} if $ENV{SEMAPHORE_WORKFLOW_ID};
$json->{service_pull_request} = $ENV{SEMAPHORE_GIT_PR_NUMBER} if $ENV{SEMAPHORE_GIT_PR_NUMBER};
} elsif ($ENV{JENKINS_URL}) {
$json->{service_name} = 'jenkins';
$json->{service_number} = $ENV{BUILD_NUM};
# In jenkins, the PR number is not available as an env var..
} elsif ($ENV{GITHUB_TOKEN}) {
# from info as at 2020-11-07
# https://github.com/coverallsapp/github-action/blob/master/src/run.ts
# https://github.com/nickmerwin/node-coveralls/blob/master/lib/getOptions.js
# we use GITHUB_TOKEN just to differentiate from still-working setup
# in next option, but which requires a secret setting up
$json->{service_name} = 'github';
$json->{repo_token} = $ENV{GITHUB_TOKEN};
$json->{service_job_id} = $ENV{GITHUB_RUN_ID};
if (($ENV{GITHUB_EVENT_NAME}||'') eq 'pull_request') {
if (open my $fh, '<:raw', $ENV{GITHUB_EVENT_PATH}) {
local $/;
my $text = <$fh>;
my $pr = decode_json $text;
if (my ($match) = ($pr->{number}||'') =~ /(\d+)$/) {
$json->{service_pull_request} = $match;
}
}
}
} elsif ($ENV{GITHUB_ACTIONS} && $ENV{GITHUB_SHA}) {
$json->{service_name} = 'github-actions';
$json->{service_number} = substr($ENV{GITHUB_SHA}, 0, 9);
} elsif ($ENV{SYSTEM_TEAMFOUNDATIONSERVERURI}) {
$json->{service_name} = 'azure-pipelines';
$json->{service_number} = $ENV{BUILD_BUILDID};
} else {
$is_travis = 0;
$json->{service_name} = $config->{service_name} || $SERVICE_NAME;
$json->{service_event_type} = 'manual';
}
die "required repo_token in $CONFIG_FILE, make sure the environment var \"COVERALLS_REPO_TOKEN\" is set or launch via Travis" if !$json->{repo_token} && !$is_travis;
if (exists $ENV{COVERALLS_PERL_SERVICE_NAME} && $ENV{COVERALLS_PERL_SERVICE_NAME}) {
$json->{service_name} = $ENV{COVERALLS_PERL_SERVICE_NAME};
}
return ($json, $endpoint);
}
sub _parse_line ($) {
my $c = shift;
return sub {
my $l = $c->location(shift);
return $l unless $l;
if ($l->[0]->uncoverable) {
return undef;
} else {
return $l->[0]->covered;
}
};
}
sub report {
my ($pkg, $db, $options) = @_;
my $cover = $db->cover;
my @sfs;
for my $file (@{$options->{file}}) {
my $f = $cover->file($file);
my $c = $f->statement();
push @sfs, get_source( $file, _parse_line $c );
}
my ($json, $endpoint) = get_config();
$json->{git} = eval { get_git_info() } || {};
$json->{source_files} = \@sfs;
my $coder = JSON::PP->new->ascii;
my $response = HTTP::Tiny->new( verify_SSL => 1 )
->post_form( $endpoint, { json => $coder->encode($json) } );
my $res = eval { decode_json $response->{content} };
print("- Report::Coveralls --------\n");
if(exists($json->{service_number})){
print "My build number: ". $json->{service_number} ."\n";
}
if ($@) {
print "error: " . $response->{content};
} elsif ($response->{success}) {
print "register: " . $res->{url} . "\n";
} else {
print "error: " . $res->{message} . "\n";
}
if($ENV{COVERALLS_PARALLEL}){
print "Parallel mode: True". "\n"
}
print("----------------------------\n");
}
1;
__END__
=encoding utf-8
=head1 NAME
Devel::Cover::Report::Coveralls - coveralls backend for Devel::Cover
=head1 USAGE
=head2 GitHub Actions
1. Add your repo to coveralls. L<https://coveralls.io/repos/new>
2. Add settings to one of your GitHub workflows. Here assuming you're
calling it F<.github/workflows/ci.yml>:
jobs:
ubuntu:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
perl-version: ['5.10', '5.14', '5.20']
include:
- perl-version: '5.30'
os: ubuntu-latest
release-test: true
coverage: true
container: perl:${{ matrix.perl-version }}
steps:
- uses: actions/checkout@v2
# do other stuff like installing external deps here
- run: cpanm -n --installdeps .
- run: perl -V
- name: Run release tests # before others as may install useful stuff
( run in 1.614 second using v1.01-cache-2.11-cpan-8dfa8b56332 )