Sentry has become the default choice for many of our teams when it comes to front-end error reporting. The convenience of features like the grouping of errors or defining patterns for discarding errors with certain parameters helps deal with the flood of errors coming from many end user devices. Integrating Sentry in your CD pipeline allows you to upload source maps for more efficient error debugging, and it helps easily trace back which errors occurred in which version of the software. We also appreciate that while Sentry is primarily a SaaS offering, its source code is publicly available and it can be used for free for smaller use cases and self-hosting.
Making the web inclusive requires serious attention to ensure accessibility is considered and validated at all stages of software delivery. Many of the popular accessibility testing tools are designed for testing after a web application is complete; as a result, issues are detected late and often are harder to fix, accumulating as debt. In our recent internal work on Thoughtworks websites, we included the open-source accessibility (a11y) testing engine axe-core as part of our build processes. It provided team members with early feedback on adherence to accessibility rules, even during early increments. Not every issue can be found through automated inspection, though. Extending the functionality of axe-core is the commercially available axe DevTools, including functionality that guides team members through exploratory testing for a majority of accessibility issues.
Since we last wrote about dbt, we've used it in a few projects and like what we've seen. For example, we like that dbt makes the transformation part of ELT pipelines more accessible to consumers of the data as opposed to just the data engineers building the pipelines. It does this while encouraging good engineering practices such as versioning, automated testing and deployment. SQL continues to be the lingua franca of the data world (including databases, warehouses, query engines, data lakes and analytical platforms) and most of these systems support it to some extent. This allows dbt to be used against these systems for transformations by just building adaptors. The number of native connectors has grown to include Snowflake, BigQuery, Redshift and Postgres, as has the range of community plugins. We see tools like dbt helping data platforms become more "self service" capable.
Flipper is an extensible mobile application debugger. Out of the box it supports profiling, interactive layout inspection, log viewer and a network inspector for iOS, Android and React Native applications. Compared to other debugging tools for mobile apps, we find Flipper to be lightweight, feature rich and easy to set up.
We wrote about Great Expectations in the previous edition of the Radar. We continue to like it and have moved it to Trial in this edition. Great Expectations is a framework that enables you to craft built-in controls that flag anomalies or quality issues in data pipelines. Just as unit tests run in a build pipeline, Great Expectations makes assertions during execution of a data pipeline. We like its simplicity and ease of use — the rules stored in JSON can be modified by our data domain experts without necessarily needing data engineering skills.
We've had a bit more experience performance testing with k6 since we first covered it in the Radar, and with good results. Our teams have enjoyed the focus on the developer experience and flexibility of the tool. Although it's easy to get started with k6 all on its own, it really shines with its ease of integration into a developer ecosystem. For example, using the Datadog adapter, one team was quickly able to visualize performance in a distributed system and identify significant concerns before releasing the system to production. Another team, with the commercial version of k6, was able to use the Azure pipelines marketplace extension to wire performance tests into their CD pipeline and get Azure DevOps reporting with little effort. Since k6 supports thresholds that allow for automated testing assertions out of the box, it's relatively easy to add a stage to your pipeline that detects performance degradation of new changes, adding a powerful feedback mechanism for developers.
MLflow is an open-source tool for machine-learning experiment tracking and lifecycle management. The workflow to develop and continuously evolve a machine-learning model includes a series of experiments (a collection of runs), tracking the performance of these experiments (a collection of metrics) and tracking and tweaking models (projects). MLflow facilitates this workflow nicely by supporting existing open standards and integrates well with many other tools in the ecosystem. MLflow as a managed service by Databricks on the cloud, available in AWS and Azure, is rapidly maturing, and we've used it successfully in our projects. We find MLflow a great tool for model management and tracking, supporting both UI-based and API-based interaction models. Our only growing concern is that MLflow is attempting to deliver too many conflating concerns as a single platform, such as model serving and scoring.
OR-Tools is an open-source software suite for solving combinatorial optimization problems. These optimization problems have a very large set of possible solutions, and tools like OR-Tools are quite helpful in seeking the best solution. You can model the problem in any one of the supported languages — Python, Java, C# or C++ — and choose the solvers from several supported open-source or commercial solvers. We've successfully used OR-Tools in multiple optimization projects with integer and mixed-integer programming.
Playwright allows you to write Web UI tests for Chromium and Firefox as well as WebKit, all through the same API. The tool has gained some attention for its support of all the major browser engines which it achieves by including patched versions of Firefox and Webkit. We continue to hear positive experience reports with Playwright, in particular its stability. Teams have also found it easy to migrate from Puppeteer, which has a very similar API.
We welcome the increased availability and maturity of infrastructure configuration scanning tools: Prowler helps teams scan their AWS infrastructure setups and improve security based on the results. Although Prowler has been around for a while, it has evolved a lot over the past few years, and we've found it very valuable to enable teams to take responsibility for proper security with a short feedback loop. Prowler categorizes AWS CIS benchmarking checks into different groups (Identity and Access Management, Logging, Monitoring, Networking, CIS Level 1, CIS Level 2, EKS-CIS), and it includes many checks that help you gain insights into your PCI DSS and GDPR compliance.
While duck typing is certainly seen as a feature by many Python programmers, sometimes — especially for larger codebases — type checking can be useful, too. For that reason a number of type annotations are proposed as Python Enhancement Proposals (PEPs), and Pyright is a type checker that works with these annotations. In addition, it provides some type inference and guards that understand conditional code flow constructs. Designed with large codebases in mind, Pyright is fast, and its watch mode checks happen incrementally as files are changed to further shorten the feedback cycle. Pyright can be used directly on the command line, but integrations for VS Code, Emacs, vim, Sublime, and possibly other editors are available, too. In our experience, Pyright is preferable to alternatives like mypy.
Adopting a "you build it, you run it" DevOps philosophy means teams have increased attention on both technical and business metrics that can be extracted from the systems they deploy. Often we find that analytics tooling is difficult to access for most developers, so the work to capture and present metrics is left to other teams — long after features are shipped to end users. Our teams have found Redash to be very useful for querying product metrics and creating dashboards in a way that can be self-served by general developers, shortening feedback cycles and focusing the whole team on the business outcomes.
Terratest caught our attention in the past as an interesting option for infrastructure testing. Since then, our teams have been using it, and they're very excited about it because of its stability and the experience it provides. Terratest is a Golang library that makes it easier to write automated tests for infrastructure code. Using infrastructure-as-code tools such as Terraform, you can create real infrastructure components (such as servers, firewalls, or load balancers) to deploy applications on them and then validate the expected behavior using Terratest. At the end of the test, Terratest can undeploy the apps and clean up resources. This makes it largely useful for end-to-end tests of your infrastructure in a real environment.
Tuple is a relatively new tool optimized for remote paired programming, designed to fill the gap Slack left in the marketplace after abandoning Screenhero. Although it still exhibits some growing pains — platform availability is limited to Mac OS for now (with Linux support coming soon), and it has some UI quirks to work through — we've had good experience using it within those constraints. Unlike general-purpose video- and screen-sharing tools like Zoom, Tuple supports dual control with two mouse cursors, and unlike options such as Visual Studio Live Share, it isn't tied to an IDE. Tuple supports voice and video calls, clipboard sharing, and lower latency than general-purpose tools; and its ability to let you draw and erase in your pair's screen with ease makes Tuple a very intuitive and developer-friendly tool.
When working with React, we often encounter situations where our page is very slow because some components are re-rendering when they shouldn't be. Why Did You Render is a library that helps detect why a component is re-rendering. It does this by monkey patching React. We've used it in a few of our projects to debug performance issues with great effect.
Even though Docker has become the sensible default for containerization, we're seeing new players in this space that are catching our attention. That is the case for Buildah and Podman, which are complementary projects to build images (Buildah) and run containers (Podman) using a rootless approach in multiple Linux distributions. Podman introduces a daemonless engine for managing and running containers which is an interesting approach in comparison to what Docker does. The fact that Podman can use either Open Container Initiative (OCI) images built by Buildah or Docker images makes this tool even more attractive and easy to use.
CI servers and build tools are some of the oldest and most widely used in our kit. They run the gamut from simple cloud-hosted services to complex, code-defined pipeline servers that support fleets of build machines. Given our experience and the wide range of options already available, we were initially skeptical when GitHub Actions were introduced as another mechanism to manage the build and integration workflow. But the opportunity for developers to start small and easily customize behavior means that GitHub Actions are moving toward the default category for smaller projects. It's hard to argue with the convenience of having the build tool integrated directly into the source code repository. An enthusiastic community has emerged around this feature and that means a wide range of user-contributed tools and workflows are available to get started. Tools vendors are also getting on board via the GitHub Marketplace. However, we still recommend you proceed with caution. Although code and Git history can be exported into alternative hosts, a development workflow based on GitHub Actions can't. Also, use your best judgment to determine when a project is large or complex enough to warrant an independently supported pipeline tool. But for getting up and running quickly on smaller projects, it's worth considering GitHub Actions and the ecosystem that is growing around them.
Graal Native Image is a technology that compiles Java code into an operating system's native binary — in the form of a statically linked executable or a shared library. A native image is optimized to reduce the memory footprint and startup time of an application. Our teams have successfully used Graal native images, executed as small Docker containers, in the serverless architecture where reducing start time matters. Although designed for use with programming languages such as Go or Rust that natively compile and require smaller binary sizes and shorter start times, Graal Native Image can be equally useful to teams that have other requirements and want to use JVM-based languages.
Graal Native Image Builder, native-image, supports JVM-based languages — such as Java, Scala, Clojure and Kotlin — and builds executables on multiple operating systems including Mac OS, Windows and multiple distributions of Linux. Since it requires a closed-world assumption, where all code is known at compile time, additional configuration is needed for features such as reflection or dynamic class loading where types can't be deduced at build time from the code alone.
HashiCorp Boundary combines the secure networking and identity management capabilities needed for brokering access to your hosts and services in one place and across a mix of cloud and on-premise resources if needed. Key management can be done by integrating the key management service of your choice, be it from a cloud vendor or something like HashiCorp Vault. HashiCorp Boundary supports a growing number of identity providers and can be integrated with parts of your service landscape to help define permissions, not just on host but also on a service level. For example, it enables you to control fine-grained access to a Kubernetes cluster, and dynamically pulling in service catalogs from various sources is on the roadmap. All of this stays out of the way of the engineering end users who get the shell experience they're used to, securely connected through Boundary's network management layer.
Remember the research project pix2code that showed how to automatically generate code from GUI screenshots? Now there is a productized version of this technique — imgcook is a SaaS product from Alibaba that can intelligently transform various design files (Sketch/PSD/static images) into front-end code. Alibaba needs to customize a large number of campaign pages during the Double Eleven shopping festival. These are usually one-time pages that need to be developed quickly. Through the deep-learning method, the UX's design is initially processed into front-end code and then adjusted by the developer. Our team is evaluating this tech: although the image processing takes place on the server side while the main interface is on the web, imgcook provides tools that could integrate with the software design and development lifecycle. imgcook can generate static code as well as some data-binding component code if you define a DSL. The technology is not perfect yet; designers need to refer to certain specifications to improve the accuracy of code generation (which still needs to be adjusted by developers afterward). We've always been cautious about magic code generation, because the generated code is usually difficult to maintain in the long run, and imgcook is no exception. But if you limit the usage to a specific context, such as one-time campaign pages, it's worth a try.
Longhorn is a distributed block storage system for Kubernetes. There are many persistent storage options for Kubernetes; unlike most, however, Longhorn is built from the ground up to provide incremental snapshots and backups, thereby easing the pain of running a replicated storage for non–cloud-hosted Kubernetes. With the recent experimental support for ReadWriteMany (RWX) you can even mount the same volume for read and write access across many nodes. Choosing the right storage system for Kubernetes is a nontrivial task, and we recommend you assess Longhorn based on your needs.
Operator Framework is a set of open-source tools that simplifies building and managing the lifecycle of Kubernetes operators. The Kubernetes operator pattern, originally introduced by CoreOS, is an approach to encapsulate the knowledge of operating an application using Kubernetes native capabilities; it includes resources to be managed and controller code that ensures the resources are matching their target state. This approach has been used to extend Kubernetes to manage many applications, particularly the stateful ones, natively. Operator Framework has three components: Operator SDK, which simplifies building, testing and packaging Kubernetes operators; Operator lifecycle manager to install, manage and upgrade the operators; and a catalog to publish and share third-party operators. Our teams have found Operator SDK particularly powerful in rapidly developing Kubernetes-native applications.
The number of services offered by the big cloud providers keeps growing, but so does the convenience and maturity of tools that help you use them securely and efficiently. Recommender is a service on Google Cloud that analyzes your resources and gives you recommendations on how to optimize them based on your actual usage. The service consists of a range of "recommenders" in areas such as security, compute usage or cost savings. For example, the IAM Recommender helps you better implement the principle of least privilege by pointing out permissions that are never actually used and therefore are potentially too broad.
Over the past few years Windows Subsystem for Linux (WSL) has come up a few times in our discussions. Although we liked what we saw, including the improvements in WSL 2, it never made it into the Radar. In this edition we want to highlight an extension for Visual Studio Code that greatly improves the experience working with WSL. Although Windows-based editors could always access files on a WSL file system, they were unaware of the isolated Linux environment. With the Remote - WSL extension, Visual Studio Code becomes aware of WSL, allowing developers to launch a Linux shell. This also enables debugging of binaries running inside WSL from Windows. Jetbrains' IntelliJ too has seen steady improvement in its support for WSL.
One of the patterns we've seen repeat itself in this publication is that static error- and style-checking tools emerge quickly after a new language gains popularity. These tools are generically known as linters — after the classic and beloved Unix utility lint, which statically analyzes C code. We like these tools because they catch errors early, before code even gets compiled. The latest instance of this pattern is Spectral, a linter for YAML and JSON. Although Spectral is a generic tool for these formats, its main target is OpenAPI (the evolution of Swagger) and AsyncAPI. Spectral ships with a comprehensive set of out-of-the-box rules for these specs that can save developers headaches when designing and implementing APIs or event-driven collaboration. These rules check for proper API parameter specifications or the existence of a license statement in the spec, among other things. While this tool is a welcome addition to the API development workflow, it does raise the question of whether a non-executable specification should be so complex as to require an error-checking technique designed for programming languages. Perhaps developers should be writing code instead of specs?
Yelp detect-secrets is a Python module for detecting secrets within a codebase; it scans files within a directory looking for secrets. It can be used as a Git pre-commit hook or to perform a scan in multiple places within the CI/CD pipeline. It comes with a default configuration that makes it very easy to use but can be modified to suit your needs. You can also install custom plugins to add to its default heuristic searches. Compared to similar offerings, we found that this tool detects more types of secrets with its out-of-the-box configuration.
As the API specification ecosystem matures, we're seeing more tools built to automate style checks. Zally is a minimalist OpenAPI linter that helps to ensure an API conforms to the team's API style guide. Out of the box, it will validate against a rule set developed for Zalando's API style guide, but it also supports a Kotlin extension mechanism to develop custom rules. Zally includes a web UI that provides an intuitive interface for understanding style violations and includes a CLI that makes it easy to plug into your CD pipeline.
Based on the experiences of multiple Thoughtworks teams we suggest approaching AWS CodePipeline with caution. Specifically, we've found that once teams move beyond simple pipelines, this tool can become hard to work with. While it may seem like a "quick win" when first starting out with AWS, we suggest taking a step back and checking whether AWS CodePipeline will meet your longer-term needs, for example, pipeline fan-out and fan-in or more complex deployment and testing scenarios featuring nontrivial dependencies and triggers.