An awesome Git Flow



```
npm i -g @cmflow/cli
CmFlow is compatible with semantic-release 📦🚀. You can use
CmFlow release to deploy your projects based on CmFlow convention.
Add the cmflow to your project:
`sh`
npm i --save-dev @cmflow/cli
Edit your package.json and add the following configuration:
`json`
{
"flow": {
"branch": {
"develop": "master",
"production": "master"
}
}
}
Then create release.config.js with this configuration:
`javascript
import { defineConfig } from '@cmflow/cli'
export default defineConfig({
verifyConditions: ['@cmflow/cli/semantic/core/verify-conditions'],
analyzeCommits: ['@cmflow/cli/semantic/core/analyze-commits'],
verifyRelease: ['@cmflow/cli/semantic/core/verify-release'],
generateNotes: [
[
"@cmflow/cli/semantic/conditional", // add this task to trigger build npm task
{
// when: (context) => context.branch.type === "release" // default condition to run the task
run: ["@semantic-release/core/release-notes-generator"]
}
]
],
prepare: [
'@cmflow/cli/semantic/core/prepare/bump-version',
[
'@cmflow/cli/semantic/core/prepare/run', // add this task to trigger build npm task
{
command: 'build'
}
],
[
'@cmflow/cli/semantic/core/prepare/run', // add this task to trigger build npm task
{
command: 'test_e2e'
}
],
[
'@cmflow/cli/semantic/core/conditional', // add this task to trigger build npm task
{
// when: (context) => context.branch.type === "release" // default condition to run the task
run: [
'@cmflow/cli/semantic/core/prepare/commit'
]
}
]
],
publish: [
[
'@cmflow/cli/semantic/core/conditional',
{
// when: (context) => context.branch.type === "release" // default condition to run the task
run: [
'@cmflow/cli/semantic/core/sync-repository',
'@semantic-release/github'
] // only run if the conditional rule is true
}
],
[
'@cmflow/cli/semantic/core/exit', // run process.exit(0) if the branch is not a release branch - legacy: maybe not necessary now all task are conditional
{
when: (context) => context.nextRelease.channel === 'prerelease'
}
]
],
success: [
[
'@cmflow/cli/semantic/core/conditional',
{
// when: (context) => context.branch.type === "release" // default condition to run the task
run: '@semantic-release/github' // only run if the conditional rule is true
}
]
],
fail: [
[
"@cmflow/cli/semantic/core/conditional",
{
// when: (context) => context.branch.type === "release" // default condition to run the task
run: '@semantic-release/github' // only run if the conditional rule is true
}
]
],
npmPublish: false
})
`
Then edit your package.json add the following tasks on script property:
`json`
{
"script": {
"release": "cmrelease",
"release_dry_run": "cmrelease --dry-run"
}
}
Now, CmFlow and semantic release are correctly installed on your project.
CMFlow provide a @cmflow/cli/semantic/core/conditional task to run one task or many task only if a condition is true. The condition is a
function that takes the semantic context as parameter and return a boolean.
You can customize the condition to run the task by adding a when property to the configuration object.
`javascript`
export default defineConfig({
publish: [
'@cmflow/cli/semantic/core/conditional',
{
when: (context) => context.branch.type === 'release', // default condition to run the task
run: ['@semantic-release/github', '@semantic-release/github'] // only run if the conditional rule is true
}
]
})
This plugin synchronizes your remote repository after publishing:
- It pushes the current branch to the remote (with --set-upstream) if it is part of the candidate branches.
- It then synchronizes the development branch with the production branch if they are different.
Options:
- pluginOptions.branches: Allows you to explicitly define the list of branches that must be pushed to synchronize the remote. Example:
`javascript`
export default defineConfig({
publish: [
[
'@cmflow/cli/semantic/core/conditional',
{
run: [
[
'@cmflow/cli/semantic/core/sync-repository',
{ includes: ['main', 'develop', 'release'] }
],
'@semantic-release/github'
]
}
]
]
})
Default behavior:
- If pluginOptions.branches is not provided, the plugin falls back to semantic-release's branches configuration (options.branches). Values can be strings or branch objects; in the latter case, only the branch name is used.
Notes:
- PRODUCTION_BRANCH and DEVELOP_BRANCH are defined via the CmFlow configuration (flow.branch.production and flow.branch.develop) and are used for the synchronization between production and develop.
CmFlow release is able to run build and test_e2e task during the prepare step. It's useful when you want topackage.json
deploy a docker image on docker hub with the right revision number in the . The only requirement, is tobuild
have a and test_e2e tasks in you npm scripts.
Example:
`json`
{
"scripts": {
"build": "docker-compose build",
"test_e2e": "docker-compose up -d && sleep 10 && npm run test_cucumber && docker-compose stop"
}
}
Then:
`javascript`
export default defineConfig({
prepare: [
[
'@cmflow/cli/semantic/core/run',
{
command: 'build'
}
],
[
'@cmflow/cli/semantic/core/run',
{
command: 'test_e2e'
}
]
]
})
CmFlow release generate a release.info file in the root of your project. This file contains the branch name.
`js
import { defineConfig } from '@cmflow/cli'
export default defineConfig({
prepare: [
'@cmflow/cli/semantic/prepare/bump-version',
[
'@cmflow/cli/semantic/prepare/release-info',
{
path: './resources/release.info'
}
]
]
})
`
Add the following configuration to your release.config.js:
`js
import { defineConfig } from '@cmflow/cli'
export default defineConfig({
publish: [
'@cmflow/cli/semantic/docker/publish'
]
});
`
`js
import { defineConfig } from '@cmflow/cli'
export default defineConfig({
success: [
'@cmflow/cli/semantic/docker/success'
]
})
`
CmFlow release can be used with Travis CI, Circle CI and GitLab. You have to create these environments variables to
allow git release note deployment, commit push and docker image deployment.
| Variable | Description |
|------------------------|---------------------------------------------------------------------------------------------------------------------------------|
| PROJECT_NAME | The project to publish artifact on docker |
| SCM_TOKEN | A SCM Token (GH_TOKEN or GITLAB_TOKEN) |
| GH_TOKEN (deprecated) | A GitHub token personal access token. |
| GIT_USER_EMAIL | User mail to sign the commit produced by CmFlow release |
| GIT_USER_NAME | User name to sign the commit produced by CmFlow release |
| DOCKER_HUB_ID | The docker hub id |
| DOCKER_HUB_PWD | The docker password account |
The jira-releases command lists and (optionally) updates Jira versions related to an application version, then generates a share-ready delivery note.
(e.g., https://your-instance.atlassian.net)
- JIRA_EMAIL
- JIRA_TOKEN (API token)
- Optional: HTTPS_PROXY if you need a proxy
- Optional (to trigger a Directus workflow):
- DIRECTUS_URL
- DIRECTUS_FLOW_ID
- DIRECTUS_ACCESS_TOKENIf all three Directus variables are present,
CmFlow considers CAN_TRIGGER_WORKFLOW=true and will attempt to run the workflow after updating releases.$3
`sh
cm jira-releases --project-id --component --tag [--update] [--verbose]
`Aliases and options (from
bin/cm-jira-releases.js):-
-c, --component : Jira component filter (e.g., API).
- -c, --project-id : Jira project key (e.g., CMAB).
- -t, --tag : target version to analyze (e.g., 0.3241.3, v0.3241.3, or version-0.3241.3). v and version- prefixes are automatically ignored.
- -u, --update: updates Jira (marks the version(s) as released with today's date and moves the issues).
- -v, --verbose: verbose logs.Note: Jira versions are expected to follow
or similar. For example, if --component API and a Jira version is named API-0.3241.3, the 0.3241.3 part will be compared to --tag using semver.$3
1. Fetch all Jira versions for the project (projectId).
2. Keep those whose version (after stripping component-, version-, and v prefixes) is semver <= the provided --tag.
3. Print the delivery note to stdout (example below).
4. If --update is provided:
- Mark the relevant version(s) as released=true with releaseDate=YYYY-MM-DD (today's date).
5. If the Directus config is complete, trigger the workflow by passing the list of version values for the processed releases.> Important: moving issue isn't supported from the cmflow. You have to create a jira automation script to move the issue on your board.
$3
From this repo, a sample script is provided in
package.json:`sh
yarn jira_releases
`which runs, with
.env loaded:`sh
node --env-file=.env bin/cm.js jira-releases \
--project-id CMAB \
--component API \
--tag 0.3241.3 \
--verbose
`Raw CLI example:
`
cm jira-releases --project-id CMAB --component API --tag v0.3241.3 --update
`$3
- Use a valid semver --tag (the v/version- prefixes are accepted).
- Ensure your Jira versions follow a consistent schema that includes the component () to allow matching.
- First run without --update to preview the note and verify selected versions and issues.
- Provide HTTPS_PROXY` if your environment requires it to reach Jira/Directus.