Skip to main content
Version: Next

Frontend Dynamic Git Tag Generation Principle

๐Ÿงพ Component Packaging Info Writer Tool: Git Tag Writerโ€‹

This script is used to automatically traverse the component directory ./src/widgets/*/, obtain the Git information (commit, branch, user.name) of each component, and write it to the dist/{widgetName}/version.tag file. It facilitates subsequent version tracking and backtracking of packaging information.


Function Introductionโ€‹

FunctionDescription
Traverse component pathMatch ./src/widgets/*/ via glob
Get component Git infoExtract commit, branch, userName
Write version tag fileOutput to dist/{widget}/version.tag
Determine if build succeededIf index.js is not found, do not write version.tag file

Directory Structure Expectationโ€‹

src/
โ””โ”€โ”€ widgets/
โ”œโ”€โ”€ widgetA/
โ”œโ”€โ”€ widgetB/
dist/
โ””โ”€โ”€ widgetA/
โ””โ”€โ”€ index.js <- Write version.tag if exists

Core Method Explanationโ€‹

getWidgetsPath()โ€‹

StepDescription
1. globMatch all component paths ./src/widgets/*/
2. GitExecute git rev-parse and git config to get info
3. Write fileIf dist/{component}/index.js exists, write tag file

getGitInfo(cwd: string)โ€‹

Returns the Git information object under the component directory:

{
commit: 'abc123',
branch: 'main',
userName: 'yourname'
}

Output Example

{
"commit": "c7e5a4f",
"branch": "feature/widgetA",
"userName": "alice"
}

Code implementation follows:

import { globSync } from 'glob'
import { execa } from 'execa'
import slash from 'slash'
import path from 'path'
import fs from 'fs-extra'

const getWidgetsPath = async () => {
const widgetsPath = globSync(`./src/widgets/*/`)
for (let index = 0; index < widgetsPath.length; index++) {
const widgetPath = slash(widgetsPath[index])
const slashCwd = slash(process.cwd())
const cwd = slash(path.resolve(slashCwd, widgetPath))
const gitInfo = await getGitInfo(cwd)
const wPaths = widgetPath.split('/')
const widgetName = wPaths[wPaths.length - 1]
if (widgetName) {
const tag = {
commit: gitInfo.commit?.stdout,
branch: gitInfo.branch?.stdout,
userName: gitInfo.userName?.stdout,
}
const widgetTagFile = slash(
path.resolve(slashCwd, `dist/${widgetName}/version.tag`)
)
const widgetFile = slash(
path.resolve(slashCwd, `dist/${widgetName}/index.js`)
)

const isExist = fs.existsSync(widgetFile)
if (isExist) {
fs.writeJsonSync(widgetTagFile, tag)
}
}
}
}

/**
* Get git info
* @returns
*/
const getGitInfo = async (cwd) => {
const option = {
cwd,
}
async function getGitHash() {
return await execa('git', ['rev-parse', '--short', 'HEAD'], option)
}

async function getGitBranch() {
return execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], option)
}

async function getGitUserName() {
return execa('git', ['config', 'user.name'], option)
}
try {
const commit = await getGitHash()
const branch = await getGitBranch()
const userName = await getGitUserName()
return {
commit,
branch,
userName,
}
} catch (error) {
console.error(error)
return {}
}
}

const start = getWidgetsPath

export default start