Improving Git Flow for Managing Private TypeScript Dependencies on Bitbucket
In our current workflow, Bitbucket serves both as a code repository and a private NPM repository. Installing dependencies via git+ssh
and specifying a tag
is very convenient for pure JavaScript projects.
As some dependencies started using TypeScript, we need to manage them in one of the following ways:
- Directly commit the compiled
dist
files to the main/master branch. - Compile during
postinstall
. Upon dependency installation, it automatically compiles.
However, both methods have their drawbacks.
- Directly committing
dist
to the main branch adds many extra files during code review, making the project structure less elegant. - Using
postinstall
requires installingtypescript
additionally for pure JavaScript projects, which is also not elegant.
Considering the manpower and repository migration costs (we have nearly 100 dependencies, each with many versions and used by different services), we can only address these issues by improving Git flow.
Objectives
The redesigned Git flow should meet the following objectives:
- Development branches should not contain compiled
dist
files. - Compilation should not rely on
postinstall
. - Dependency installation should remain unchanged, still via
git+ssh
and specifyingtag
. - Consideration for
hotfix
scenarios.
Improved Git Flow
To achieve the above objectives, here is the improved Git flow:
For regular development, after merging code into master
, we first push the src
tag and modify .gitignore
to temporarily create a build
branch. Then, we compile on the build
branch and tag it formally, including the dist
files, which can be referenced by other services.
When a hotfix
is needed, we can branch off from the corresponding src
tag to fix and then merge back into the master
branch following the same steps.
Pipeline Script Configuration
The Git flow described above involves tagging, modifying .gitignore
, compiling, and then releasing after code merges. Even with documentation, it’s prone to errors in practice. Thus, it’s crucial to automate these steps using Bitbucket Pipeline upon merging code into the master
branch.
Here is an example:
- Pipeline section:
1 |
|
- Tagging and compilation script:
The build.sh script in the pipeline is the core of the Git flow. It tags the source, compiles, and pushes the compiled formal tag.
The version of the tag follows semver rules, with the current tag being fetched from package.json’s version. The next version is derived from the prefix of the branch name, e.g., for major/xxxx, the next version increments the major version; for feature/xxx, it increments the minor version. It uses npm version command to upgrade the tag.
1 |
|
It’s recommended to execute Shell scripts within the Deployment section because it’s a blocking queue, ensuring only one script runs at a time, thus avoiding tag duplication issues.
Also, certain naming restrictions should be imposed on development branches, for instance, using tools like Husky.
Expansion
This Git flow can be applied in any code hosting tool, even without triggering methods like Pipeline/GitAction; it can still be achieved by running scripts. It also enables automatic tagging.
Although there’s no perfect Git flow, a suitable one can standardize our work and enhance efficiency.
(Translated by ChatGPT)