Makefile校验Git Tag与package.json版本一致性时无论匹配与否均报错的解决方法
Makefile
enforce-versions Target Always Exits with Code 1 (Even When Versions Match) Let’s break down why your current setup fails, and fix it step by step:
Root Cause
Your issue stems from two key problems:
- Quoted version string from
jq: By default,jq .version package.jsonoutputs the version wrapped in double quotes (e.g.,"1.1.0"). When you prepend av, yourPKG_VERSIONvariable becomesv"1.1.0"(with embedded quotes), whileLATEST_TAGfromgit describeis a clean string likev1.1.0(no quotes). These values never match, so Make’sifeqcondition always evaluates to false, triggeringexit 1. - Misuse of Make’s
ifeqin rule commands: Make processesifeqconditions during the rule-parsing phase, not at runtime when shell commands execute. This leads to unexpected behavior when working with dynamically generated values like git tags or package.json versions.
Fixed Makefile (String Comparison)
First, fix the jq call to get an unquoted version string with the -r (raw output) flag. Then replace Make’s ifeq with a shell if statement for runtime evaluation:
# Get package version without quotes, prepend 'v' PKG_VERSION=v$(shell jq -r .version package.json) # Get latest git tag LATEST_TAG=$(shell git describe --tags --abbrev=0 $$(git rev-list --tags --max-count=1)) enforce-versions: @echo "Comparing \"$(PKG_VERSION)\" & \"$(LATEST_TAG)\"" @if [ "$(PKG_VERSION)" = "$(LATEST_TAG)" ]; then \ echo "Versions match - proceeding with CI"; \ exit 0; \ else \ echo "ERROR: Versions do NOT match - aborting CI"; \ exit 1; \ fi
Semantic Version Comparison (More Robust)
If you need to handle semantic versioning correctly (e.g., avoiding string comparison bugs like v1.10.0 being treated as "less than" v1.9.0), use a dedicated semver tool. For example, with the Node.js semver package:
Install it in your CI environment (if not already present):
npm install -g semverUpdate the
enforce-versionstarget:enforce-versions: @echo "Comparing \"$(PKG_VERSION)\" & \"$(LATEST_TAG)\"" @if semver eq $(PKG_VERSION) $(LATEST_TAG); then \ echo "Versions match - proceeding with CI"; \ exit 0; \ else \ echo "ERROR: Versions do NOT match - aborting CI"; \ exit 1; \ fi
How This Works
- The
jq -rflag ensures we get a raw, unquoted version string frompackage.json, soPKG_VERSIONmatches the format of your git tags exactly. - Using a shell
ifstatement ensures the comparison happens at runtime, right when you runmake enforce-versions, avoiding pre-parsing surprises from Make. - The semver-based check handles edge cases in version numbering that simple string comparison can’t.
内容的提问来源于stack exchange,提问作者danielcooperxyz
相关产品推荐
相关产品推荐

