If I made a distribution Foo and uploaded it to CPAN, I'd expect that it is install-able via various CPAN clients such as
cpm, that is, from a fresh perl installation, these commands should be successful:
cpan Foo cpanm Foo cpm install -g Foo
What's a bit non-obvious is that this requires a chain of conventions to be satisfied in order to happen smoothly... distribution Foo needs to properly ship with build procedure / installer and
META.json, in which all dependencies are correctly declared.
But that is not enough, even if I correctly authored all the meta-data in distribution Foo, if there is even a single miss in any other dependencies in Foo's dependency tree, the installation would fail.
For that reason, I thought it might be worth it to test the installation process during development, at least make a CI workflow that tries to install everything. The successful of such test would just be whether the installation is successfully finished or not. Conventionally the exit status (
$?) reflects that.
Here's something I came up with. It is a GitHub workflow that first build a distribution, a
.tar.gz file, then try to install that file with
name: Installation Test on: push: branches: - fun jobs: build: runs-on: 'ubuntu-latest' steps: - uses: actions/checkout@v2 - name: Setup Perl environment uses: shogo82148/actions-setup-perl@v1 - name: Install Authoring Dependencies run: cpanm -n App::ModuleBuildTiny && cpanm -q -n --no-man-pages --installdeps . - name: Generate dist run: mbtiny dist - name: Display what is generated run: |- echo *.tar.gz tar tvzf *.tar.gz - uses: actions/upload-artifact@v2 with: name: dist-for-installation-test path: '*.tar.gz' retention-days: 1 install: runs-on: 'ubuntu-latest' needs: build container: image: perl:5.34 steps: - uses: actions/download-artifact@v2 with: name: dist-for-installation-test - name: Display the downloaded files run: ls -R - name: Install in a perl:5.34 container (--notest) run: cpanm --notest *.tar.gz
There are a lot of instructions but what matters is the final one
cpanm --notest *.tar.gz. This would install whatever was built and all its dependencies, without running module tests`, and if even that failed, that means some meta data is missing and the distribution would not be install-able even if it is uploaded to CPAN.
Of course that is just
cpanm, I could also add
cpm there to verify whether there is a difference between all these CPAN clients. Also, I could setup a matrix run so it runs on all perl versions.
The workflow contains two jobs,
build so it is always executed after successful
build job runs on the default
ubuntu-latest machine, but the
install job runs in a container instance with presumably a different version of perl, and also without a clone of current repo. With this setup I can simulate the installation process on a fresh machine.
To share the distribution
.tar.gz file across different jobs, the only way I can fin is by uploading the file to the "artifact" storage -- basically an external storage. This probably cost me something if a lot of files are accumulated. I changed the
retention period to 1 day because I don't plan to download this anyway.
On the other hand, it could be part of doing the actual CPAN release. Maybe with some modification the workflow would build a new version with new version number, and I would just have to download the artifact then re-upload to CPAN. This would save the setup of preparing authoring tools. It could be a useful scenario for teaching new developers to upload something to CPAN.
The installation process also download a lot of stuffs from cpan.org and cost some bandwidth on the way. It's best not to do so on every commits or on a branch with frequent pushes. Definitely suitable pre-release though.
Most likely, this idea of "Installation as a test" isn't new, and it is a bit convenient to have it checked in CI.
Originally posted on gugod's blog -- CPAN installation as a test, with GitHub workflow