Versioning tracked components in a repository helps create a higher-level contracts, for the safe reuse of components between different repositories and users.
Versioning components is essential when collaborating on components to avoid breaking the different applications the components are sourced to or used in. Component versioning can get complex in complex dependency graphs and Bit does a lot to make this process as easy and efficient as possible.
Once a Bit component is tracked, you can version it using the bit tag command.
Upon tagging, Bit will apply the actions below to make sure that the component dependency graph is resolved. It will also validate that the component is isolated and can be reused outside of the repository’s context.
What happens when a component is tagged
- Version is set for the component. Bit uses SemVer to version components and provides a simple CLI interface to control SemVer for multiple components at once.
- Resolve and lock the component’s dependency graph. Bit will make sure all component dependencies are resolved. All dependencies will be written and locked for better predictability and consistency.
- Component execution and testing in an Isolated component environment. To make sure each component is truly reusable and executable outside of the original project’s context, Bit will build an isolated component environment and apply all configured extensions. Extensions may include testing execution, compiling or even docs parsing for better discoverability.
Bit and SemVer
Versioning a simple tracked component
A simple component is a component with no external dependencies, as shown in this example. Once a component is successfully tracked, and the bit status command shows the component’s status as new or modified, then the component is ready to be versioned.
$ bit status new components > hello/world
To version our new
hello/world component, use bit tag.
$ bit tag hello/world 1.0.0 1 components tagged | 1 added, 0 changed, 0 auto-tagged added components: email@example.com
As you can see, this command tagged the new component
hello/world in version
By using bit status, you can now see the component is staged and pending to be organized in a Scope.
$ bit status staged components > hello/world
In case a specific version was not specified, Bit will increment a patch version by default. This means that in the above case the command
bit tag hello/worldwill tag the component in version
0.0.1. To increment major or minor versions you can use the
--majorflags as described on the Bumping component versions section, below.
Versioning multiple components
In many cases, we’ll want to make cross-component changes or track multiple new components together.
To ease the process of versioning multiple new or modified components, bit tag exposes the
--all flag indicates to Bit to tag all new and modified components together. It can accept a specific SemVer for all components or increment each of the component’s versions individually.
To understand this better, let’s take the following component status as an example:
$ bit status new components > hello/world > ui/button modified components > string/pad-left
In this case, we have two new components (
ui/button) and one modified component (
string/pad-left). To version these components by running bit tag take a look at the following example:
$ bit tag --all 3 components tagged | 2 added, 1 changed, 0 auto-tagged added components: firstname.lastname@example.org, email@example.com changed components: firstname.lastname@example.org
As you can see, since a specific version was not specified, Bit increased all new and modified components in a single patch version.
As bit tag applies only to new and modified components, it can’t be used for aligning versions of all the components under the same Scope. To tag and align all versions under the same Scope, head over to the align local components section below.
Versioning components in a complex dependency graph
Components that depend on other components, such as this example are called ‘components with dependency tree’. If you have this structure in your components, you might sometime see that a component you haven’t modified yourself is marked as modified. That’s because a dependency of that component has been changed, and thus the dependency tree has been modified.
For example, when component
foo requires component
bar, and both are in the same project, and the component
bar is modified -
foo will be marked as modified as well, when we run the bit status command. However, the component’s source code hasn’t changed at all, but rather its dependency graph has.
This is a very basic example, but the same principle applies when there are multiple levels of dependencies between components. Bit will understand how a modification to any component on the dependency graph of the project will affect the rest of the components used, and prompt to tag the changes.
For example, let’s assume the following project structure and components.
. ├── bit.json ├── package.json └── src └── utils ├── bar.js └── foo.js
import Bar from './bar';
bit add src/utils/*.js --namespace utils bit tag --all 0.0.1
We now have two components with a dependency between them.
utils/bar.js, as follows:
Aligning all local components to the same version
After a while of working with Bit, each component will have a life of its own, and its own list of tags. However, with every major release, you might want to tag all components with the same version, so your consumers will know that this component is a part of a specific release.
--all only applies on modified or new components, you may also want to include non-modified or new components in the versioning process.
To do this, bit tag exposes the
--scope flag that enables the tagging of all components under your project’s Scope.
A simple example for using this flag would be:
bit tag --scope 1.0.1
In this example, all the Scope’s components will be tagged with version 1.0.1.
$ bit status new components > hello/world > ui/button modified components > string/pad-left
We have with two more components (
user/signup) already tagged, without applied changes.
You can view all your local components by using bit list.
bit tag --scope 3.0.0
Bumping component versions
The great thing about Semantic Versions is that the version number itself tells your consumers the type of change to expect. Usually, setting it is not an issue, as you know the version of the project you are working on, so you know which number to increment.
When working with small pieces of your project, you might not always remember which exact version each component has. Bit allows you to simply state the type of change you made, and it will bump the version accordingly.
Bumping versions is done with bit tag
--major flags. For more concrete examples, please take a look at the below section.
bit tag --all --major # Increment all modified and new components with a major version. bit tag --all --minor # Increment all modified and new components with a minor version. bit tag --all --scope --patch # Increment all components with a patch version. bit tag --scope --patch # Increment all components under the same Scope with a patch version.
If you regret tagging a version, you can easily undo it, as long as the component is still staged (meaning - there’s a tagged version that hasn’t been exported yet). This is called ‘untagging’, and is done using the untag command.
Untagging a version won’t undo the code changes associated with that version - it will only remove the version itself.
Untagging a component’s specific version
Let’s say we’ve just tagged version 1.0.0 for component
bit tag foo/bar 1.0.0
If we want to untag this version, the latest one, we can just untag the component and specify which version we want to untag.
bit untag foo/bar 1.0.0
This will revert the component’s 1.0.0 version. You can untag a version whether it’s the latest one or not, as long as it’s still staged.
Untagging a component’s staged versions
In case we want to untag all the component’s staged versions - whether there are 10, or just the one - we can untag the component without specifying a version.
Let’s say we’d just imported component
foo/bar while its latest version was 1.0.0. Afterwards, we’d made a few sets of changes and have tagged the component three minor versions.
bit tag foo/bar bit tag foo/bar bit tag foo/bar
The component’s version will now be 1.0.3, since we’ve tagged version 1.0.1, 1.0.2 and 1.0.3. Now let’s untag all of them.
bit untag foo/bar
This will remove those three staged versions, and revert the component’s version to the latest one that’s not staged - 1.0.0.
Component status changed after untagging
Once you’ve untagged all the component’s staged versions, the code changed will remain. Therefore, the component’s status will revert back to
Untagging a specific version for all the staged components
We can untag a specific staged version from all the staged components at once, by specifying the
--all option and a specific version.
bit untag --all 0.11.4
This is especially useful if we’ve aligned all local components to the same version and wish to revert it.
Untagging all the staged versions for all the components in your local scope
If we want to revert ALL the versions we’ve tagged across the whole local scope, we can use the
-all option, without specifying a version.
bit untag --all
Viewing component history
Bit provides simple tooling to view component tag history.
bit log hello/world