Pull Request previews for Open Source libraries with Netlify
When authoring OSS libraries testing is essential, unit tests are a good start, but you also want to make sure it works on a real app, let's setup pull request preview apps with Netlify!
What does the title even mean?
I get it, the title is hard to understand, but bear with me, I will walk you through the problem and one possible solution.
Let's say you wrote your first open source (or not) library, you wrote unit tests for it, and you have an example web app where you can test the library and check that it is working as expected, for now, you test it locally using npm link (or something similar). As a solo developer, this works just fine.
Now, people have jumped in to help you write the new features for your library, but they need a safe way to test the changes in a real app and show the reviewer a working example of it. Making the reviewers download the sample app, the new code and running npm link for every PR does not scale.
Let's fix this with pull request preview apps for libraries.
What is a pull request preview app?
If you use a "pull request based" workflow, a preview app is like having a "staging" or "pre-production" server for each of your branches or pull requests (PR). You basically have one copy of your entire application (or almost your entire app) for each PR/branch. If you had never used this and have the opportunity to try it out at work or in some side projects, trust me, it feels like heaven!
If you are still here, you might be wondering why not to write end-to-end (e2e) tests and you would be done. E2E tests are expensive and in some cases hard to write, so, this solution is for those cases where e2e is too much and you only need some basic "manual e2e" testing of your library. Moreover, you can even deploy the sample app as an example of usage of your library for end users, it is a win-win!
We need some simple things to achieve this:
- Library to test, we are going to use vue-preferences
- Sample application for the library, here we use vue-preferences/sample-app
- A way to link the new library code to the sample application, we use npm-link
- A way to deploy a preview application for PRs, for this we chose Netlify
::: warning WARNING From now on I will provide steps assuming the items listed previously, but you can follow the steps replacing each "ingredient" with your specific needs. The general idea should apply. If you need help, let me know in the comments or @fedekauffman! :::
Step 1: Library with a sample app
The first step is to have the sample app in the same repository as the library you want to enable previews for, there are other ways of achieving this, but this is probably the most convenient one and "forces" you to keep the sample app up-to-date.
Here is a simplified tree view of the vue-preferences library including the sample-app:
... ├── examples │ └── sample-app <--- This is the sample app │ ├── package.json │ ├── public │ ├── src │ └── yarn.lock ├── package.json ├── src │ └── index.js <--- This is the library code ├── tests │ ... └── yarn.lock
Step 2: Linking the library
Next, you have to figure out how to create a build of your sample app that uses the latest code available in your repository in the current branch, luckily, if you are using
npm that is very easy!
- Enter the library repository and run
- Build it, in this case, we use
- Go to the sample app folder
npm link vue-preferences
- Built it,
yarn buildor for live reload (if you have it set up),
At this point, you should have the sample app running with the latest code in your branch!
Step 3: Deploying with Netlify
Since this example runs around a VueJS library and a web sample application it makes sense to use a service like Netlify to deploy static assets. If it's not the case and your library is a CLI (or anything not web) you could, for example, use Heroku to launch a Dyno where you can run some test commands.
From Step 2 we know how to build the sample app with the library, we now just need to put that in the
netlify.toml file and we are done:
# By default all the branches/PRs build using the latest commit # available in the branch. [build] base = "." publish = "examples/sample-app/dist" command = """ yarn build && \ npm link && \ cd examples/sample-app && \ yarn install && \ npm link vue-preferences && \ yarn build --mode development """ # The master branch just builds whatever is defined in the package.json # This is because you probably want the production sample app to be stable # and not just build whatever is in the repository [context.master] base = "examples/sample-app" publish = "examples/sample-app/dist" command = "yarn build"
Now, every time you push a new commit your sample app gets built with the latest code in the repository, moreover, if you open a pull request you will get an isolated sample app to test the library code. Cool right :nerd_face:?
This approach might not work for every library, you might need to adapt it to your needs, but now you have a starting point!
This was actually merged to master in vue-preferences (PR 18) and you can see a test pull request (PR 19) which adds a
console.log statement to the library code which is then successfully built into the preview application :tada:.