App-GHGen
view release on metacpan or search on metacpan
t/integration.t view on Meta::CPAN
'total_minutes equals sum of per-workflow minutes_per_month');
# Within free tier: billable_minutes == 0 and monthly_cost == 0.
if ($usage->{total_minutes} <= $FREE_TIER_MINUTES) {
is($usage->{billable_minutes}, 0, 'billable_minutes is 0 within free tier');
is($usage->{monthly_cost}, 0, 'monthly_cost is 0 within free tier');
}
diag(sprintf 'Total: %.1f min billable: %.1f cost: $%.2f',
$usage->{total_minutes}, $usage->{billable_minutes}, $usage->{monthly_cost})
if $ENV{TEST_VERBOSE};
restore_all();
});
};
# ---------------------------------------------------------------------------
# Subtest 10: Fixer::fix_workflow end-to-end file round-trip
# Write a YAML file with known issues, call fix_workflow(), read it back,
# and verify the mutations persisted to disk.
subtest 'Fixer::fix_workflow: mutations written to disk and re-loadable' => sub {
in_tempdir(sub {
path('.github/workflows')->mkpath;
my $wf_path = '.github/workflows/fixme.yml';
DumpFile($wf_path, {
name => 'Fixable',
on => [qw(push)],
jobs => {
build => {
'runs-on' => 'ubuntu-18.04',
steps => [
{ uses => 'actions/checkout@main' },
{ run => 'cargo build' },
],
},
},
});
my @issues = (
{
type => 'cost',
severity => 'low',
message => 'No concurrency group - old runs continue when superseded',
},
{
type => 'maintenance',
severity => 'low',
message => 'Using older runner versions - consider updating',
},
);
my $n = fix_workflow($wf_path, \@issues);
cmp_ok($n, '>=', 1, "fix_workflow applied at least one fix (got $n)");
# Re-read the YAML from disk and assert the fixes persisted.
my $reloaded = LoadFile($wf_path);
ok(defined $reloaded->{concurrency},
'concurrency key present in reloaded workflow (persisted to disk)');
isnt($reloaded->{jobs}{build}{'runs-on'}, 'ubuntu-18.04',
'outdated runner updated in reloaded workflow');
diag("Reloaded runs-on: $reloaded->{jobs}{build}{'runs-on'}") if $ENV{TEST_VERBOSE};
});
};
# ---------------------------------------------------------------------------
# Subtest 11: fix_workflow skips DumpFile when no fixes applied
# POD: the file is only rewritten when fix count > 0.
# Spy on DumpFile to confirm it is never called when the issues list is empty.
subtest 'Fixer::fix_workflow: DumpFile not called when zero fixes applied' => sub {
in_tempdir(sub {
path('.github/workflows')->mkpath;
my $wf_path = '.github/workflows/clean.yml';
DumpFile($wf_path, _clean_workflow());
# Spy (call-through) records calls without preventing them.
my $get_dump_calls = spy('App::GHGen::Fixer::DumpFile');
my $n = fix_workflow($wf_path, []);
is($n, 0, 'fix_workflow returns 0 when no issues passed');
is(scalar $get_dump_calls->(), 0,
'DumpFile not called when fix count is zero');
restore_all();
});
};
# ---------------------------------------------------------------------------
# Subtest 12: PerlCustomizer detect_perl_requirements + generate_custom_perl_workflow
# Verify the detect -> configure -> generate pipeline and the step-ordering
# invariant documented in CLAUDE.md and PerlCustomizer POD.
subtest 'PerlCustomizer: detect_perl_requirements feeds generate_custom_perl_workflow' => sub {
in_tempdir(sub {
path('cpanfile')->spew("requires 'perl', '5.036';\nrequires 'Moose';\n");
path('Makefile.PL')->spew("use ExtUtils::MakeMaker;\n");
my $reqs = detect_perl_requirements();
ok($reqs->{has_cpanfile}, 'cpanfile detected');
ok($reqs->{has_makefile_pl}, 'Makefile.PL detected');
is($reqs->{min_version}, '5.036', 'Correct minimum Perl version extracted');
my $yaml = generate_custom_perl_workflow({
enable_linter => 1,
enable_linter_unused => 0,
enable_critic => 1,
enable_coverage => 1,
});
ok(defined $yaml && length $yaml > 0, 'generate_custom_perl_workflow returns YAML');
# Step ordering invariant per CLAUDE.md:
# checkout -> setup-perl -> cache -> deps -> lint -> tests -> critic -> coverage
my $checkout_pos = index($yaml, 'checkout');
my $lint_pos = index($yaml, 'perl {0}');
my $prove_pos = index($yaml, 'prove');
my $critic_pos = index($yaml, 'Perl::Critic');
my $cover_pos = index($yaml, 'Devel::Cover');
cmp_ok($checkout_pos, '>=', 0, 'checkout step present in generated YAML');
cmp_ok($lint_pos, '>=', 0, 'lint step (perl {0}) present in generated YAML');
cmp_ok($prove_pos, '>=', 0, 'test step (prove) present in generated YAML');
( run in 0.614 second using v1.01-cache-2.11-cpan-81fc1098f69 )