App-GHGen
view release on metacpan or search on metacpan
lib/App/GHGen/Reporter.pm view on Meta::CPAN
$comment .= " create-pr: true\n";
$comment .= "```\n\n";
}
# Add savings estimate
my $savings = estimate_savings($issues);
if ($savings->{minutes} > 0) {
$comment .= "### ð° Potential Savings\n\n";
$comment .= "By fixing these issues:\n";
$comment .= "- â±ï¸ Save **~$savings->{minutes} CI minutes/month**\n";
if ($savings->{cost} > 0) {
$comment .= "- ðµ Save **~\$$savings->{cost}/month** (private repos)\n";
}
$comment .= "\n";
}
$comment .= "---\n";
$comment .= "*Analysis by [GHGen](https://github.com/your-org/ghgen)*\n";
return $comment;
}
=head2 estimate_savings($issues)
Estimate CI-minute savings and associated cost reduction from fixing a set of issues.
=head3 Purpose
For each C<performance> (caching) or C<cost> (concurrency, triggers) issue,
add a fixed minute estimate to the running total and compute the equivalent
USD saving at the GitHub private-repo rate of $0.008/minute.
=head3 Arguments
=over 4
=item C<$issues> (ArrayRef[HashRef], required)
Issue hashes with at least C<type> and C<message>.
=back
=head3 Returns
A hash reference:
{
minutes => Int, # total estimated minutes saved per month; 0 when no savings
cost => Int, # floor(minutes * 0.008); 0 when no savings
}
=head3 Side Effects
None. Pure function.
=head3 Usage Example
my $s = estimate_savings(\@issues);
say "Save $s->{minutes} min/month";
=head3 API SPECIFICATION
=head4 Input
{ issues => { type => 'arrayref', required => 1 } }
=head4 Output
{
type => 'hashref',
keys => {
minutes => { type => 'scalar' },
cost => { type => 'scalar' },
},
}
=head3 FORMAL SPECIFICATION
estimate_savings : seq Issue â { minutes: â, cost: â }
RATE â 0.008
savings(i) â
i.type = performance â§ i.message =~ /caching/ â 500
i.type = cost â§ i.message =~ /concurrency/ â 50
i.type = cost â§ i.message =~ /triggers/ â 100
otherwise â 0
total â â { savings(i) ⣠i â issues }
result â { minutes ⦠total, cost ⦠floor(total à RATE) }
=cut
sub estimate_savings($issues) {
my %savings = (
minutes => 0,
cost => 0,
);
for my $issue (@$issues) {
# Estimate savings by issue type
if ($issue->{type} eq 'performance') {
# Caching saves ~5 minutes per workflow run
# Assume 100 runs/month
$savings{minutes} += 500 if $issue->{message} =~ /caching/;
} elsif ($issue->{type} eq 'cost') {
if ($issue->{message} =~ /concurrency/) {
# Concurrency saves ~50 minutes/month by canceling old runs
$savings{minutes} += 50;
}
if ($issue->{message} =~ /triggers/) {
# Trigger filters save ~100 minutes/month
$savings{minutes} += 100;
}
}
}
# Private repo pricing: ~$0.008 per minute
$savings{cost} = int($savings{minutes} * 0.008);
( run in 1.278 second using v1.01-cache-2.11-cpan-9169edd2b0e )