Developer-Dashboard

 view release on metacpan or  search on metacpan

t/142-action-pin-provenance.t  view on Meta::CPAN

# Purpose: execute the gate under a controlled environment.
# Input:   $argv arrayref; $fixture optional path to the offline resolver JSON.
# Output:  ($exit_code, $stdout, $stderr).
sub _run_gate {
    my ( $argv, $fixture ) = @_;

    local $ENV{DD_ACTION_PIN_FIXTURE} = $fixture // '';
    my ( $stdout, $stderr, $exit ) = capture {
        system( $^X, $GATE, @{$argv} );
    };
    return ( $exit >> 8, $stdout, $stderr );
}

# Purpose: read a whole file.
# Input:   $path.
# Output:  its contents.
sub _slurp {
    my ($path) = @_;
    open my $fh, '<:raw', $path or die "Unable to read $path: $!";
    local $/;
    my $text = <$fh>;
    close $fh or die "Unable to close $path: $!";
    return $text;
}

__END__

=pod

=head1 NAME

t/142-action-pin-provenance.t - the action-pin provenance gate's own regression
suite

=head1 PURPOSE

Prove that C<script/audit-action-pins> reaches the right verdict for every shape
of action pin: correct, stale-runtime, falsely-commented, and unresolvable. It
covers the gate's decision logic, not GitHub's behaviour.

=head1 WHY IT EXISTS

DD-449. Every C<uses:> line in this repository is pinned to an immutable 40-hex
SHA and annotated with a C<# vX.Y.Z> comment, and
C<t/34-scorecard-guardrails.t> reads its node24 version floors out of those
comments. Nothing verified a comment against the SHA it annotated, so three pins
carried versions written from intent: C<actions/checkout> claimed C<# v5.2.2>, a
tag that has never existed upstream, over a commit that is really v4.2.2.

All three were node20 actions, and GitHub now force-runs node20 actions on
node24. C<actions/checkout> survives that; C<shogo82148/actions-setup-perl>
v1.31.3 fails with C<Error: unable to get latest version>. The C<Setup Perl>
step failed on every CI run for ten days - skipping the suite, the coverage gate
and both dependency audits - while the guardrail test certified the migration as
complete. C<script/audit-action-pins> is the check that resolves the SHA, and
this file is what keeps that check honest.

=head1 WHEN TO USE

Run it whenever C<script/audit-action-pins> changes, and as part of the full
suite. It needs no network and no credentials.

=head1 HOW TO USE

    prove -lv t/142-action-pin-provenance.t
    prove -lr t

=head1 WHAT USES IT

The full C<prove -lr t> gate, and the CI workflow that runs it.

=head1 HOW IT WORKS

Each case writes a throwaway workflow directory and a JSON fixture into a
temporary directory, then runs the gate with C<DD_ACTION_PIN_FIXTURE> pointing
at that fixture so the upstream lookups are answered from disk. That keeps the
suite hermetic and makes cases like "this tag resolves to a different commit"
expressible at all - they cannot be staged against a real upstream repository.

=head1 EXAMPLES

Check just the fail-closed behaviour while editing the gate's exit codes:

    prove -lv t/142-action-pin-provenance.t 2>&1 | grep -i unusable

Run the real, network-backed audit that this file's fixtures stand in for:

    script/audit-action-pins

=cut



( run in 1.525 second using v1.01-cache-2.11-cpan-007c89162af )