The Year in Review 2025
As usual, it's been another busy year, focused mostly of sustaining of my existing projects and setting a new record with almost 500 software releases. I've continued development of new, and adoption of some existing, tools and techniques to improve productivity and software quality. In addition, I joined the Pa11y team where work has ramped up again resulting in several needed, major releases.
Blog posts #
I didn't start this year with any specific goals for blog posts because I was so busy with other projects that I only managed two posts. They're related to subsequent topics in this post and are linked there.
Software projects #
This year was busy with software development rather than writing, with a handful of new items to note.
I joined the Pa11y team #
Last year, with some uncertainty in support for the
Pa11y projects, I had released forks of both pa11y
and pa11y-ci as interim fixes until the long-term plans of the team were
better understood. In 2025, I, and several others, joined the Pa11y team and
there has been a resurgence in development. This led to two major releases (and
a few minor/patch releases as well):
- The release of
pa11y@9.0.0, which was the first major release in over a year. - The release of
pa11y-ci@4.0.0. This was the first major release upgrading frompa11y@6.2.3(released in 2022) topa11y@9.0.0.
Work is ongoing, so expect continued support and enhancements this year. A
significant upgrade to the axe runner, improving the treatment of issues
requiring manual review (see
PR #685), is close to release.
My open source software projects #
This year was full of a lot of sustaining work on existing projects, with a few new and noteworthy items.
In 2025 I started four new projects, and between those projects and my other existing projects shipped 479 releases (63 major, 131 minor, 276 patch), which is a new record. Even though many of those were routine sustaining updates (refactoring, security patches, dependency updates, etc.), it reinforces that continuous delivery practices and extensive automation do improve productivity and the ability to confidently release software.
Full list of 2025 new projects
| Project | Description |
|---|---|
| Container Images / Kaniko | A project to build container images for Chainguard's kaniko fork. |
| Container Images / PSScriptAnalyzer | A container image to run lint and SAST analyses on PowerShell scripts with PSScriptAnalyzer. |
| Tests / Container Multi-Platform Test | A multi-platform container project to test CI jobs. |
| Tests / Node Web Test | A Node.js project to test CI pipeline jobs for web pages/applications. |
Full list of 2025 software releases
The significant projects and events for the year are summarized in the subsequent sections (ordered predominantly by significance).
NPM supply chain security #
This year saw numerous, large-scale NPM supply chain attacks. Given the ease of publishing, huge catalog of packages, casual treatment of transitive dependencies, and large developer base, it's an attractive target. I was not directly impacted, but it did open the community's eyes to the risks and force mitigating actions.
In July, NPM introduced Trusted Publishing (docs, blog post) to significantly improve the integrity of the publishing process. This eliminates the need for publishing tokens that could be compromised (which we saw this year) and focuses on publishing from CI/CD workflows on trusted platforms. Individual NPM packages must register a specific GitLab or GitHub project as the source, and the CI pipeline or workflow file with the publishing script, then that CI job from that project on that platform can use the platform OIDC to authenticate to NPM and publish projects. This, along with the elimination of long-lived publishing tokens, are significant improvements to the integrity of NPM publishing, although there's still more improvements that could be made. For my part, all of my published NPM packages have moved to trusted publishing.
In addition, it was observed that the large user base, as well as an
ever-growing list of security companies, do fairly quickly identify compromised
packages. Therefore, allowing some delay after publishing, but before adoption,
has been shown to allow community identification of many compromised packages
and take mitigating actions. With that, tools like Renovate have adopted a
default minimumReleaseAge setting for NPM packages requiring several days for
this to occur before updating, and I've adopted that philosophy in my
Renovate config presets,
which are used in all of my projects.
Type stripping is stable in Node 24 #
I don't think this got nearly as much discussion as it deserved, but with the release of Node 24.12.0 (release notes), the ability for Node to natively execute TypeScript files through type-stripping, without a build or transpilation step, is now stable in the Active LTS release (as well as Node 25, the current release). As a package author, I've published types with libraries for years, but have been resistant to fully adopting TypeScript in those packages, instead leveraging JSDoc types, because of the added overhead and complexity of a build step. The Node implementation does impose some limitations on the use of a few TypeScript features, although one (like me) could argue that these features go beyond pure typing and create new JavaScript when transpiled, so this limitation is not only tolerable, it's desirable. While it will be some time before this is stable in all supported Node versions (April 2027 by my check of the Node release schedule, which is only 15 months away), it's a significant step forward for the ecosystem.
With that, late this year I converted one CLI tool to TypeScript (see
this release),
and plan to continue as appropriate in 2026. As with implementing any
significant new capability, I starting with setting up robust automated tooling,
which in this case was an updated ESLint configuration with TypeScript parsing
and rules. Given my opinionated stance on linting, it did take some time to get
through all of the typescript-eslint rules and setup configurations that
properly supported JavaScript (CJS and ESM) and TypeScript files, but the end
result is a highly opinionated configuration that I'm happy with, which was
published as my last release of the year (see
this release).
Chainguard's Kaniko container image #
In mid-2025, after virtually no support for a year, Google officially archived Kaniko, a tool introduced in 2018 to allow building container images in Kubernetes or other containerized environments since it did not rely on the Docker daemon. Shortly afterwards, the Chainguard team, including several of the original Kaniko authors, announced that they had created and were maintaining a fork as a replacement.
While they are maintaining that fork, and have had six releases this year, they are only maintaining the code, not providing any binary artifacts, including a container image. So, I created this Kaniko project, which is simply a CI pipeline and infrastructure to build, test, and deploy a Kaniko container image (built from Kaniko's Dockerfile) to GitLab's container registry (it doesn't contain the Kaniko code, that's pulled from the Chainguard fork repository in CI). You can read the full story in this blog post.
Renovate responsiveness to GitLab repository actions #
My last project of 2024 was the GitLab Webhook Renovate Proxy, which is a Cloudflare Worker that intercepts GitLab merge request and issue webhooks and forwards those that should trigger a Renovate pipeline to re-analyze a project. This year is saw extensive use, and reinforced how effective it is in improving the responsiveness of Renovate running in GitLab CI (beyond simply running scheduled Renovate pipelines). A summary with additional detail is available in this blog post.
Mutation testing #
Last, but certainly not least, I have begun experimentation with mutation testing, incorporating StrykerJS into several of my projects to evaluate its effectiveness in improving test coverage and quality. From their website:
Mutation testing introduces changes to your code, then runs your unit tests against the changed code. It is expected that your unit tests will now fail. If they don't fail, it might indicate your tests do not sufficiently cover the code.
Bugs, or mutants, are automatically inserted into your production code. Your tests are run for each mutant. If your tests fail then the mutant is killed. If your tests passed, the mutant survived. The higher the percentage of mutants killed, the more effective your tests are.
So far it has proved easy to set up and effective at finding gaps in test coverage, although it can be slow given the numerous variations of the test suite that are run.
GitLab CI template tests #
Last year, the GitLab CI Templates project's CI pipeline was updated to trigger multi-project downstream pipelines to allow enhanced testing of templates in the appropriate project types. That was augmented this year with several new test projects to cover additional scenarios including multi-platform container images (which had new jobs and collections added in 2025) and web application testing (which was previously untested). While there are still a few jobs that are not currently tested, this testing now covers the vast majority of the GitLab CI templates project.
Contributions to other open source projects #
I also made contributions to a few other open source projects this year,
including knip and Chainguard's
fork of kaniko.
Looking forward to 2026 #
Some of the things I'm looking forward to or will hopefully be resolved in 2026 include:
- The Node.js Release Working Group team has been iterating on proposed changes to the Node.js release and support philosophy. It's not set in stone yet, but looks like it may take effect in 2026.
- This year included some evaluation of container image hardening techniques, which will continue in 2026. This includes migrating to hardened container base images (for example Docker Hardened Images, Chainguard Images, Google Distroless Images, or others) and container image and software bill-of-materials (SBOM) signing (including container registry support, which is evolving, although very slowly).
- Continuing to migrate projects to leverage mutation testing and investigate options for improving CI pipeline performance.
- The future of Kaniko, as it was this year, is a little uncertain. In addition
to the Chainguard fork, a
community fork has been getting
some attention. It doesn't have corporate backing like the Chainguard fork,
but it has been more actively developed this year, including security/bug
fixes as well as adding missing capabilities (the
--annotationflag, for example). I'll be watching both to see how they evolve this year.
Aaron Goldenthal