From afee94b16c69c32e17737ac2ebde5fe956bec805 Mon Sep 17 00:00:00 2001 From: "David E. Wheeler" Date: Sun, 11 Aug 2024 14:32:51 -0400 Subject: [PATCH] Modernize and add GitHub Workflows * Test with Perl 5.10 - 5.40 on Linux, macOS, and Windows. * Automate release on tags starting with v. * Generate latest changes. * Update `Build.PL` to use meta-spec v2. * Update `MANIFEST.SKIP` and `.gitignore` * Add CPAN release and CI badges to README. * Replace search.cpan.org URLs and use https everywhere supported. * Update copyright date and use reference links in README. * Remove pod test from releases and add maintainer tests in `xt` directory. * Document `make_request` and `purge_code_cache`. --- .github/workflows/ci.yml | 43 +++++++++++++++++++++++ .github/workflows/release.yml | 45 ++++++++++++++++++++++++ .gitignore | 4 ++- Build.PL | 56 ++++++++++++++++++++++++------ Changes | 3 ++ MANIFEST.SKIP | 38 ++++++++++++++++---- README.md | 16 ++++++--- lib/MasonX/Interp/WithCallbacks.pm | 26 ++++++++------ t/08apache.t | 4 +-- t/09cgi.t | 2 +- t/10pod.t | 7 ---- t/lib/TestCallbacks.pm | 2 +- xt/pod-coverage.t | 6 ++++ xt/pod-spelling.t | 15 ++++++++ xt/pod.t | 7 ++++ 15 files changed, 231 insertions(+), 43 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml delete mode 100644 t/10pod.t create mode 100644 xt/pod-coverage.t create mode 100644 xt/pod-spelling.t create mode 100644 xt/pod.t diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..ff70d72 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,43 @@ +name: ✅ CI +on: + push: + branches: ['**'] + pull_request: + schedule: + - cron: '0 10 3 * *' # Monthly at 10am on the third +jobs: + test: + strategy: + matrix: + os: + - { icon: 🐧, name: ubuntu } + - { icon: 🍎, name: macos } + - { icon: 🪟, name: windows } + perl: [ '5.40', '5.38', '5.36', '5.34', '5.32', '5.30', '5.28', '5.26', '5.24', '5.22', '5.20', '5.18', '5.16', '5.14', '5.12', '5.10' ] + name: 🐪 Perl ${{ matrix.perl }} on ${{ matrix.os.icon }} + runs-on: ${{ matrix.os.name }}-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Perl + uses: shogo82148/actions-setup-perl@v1 + with: + perl-version: ${{ matrix.perl }} + - name: Install Dependencies + run: | + cpanm -v --notest --no-man-pages Module::Build + cpanm -v --notest --no-man-pages --installdeps --with-develop . + - name: Test + env: + AUTHOR_TESTING: 1 + RELEASE_TESTING: 1 + run: prove -lv + + # Make sure we can build the distribution bundle. + - name: Test Distro + if: runner.os == 'Linux' + run: | + prove -l xt + perl Build.PL + ./Build + ./Build manifest + ./Build disttest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..0e912c4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,45 @@ +name: 🚀 Release +on: + push: + tags: [v*] +jobs: + release: + name: 🚀 Release + runs-on: ubuntu-latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Check out the repo + uses: actions/checkout@v4 + - name: Setup Perl + uses: shogo82148/actions-setup-perl@v1 + - name: Install Release Dependencies + run: cpanm -qn Module::Build CPAN::Uploader + + # CPAN + - name: Package the Release + id: package + run: perl Build.PL && ./Build manifest && ./Build dist && echo "tarball=$(./Build tarball_name)" >> $GITHUB_OUTPUT + - name: Generate Release Changes + run: ./Build latest_changes + - name: Release on CPAN + env: + CPANPASS: ${{ secrets.CPAN_PASSWORD }} + CPANUSER: ${{ secrets.CPAN_USERNAME }} + run: cpan-upload --user "$CPANUSER" --password "$CPANPASS" '${{ steps.package.outputs.tarball }}' + + # GitHub + - name: Create GitHub Release + id: release + uses: actions/create-release@v1 + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + body_path: latest_changes.md + - name: Upload Release Asset + uses: actions/upload-release-asset@v1 + with: + upload_url: ${{ steps.release.outputs.upload_url }} + asset_path: ./${{ steps.package.outputs.tarball }} + asset_name: ${{ steps.package.outputs.tarball }} + asset_content_type: application/gzip diff --git a/.gitignore b/.gitignore index 4978162..4f07548 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,6 @@ /Build /Makefile* /pm_to_blib -/t/scripts \ No newline at end of file +/t/scripts +/latest_changes.md +t/TEST diff --git a/Build.PL b/Build.PL index aa67a92..98225eb 100644 --- a/Build.PL +++ b/Build.PL @@ -1,16 +1,42 @@ use Module::Build; + my $build_pkg = eval { require Apache::TestMB } ? 'Apache::TestMB' : 'Module::Build'; -$build_pkg->new( +my $class = $build_pkg->subclass( + class => 'My::Builder', + code => q{ + sub ACTION_tarball_name { print shift->dist_dir . ".tar.gz\n" } + sub ACTION_latest_changes { + my $self = shift; + (my $dv = $self->dist_version) =~ s/^v//; + open my $in, '<:raw', 'Changes' or die "Cannot open Changes: $!\n"; + open my $out, '>:raw', 'latest_changes.md' or die "Cannot open latest_changes.md: $!\n"; + while (<$in>) { last if /^\Q$dv\E\b/ } + print {$out} "Changes for v$dv\n"; + while (<$in>) { + last if /^\s*$/; + chomp; + if (s/^\s+-/- /) { + print {$out} "\n"; + } else { + s/^\s+/ /; + } + print {$out} $_; + } + $self->add_to_cleanup('latest_changes.md'); + } + }, +); + +$class->new( module_name => 'MasonX::Interp::WithCallbacks', license => 'perl', - configure_requires => { 'Module::Build' => '0.2701' }, - build_requires => { - 'Module::Build' => '0.2701', - 'Test::More' => '0.17', - }, + create_makefile_pl => 'traditional', + configure_requires => { 'Module::Build' => '0.4209' }, + build_requires => { 'Module::Build' => '0.4209' }, + test_requires => { 'Test::More' => '0.17' }, recommends => { 'Test::Pod' => '1.20', 'Apache::TestMB' => 0 @@ -23,10 +49,20 @@ $build_pkg->new( }, add_to_cleanup => ['t/mason'], meta_merge => { + "meta-spec" => { version => 2 }, resources => { - homepage => 'http://search.cpan.org/dist/MasonX-Interp-WithCallbacks/', - bugtracker => 'http://github.com/theory/masonx-interp-withcallbacks/issues/', - repository => 'http://github.com/theory/masonx-interp-withcallbacks/', - } + homepage => 'https://metacpan.org/pod/MasonX::Interp::WithCallbacks', + bugtracker => 'https://github.com/theory/masonx-interp-withcallbacks/issues/', + repository => 'https://github.com/theory/masonx-interp-withcallbacks', + }, + prereqs => { + develop => { + requires => { + 'Test::Pod' => '1.41', + 'Test::Pod::Coverage' => '1.06', + 'Test::Spelling' => '0.25', + }, + }, + }, }, )->create_build_script; diff --git a/Changes b/Changes index 003e5ba..593ff62 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,9 @@ Revision history for Perl extension MasonX::Interp::WithCallbacks. 1.20 + - Fixed warning with Perl 5.40. + - Added GitHub workflows with CI tests for Perl 5.10 - 5.40 on Linux, + macOS, and Windows. 1.19 2011-06-21T04:33:14 - Fixed a pasto in the "Support" section. diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP index 8c5d81e..0bcf623 100644 --- a/MANIFEST.SKIP +++ b/MANIFEST.SKIP @@ -1,11 +1,37 @@ -^_build -^Build$ -^blib +# Avoid version control files. +\bRCS\b +\bCVS\b +,v$ +\B\.svn\b +\B\.git + +# Avoid Makemaker generated and utility files. +\bMakefile$ +\bblib +\bMakeMaker-\d +\bpm_to_blib$ +\bblibdirs$ +^MANIFEST\.SKIP$ + +# Avoid Module::Build generated and utility files. +\bBuild$ +\b_build + +# Avoid temp and backup files. ~$ +\.tmp$ +\.old$ \.bak$ -^MANIFEST\.SKIP$ +\#$ +\b\.# + +# Avoid build files. ^MasonX-Interp-WithCallbacks -\.git +^[.]travis.yml ^t.TEST$ -^MYMETA\.yml$ + +# Avoid extra tests. +^xt/ + +^MYMETA.yml$ ^MYMETA\.json$ diff --git a/README.md b/README.md index a6e7dda..d41965b 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ MasonX/Interp/WithCallbacks version 1.20 ======================================== +[![🧅 CPAN version](https://badge.fury.io/pl/MasonX-Interp-WithCallbacks.svg)](https://badge.fury.io/pl/MasonX-Interp-WithCallbacks) +[![✅ Build Status](https://github.com/theory/masonx-interp-withcallbacks/actions/workflows/ci.yml/badge.svg)](https://github.com/theory/masonx-interp-withcallbacks/actions/workflows/ci.yml) + MasonX::Interp::WithCallbacks subclasses HTML::Mason::Interp in order to -provide a [Mason](http://search.cpan.org/dist/HTML-Mason) callback system -built on -[Params::CallbackRequest](http://search.cpan.org/dist/params-callbackrequest/). +provide a [Mason] callback system built on [Params::CallbackRequest]. Callbacks may be either code references provided to the `new()` constructor, -or methods defined in subclasses of Params::Callback. Callbacks are triggered +or methods defined in subclasses of [Params::Callback]. Callbacks are triggered either for every request or by specially named keys in the Mason request arguments, and all callbacks are executed at the beginning of a request, just before Mason creates and executes the request component stack. @@ -57,7 +58,12 @@ Testing of this module with HTML::Mason::ApacheHandler requires: Copyright and License --------------------- -Copyright (c) 2003-2011 David E. Wheeler. Some Rights Reserved. +Copyright (c) 2003-2024 David E. Wheeler. Some Rights Reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. + + [HTML::Mason::Interp]: https://metacpan.org/pod/HTML::Mason::Interp + [Mason]: https://metacpan.org/dist/HTML-Mason + [Params::CallbackRequest]: https://metacpan.org/pod/Params::CallbackRequest + [Params::Callback]: https://metacpan.org/pod/Params::Callback diff --git a/lib/MasonX/Interp/WithCallbacks.pm b/lib/MasonX/Interp/WithCallbacks.pm index 5aa7660..325cb58 100644 --- a/lib/MasonX/Interp/WithCallbacks.pm +++ b/lib/MasonX/Interp/WithCallbacks.pm @@ -1,7 +1,7 @@ package MasonX::Interp::WithCallbacks; use strict; -use HTML::Mason qw(1.23); +use HTML::Mason 1.23; use HTML::Mason::Interp; use HTML::Mason::Exceptions (); use Params::CallbackRequest; @@ -848,6 +848,14 @@ In this example, we have overridden the component path determined by the Mason resolver in favor of an alternate component, which will be executed, instead. +=head3 make_request + +Overrides and re-dispatches to L. + +=head3 purge_code_cache + +Overrides and re-dispatches to L. + =head2 Requester The MasonX::Interp::WithCallbacks object is available in all callback methods @@ -875,14 +883,12 @@ request, just as with C<< $r->pnotes >>. =head1 SUPPORT -This module is stored in an open L. Feel free -to fork and contribute! +This module is stored in a public +L. Feel free to +fork and contribute! -Please file bug reports via L or by -sending mail to -L. +Please file bug reports via +L. =head1 SEE ALSO @@ -899,7 +905,7 @@ create callback classes and methods. This module works with L by subclassing L. Inspired by the implementation of -callbacks in Bricolage (L), it is however a completely +callbacks in Bricolage (L), it is however a completely new code base with a rather different approach. =head1 AUTHOR @@ -908,7 +914,7 @@ David E. Wheeler =head1 COPYRIGHT AND LICENSE -Copyright 2003-2011 by David E. Wheeler. Some Rights Reserved. +Copyright 2003-2024 by David E. Wheeler. Some Rights Reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/t/08apache.t b/t/08apache.t index a09efb2..6952a7c 100644 --- a/t/08apache.t +++ b/t/08apache.t @@ -192,7 +192,7 @@ SKIP: { ), "Get redirect response" ); is( $res->code, 302, "Check redirect response code" ); - is( $res->header('Location'), 'http://example.com/', + is( $res->header('Location'), 'https://example.com/', "Check redirect location" ); is( $res->header('Age'), undef, "Check redirect Age header" ); @@ -205,7 +205,7 @@ SKIP: { ), "Get redirect without abort response" ); is( $res->code, 302, "Check redirect without abort response code" ); - is( $res->header('Location'), 'http://example.com/', + is( $res->header('Location'), 'https://example.com/', "Check redirect without abort location" ); is( $res->header('Age'), 42, "Check redirect without abort Age header" ); } diff --git a/t/09cgi.t b/t/09cgi.t index f5e2c3f..53b1d46 100644 --- a/t/09cgi.t +++ b/t/09cgi.t @@ -81,7 +81,7 @@ push @$cbs, { pkg_key => $key, ############################################################################## # Set up a redirection callback. -my $url = 'http://example.com/'; +my $url = 'https://example.com/'; sub redir { my $cb = shift; my $wait = $cb->value; diff --git a/t/10pod.t b/t/10pod.t deleted file mode 100644 index 7e138b7..0000000 --- a/t/10pod.t +++ /dev/null @@ -1,7 +0,0 @@ -#!perl -w - -use strict; -use Test::More; -eval "use Test::Pod 1.20"; -plan skip_all => "Test::Pod 1.20 required for testing POD" if $@; -all_pod_files_ok(all_pod_files('bin', 'lib')); diff --git a/t/lib/TestCallbacks.pm b/t/lib/TestCallbacks.pm index e76cfde..c20a292 100644 --- a/t/lib/TestCallbacks.pm +++ b/t/lib/TestCallbacks.pm @@ -127,7 +127,7 @@ sub count { $params->{result}++; } -my $url = 'http://example.com/'; +my $url = 'https://example.com/'; sub redir { my $cb = shift; my $wait = $cb->value; diff --git a/xt/pod-coverage.t b/xt/pod-coverage.t new file mode 100644 index 0000000..f5c8951 --- /dev/null +++ b/xt/pod-coverage.t @@ -0,0 +1,6 @@ +use Test::More; +eval "use Test::Pod::Coverage 0.08"; +plan skip_all => "Test::Pod::Coverage 0.08 required for testing POD coverage" if $@; +all_pod_coverage_ok({ + also_private => [ 'parser' ] +}); diff --git a/xt/pod-spelling.t b/xt/pod-spelling.t new file mode 100644 index 0000000..5a7bb65 --- /dev/null +++ b/xt/pod-spelling.t @@ -0,0 +1,15 @@ +#!/usr/bin/env perl + +use strict; +use Test::More; +eval "use Test::Spelling"; +plan skip_all => "Test::Spelling required for testing POD spelling" if $@; + +add_stopwords(); +all_pod_files_spelling_ok(); + +__DATA__ +Bricolage +Widgitization +preloaded +preprocess diff --git a/xt/pod.t b/xt/pod.t new file mode 100644 index 0000000..f761320 --- /dev/null +++ b/xt/pod.t @@ -0,0 +1,7 @@ +#!/usr/bin/env perl + +use strict; +use Test::More; +eval "use Test::Pod 1.41"; +plan skip_all => "Test::Pod 1.41 required for testing POD" if $@; +all_pod_files_ok();