Pug 3.0.0

Forbes Lindesay
May 26, 2020 · 3 min read

This week I released pug 3.0.0. This release brings a few really exciting new features, as well as a couple of small breaking changes. I also took this opportunity to update the supported versions of node.js to match the official LTS versions. The breaking changes are minimal, and should not impact most users. The highlights include:

  • The new each … of … syntax lets you iterate over Maps and Sets as well as Arrays, and is more efficient than the each … in … syntax. Don’t worry though, the old syntax is still there, and you do not have to do anything to update if you don’t want to.
  • You can now write filters that operate on binary data (e.g. images). This means you can import an image, apply a filter, and output an optimised <img/> tag with the image data inlined as a base64 string. This can improve page load times, and make your web app easier to deploy.

You can check out the full release notes on GitHub to see examples for these features, as well as a list of the (minimal) breaking changes.

Rolling Versions

Ever since I merged Pug’s many separate packages into a “mono repo”, I was frustrated by how difficult it was to do a release. There is a lot that I like about Lerna (the tool I was using to manage this mono repo), but releases were extremely error prone, and involved a lot of nail-bitingly tense work to review the commits and decide what version each package should be released as.

The issue here is the loss of context. I wanted to be able to create and manage the release notes and versioning along with the pull requests that contain the features and bug fixes. A colleague at Threads Styling introduced me to semantic-release, which we now use extensively. It lets you generate release notes and automate the release process of a single npm package, based on the commit messages. I’ve really enjoyed using semantic release, but unfortunately I encountered a few limitations:

  1. Semantic release does not work for mono repos (this was a deal breaker for pug).
  2. Semantic release requires precisely formatted commit messages. This resulted in some mistakes where releases had the wrong version, or commits did not trigger a release when they should have.
  3. Semantic release only allows one feature/bug fix/breaking change per commit. This doesn’t work well with how I like to handle pull requests.

For a long time, I’ve felt that the solution to this problem is to attach change logs directly to the pull requests, rather than the commits. For the past 6 months, I’ve been working on creating a solution that does exactly that. Rolling Versions provides a simple user interface to allow you to attach change logs to specific packages in a pull request. It then provides a CLI to publish your packages, which you can run on your continuous integration service (in this case GitHub Actions).

It’s taken a long time to get to this point, but it did finally allow me to release a new version of pug with confidence, and I expect it to enable more frequent releases in the future.

Although I still have a lot of improvements I want to make to Rolling Versions over the coming months, the beta version is now ready for you to use on your projects.

The logo for pug, a slightly sad looking cartoon dog wearing a red collar with a pendant in the shape of a bone.
The logo for pug, a slightly sad looking cartoon dog wearing a red collar with a pendant in the shape of a bone.
Pug Logo


Add change sets to pull requests. Automatically release with change logs.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store