The direction for the GitLab product is spelled out on the Direction page. This document provides lessons and heuristics on how to design changes and new features. Our iterative process is demonstrated in a blog post.
These are core principles we believe strongly in. The goal is to build a PM system that fosters and honors these principles, in a way that works for GitLab.
From development teams to marketing organizations, everyone needs to collaborate on digital content. Content should be open to suggestions by a wide number of potential contributors. Open contribution can be achieved by using a mergeable file format and distributed version control. The mission of GitLab is to allow everyone to collaborate on all digital content so people can cooperate effectively and achieve better results, faster.
Ideas flow through many stages before they are realized. An idea originates in a chat discussion, an issue is created, it is planned in a sprint, coded in an IDE, committed to version control, tested by CI, code reviewed, deployed, monitored, and documented. Stitching together all these stages of the DevOps lifecycle can be done in many different ways. You can have a marketplace of proprietary apps from different suppliers or use a suite of products developed in isolation.
We only ship in a Minimal Viable Product (MVP) style. We call it Minimal Viable Change (MVC) because our business model is focused on adding additional value to our integrated product suite instead of building separate, new products.
MVC means we deliver the smallest possible solution that offers value to our users. To avoid feature bloat, we rely on user research to validate whether our idea addresses a market need in a desirable way. This approach sets us up to expend the smallest possible amount of effort to build new capabilities, while learning more about how to best add additional functionality over time.
While an MVC may not have the robust functionality of a fully developed feature, it should still address fundamental user needs through a bug-free and highly usable experience. The minimal viable change should not be a broken feature.
Advantages of an MVC approach:
An MVC approach is a byproduct of our spirit of iteration. That means we break problems down as small as possible, use throughput as a performance indicator, and focus on reduced cycle time. Thinking iteratively is not always intuitive, and breaking certain topics or projects down can be challenging. Here's a helpful video from our CEO with guidance on how to think more iteratively.
An MVC approach allows for maximum feedback while iterating. To help gather that feedback, Product Managers are encouraged to create feedback issues (example) to consolidate suggestions and experiences from users. Consider mentioning the feedback issue in any release post items and related implementation issue(s) for awareness.
Just because something is not invented here doesn't mean it doesn't have a perfect home within our solution. GitLab is an Open Core product and is part of the broader ecosystem of Open Source tools in the market. Every day there are new innovative tools out there that solve real-world customer problems; we should not be afraid of embedding these tools into our own products in order to solve those same problems for our customers too. Leveraging existing technology allows us to get to market much more quickly, to contribute to Open Source (and help strengthen Open Source as a whole), and allows us to focus our own people on making GitLab itself better. Building professional relationships with these tool creators also is a positive for GitLab since they may have important user perspectives around your categories.
We have achieved many successes following this approach:
There are also many more examples throughout the company where this has been successful. As a product manager you should be monitoring the world of Open Source as it relates to your area to see where new innovative tools are being developed, and not be afraid of integrating those. One thing to keep in mind, integrating could be anything from a blog post describing how the tool works together with GitLab all the way up to bundling it inside of our own installation, and this can evolve iteratively.
As an application development tool, we understand the natural inclination to create an array of buttons to press and knobs to turn.
We believe however that more options are not necessarily better, and that our users are better served by an application with reduced complexity yet still contains the features they need.
We admire other convention over configuration tools like Ruby on Rails (that doctrine of which perfectly describes the value of integrated systems), Ember, and Heroku, and strive to offer the same advantages for a continuous delivery of software.
Furthermore, Ruby on Rails has been of massive influence to the Ruby community. Uplifting it, and making it more powerful and useful than ever before, for many more usecases. We want GitLab to be to Kubernetes, what Rails is to Ruby.
You should prefer choices that are well thought out and based on current best practices. Avoid unnecessary configuration. Avoid configuration to support fragile workflows.
When considering adding new configuration, we follow the following principles:
Sometimes fast deployments are needed to fix a service or application outage that can cost a business money and reputation, we understand time is of the essence in these situations. That’s why we believe giving the team control over this is important in crucial moments of the development lifecycle
Product Managers at GitLab are frequently confronted with the choice of whether to add new configurations or not. These can frequently be times where an outside perspective is important. That's why we've created the option to request a New Config Review.
Here's an example of how to consider whether to add new configuration. Let's say you are proposing we add a checkbox or two radio boxes in a feature dialog box. Think carefully about what users really want. Most of the time, you'll find you really only need one solution, so remove the other option. When two possible choices really are necessary, the best or most common one should be the default, and the other one should be available. If the non-default choices are significantly less common, then consider taking them out of the main workflow for making decisions, by putting them behind an Advanced configuration tab, for example.
Avoiding configurations is not always possible. When we have no choice, the secondary priority is to configure something in the GitLab interface.
A configuration should only appear in a file (
gitlab.yml) as a last resort.
gitlab.ymlis the configuration file used by the Rails application. This is where the domain is configured. Other configurations should be moved to the UI as much as possible and no new configurations should be added here.
gitlab.rbis the configuration file for Omnibus-GitLab. It acts not only as an abstraction of the configuration of
gitlab.ymlfor GitLab-Rails, but also as the source for all configurations for services included and managed within the Omnibus-GitLab. Newly introduced services probably need to be configured here.
When you have to add a new configuration, make sure that the features and services are on by default. Only add a configuration line to either of these configuration files if the feature or service cannot be fully disabled from the admin UI.
Within each stage, the learning curve must be at least comparable to our best-in-class competitors, with clear, cohesive workflows, a highly usable interface, and comprehensive documentation. Product works closely with the User Experience team to achieve our user experience goals.
Below are some general user experience principles we should always keep in mind. Additional UX principles to familiarize yourself with can be found in the UX Department strategy and GitLab's Pajamas design system.
Using GitLab should be easy. Users should be thinking about the applications they are building and teams they are collaborating with, not about how to make our app work. Don't make users think!
This sounds obvious, but it can be hard to keep things simple as an application becomes more complex, with more features and more options to cover more use cases and more user types.
The good news is that the product designer assigned to your stage group has a high level of expertise in how to simplify the complex, and how to make decisions about when to add or avoid complexity. Involve product design in all changes that impact the UI.
Many crazy, over-ambitious ideas sound like they are impossible just because no one else is doing them.
Since we have amazing engineers and a culture of shipping minimal viable changes, we are able to do a lot more 'impossible' things than others.
That's why we're shipping merge conflict resolution, why we shipped built-in CI before anyone else, why we built a better static pages solution, and why we're able to compete.
Here at GitLab, we are an ambitious company and this means we aim for big things with every release. The reality of taking chances and planning aspirationally means that we won't always be able to deliver everything that we wanted to try in every release, and similar to our OKRs, we believe this is a good thing. We don't want to shy away from challenging ourselves and always want to keep a sense of urgency, and aiming for more helps us do that. Also see the importance of velocity
We arrived at our preference for ambitious planning after measuring our velocity and finding that our velocity was unchanged whether we scheduled ambitiously or scheduled for providing slack.
Feature discoverability is important for helping novice and experienced users find features that benefit them, thereby increasing the value of GitLab for them. And the more users see and try our features, the faster we can get feedback to improve them.
However, when taken too far, this can have the unwanted effect of annoying users. The end result is that the user loses trust in GitLab, and they no longer take the time to carefully parse text and other UI elements in the future. Even worse, they might leave GitLab because of this degraded experience.
Work with your product designer to improve the discoverability of your product. The Pajamas Design System has a number of patterns that support discoverability. We can also design new patterns. The Growth team can also help you with this, as they think about things like onboarding new users and promoting feature use within the app while supporting, not annoying, the user.
The following are a few illustrative examples and best practices. Dos and Donts, general best practices, examples and more details are available in Pajamas.
Banners draw attention to new features or features that have not been enabled.
Banners should be used sparingly. Think of this: Your co-worker is hard at work in front of their computer, and you suddenly tap their shoulder or yell at them to tell them about some new cool widget. You better have a good reason for that: that widget better be awesome.
Back to the analogy: Your co-worker said they don't care about that new cool widget. Never, ever, ever, bring it up again. They told you they don't care, and you need to respect that.
Leveraging navigation is an effective design paradigm to introduce a user to a new feature or area of GitLab.
If at the current moment they don't want to be disturbed, they can just ignore it because it is only a slight visual disturbance (as compared to a banner which takes up more screen real estate).
If dismissed once, it stays dismissed forever, for that user, across all clients that the user can access GitLab with.
Back to the analogy. We're not going to bother our co-worker with 5 different cool new widgets at the same time.
Shipping only MVCs can result in a large set of loosely connected pieces that don't necessarily combine into a single, great user experience.
An obvious solution to this would be to plan out the future in detail, creating a long-term detailed plan. However, this is unwanted as it can restrict your flexibility and ability to respond to changing needs or feedback.
Flow One offers an alternative. You draw out a workflow consisting of MVCs (that can be shipped individually). The workflow should only cover a specific, narrow use-case, and nothing more.
This means you:
Flow One should cover the first iteration of a particular workflow. After this, individual MVCs can be introduced to expand the use-cases or loosen the assumptions (e.g. from a feature that can only be used if you're using feature branches, to one that works for other git strategies).
See our thoughts on breadth over depth on our strategy page. While we prioritize breadth over depth, Product Managers should not lose sight of maturing each product category, with the ultimate goal of each category moving into a lovable state. A good rule of thumb to consider when planning product improvements, is that over time, approximately 70% of engineering effort should be allocated on breadth, and 30% on depth.
Using data to learn from our users is important. Our users are spread across GitLab.com and self-managed instances, so we have to focus our efforts on learning and providing benefit to both when we decide to collect more data, or build and use additional analytics tools. If we do this, we can help make the rest of the company successful as well. This means that we should:
Per GitLab Stewardship, we will not introduce artificial limits in Core. Artificial means arbitrarily setting a small number (such as: 1) as a limit on a given GitLab object category, that would incur no additional effort or cost had we chosen a larger number. The additional effort includes product, design, and engineering effort to create the feature in the first place, and to maintain it over time.
For example, GitLab Core has the issue board feature in every project. In GitLab EE, each project supports multiple boards. This does not mean that Core has an artificial limit of one board per project, because there is additional effort to manage multiple boards such as supporting the navigation interface, and all the associated engineering work.
This principle does not apply to our SaaS offering as limits are occasionally introduced to limit our hosting costs and protect other users from potential abuse. As an example we have shared runner minute quotas and implement rate limiting.
We're discussing enforced workflows in this issue.
Enforced workflows should be avoided in GitLab. For example, there are three issue
In Progress (as of 10.2), and
Closed), and any issue should be
allowed to transition from one state to any other state
without workflow restrictions. (Roles and permissions is a separate concern.)
A comment on Hacker News perfectly details what can go wrong when enforcing workflows:
"The down side for the true end-users, those who actually use the software day-to-day, is that most business processes are awful. If your experience is the hellish existence that I see strolled about on threads where JIRA comes up …:
But that comment also specifies the advantage:
"JIRA's most powerful feature is that it affords for mapping businesses processes onto software. This is incredibly compelling to enterprise customers. Software that enforces workflows, procedures and requirements can be an incredible lever and JIRA's price point makes build vs buy decisions an absolute no-brainer."
We should ensure that GitLab makes it easy to help with enterprise workflows:
When considering a customer need for enforcement or limitations:
As an example, customers requested instance-wide enforcement through required CI jobs. Doing this would have been a mistake. Instead:
Small primitives are building blocks in GitLab. They are an abstraction not at the technical level, but truly at the product level. Small primitives can be combined, built-upon further, and otherwise leveraged to create new functionality in GitLab. For example, the label lists in issue boards use the smaller primitive of labels.
They are especially powerful because they usually take less effort and provide higher leverage than you would get from a more "complete" but standalone feature. Think of how simple Unix command line utilities can be chained together to do really complicated things, much easier (and certainly more flexibly) than you could have done with a dedicated tool.
When iterating on GitLab, strongly consider using small primitives instead of creating new abstractions, especially when considering MVC features that will provide the foundations for further improvements. To do this you can start with easy to apply concepts that meet the needs of intermediate to advanced users; from here document the usage clearly and be sure to think about discoverability. The UX can very often be refactored or enhanced later when there's a demonstrated need for refinement, onboarding for less sophisticated users, or other new abstractions needed that were identified through real-world usage.
GitLab's vision is to be the best single application for every part of the DevOps toolchain. However, some customers use tools other than our included features, and we respect those decisions. With this in mind, it's sometimes valuable to integrate with 3rd-party services and products to help bridge the gaps in their toolchain. While a single application is the best approach, multiple applications that work well together is better than ones that don't.
With this in mind, below are some product guidelines to consider:
Closed source software vendors commonly depend on plugins and marketplaces because:
Because GitLab is an open core product, third parties can add functionality directly to GitLab. Adding directly to the GitLab codebase (as opposed to building a plugin) may mean more work for them and will limit the ways in which they can charge for that functionality.
However, for users of GitLab, this has significant advantages:
And for developers of GitLab including the third parties, this has significant advantages as well:
Overall, we believe that this approach creates the best possible experience for both the users of and the contributors to GitLab, and to that end we encourage people to contribute functionality to GitLab directly.
If adding code directly to GitLab isn't an option, we encourage third-parties to integrate through our APIs.
Note: GitLab does support plugins that respond to system hooks, which tie directly to application events and are primarily used for administrative purposes such as auditing, logging, and other administrative tasks.
While our big, hairy, audacious goal spans all development processes, personas, and use-cases, there are primary targets in each one of these venues. When considering prioritization we should first aim to provide complete maturity for developers building cloud native applications in a modern way prior to moving to other development methodologies, personas, and application types.
When developing features to compete with existing competitors, make sure to solve problems for modern development teams first, and then see what's missing for legacy teams. e.g. For project management, make great project management capabilities for teams doing conversational development, lean, or even agile development before doing Scaled Agile Framework (SAFe) or waterfall.
It's important that modern first does not mean non-modern never. It means that we should first learn how teams are using the feature in a modern way, and then see what's missing. The modern way provides the path forward, and then we can add customizability or the path to modern for teams who are not quite there yet.
Our strategy includes going after a lot of new personas, going from developers to operations, security, product managers, designers, etc. But when developing features in these new areas, it's important to remember to start with the developer. If we can make security great for developers and then great for security professionals, we'll be much more successful.
Development teams deploy to tons of different platforms, from bare metal to cloud VMs to cloud-native Kubernetes clusters. We build features for cloud-native first, and then support the rest. This allows us to focus on where development is going, and deliver solutions that every company aspires to use eventually, even if they're not ready to today.
By focusing on next-generation development flows, personas, and use cases - we build features and experiences where our initial users are in the relatively small population of early adopters. While we might build experiences to support them today, we presume there will always be a much larger population of future users of these experiences. Therefore, we optimize GitLab to support the larger number of current and future adopters of next-generation principles - those who are beginning to operate in the workflow (modern), team setup (developer first), or application architectures (cloud native) we support. We focus our investment in the most modern workflows that will best support those current adopters. This will come at the cost of sustained investment in initial workflows for early adopters.
For example - we first provided an application log experience based on direct scraping of logs via kubectl. After adding support for installing Elasticsearch to your Kubernetes cluster, we should not continue to invest in the kubectl log view as we'd recommend newcomers to use Elasticsearch.