node set-version.mjs patch
node set-version.mjs minor
node set-version.mjs major
node set-version.mjs 0.0.1
Created
June 10, 2025 05:17
-
-
Save imkarimkarim/c1d08cf7ddac2709bc12d802cefc9bf7 to your computer and use it in GitHub Desktop.
React Native Expo Version Manager
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
import { execSync } from 'child_process'; | |
import fs from 'fs'; | |
import plist from 'plist'; | |
import semver from 'semver'; | |
import { Builder, parseStringPromise } from 'xml2js'; | |
// Check for clean working tree | |
const hasChanges = execSync('git status --porcelain').toString().trim().length > 0; | |
if (hasChanges) { | |
console.error('β Working tree is not clean. Please commit or stash changes first.'); | |
process.exit(1); | |
} | |
const arg = process.argv[2]; | |
if (!arg) { | |
console.error('β Provide version or bump type (patch, minor, major)'); | |
process.exit(1); | |
} | |
// --- 1. Read current version from package.json --- | |
const pkgPath = './package.json'; | |
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); | |
const currentVersion = pkg.version; | |
// --- 2. Resolve next version --- | |
let version; | |
if (['patch', 'minor', 'major'].includes(arg)) { | |
version = semver.inc(currentVersion, arg); | |
} else if (semver.valid(arg)) { | |
version = arg; | |
} else { | |
console.error(`β Invalid version or bump type: ${arg}`); | |
process.exit(1); | |
} | |
console.log(`π§ Updating version: ${currentVersion} β ${version}`); | |
// --- Helper function --- | |
function updateJSONFile(filePath, updater) { | |
const data = JSON.parse(fs.readFileSync(filePath, 'utf8')); | |
const updated = updater(data); | |
fs.writeFileSync(filePath, JSON.stringify(updated, null, 2)); | |
console.log(`β Updated ${filePath}`); | |
} | |
// --- Update app.json --- | |
updateJSONFile('./app.json', data => { | |
if (data.expo) data.expo.version = version; | |
return data; | |
}); | |
// --- Update package.json --- | |
updateJSONFile(pkgPath, data => { | |
data.version = version; | |
return data; | |
}); | |
// --- Update AndroidManifest.xml --- | |
const manifestPath = './android/app/src/main/AndroidManifest.xml'; | |
if (fs.existsSync(manifestPath)) { | |
const manifestXml = fs.readFileSync(manifestPath, 'utf8'); | |
const manifestObj = await parseStringPromise(manifestXml); | |
fs.writeFileSync(manifestPath, new Builder().buildObject(manifestObj)); | |
console.log(`β Verified ${manifestPath}`); | |
} | |
// --- Update build.gradle --- | |
const gradlePath = './android/app/build.gradle'; | |
if (fs.existsSync(gradlePath)) { | |
let gradleText = fs.readFileSync(gradlePath, 'utf8'); | |
gradleText = gradleText | |
.replace(/versionName\s+"[^"]+"/, `versionName "${version}"`) | |
.replace( | |
/versionCode\s+\d+/, | |
`versionCode ${semver.major(version)}${semver.minor(version)}${semver.patch(version)}` | |
); | |
fs.writeFileSync(gradlePath, gradleText); | |
console.log(`β Updated ${gradlePath}`); | |
} | |
// --- Update Info.plist --- | |
const plistPath = './ios/Rumis/Info.plist'; | |
if (fs.existsSync(plistPath)) { | |
const rawPlist = fs.readFileSync(plistPath, 'utf8'); | |
const plistData = plist.parse(rawPlist); | |
plistData.CFBundleShortVersionString = version; | |
plistData.CFBundleVersion = version; | |
fs.writeFileSync(plistPath, plist.build(plistData)); | |
console.log(`β Updated ${plistPath}`); | |
} | |
// --- Create git tag --- | |
try { | |
// Format code | |
execSync('yarn format'); | |
console.log('β Formatted code'); | |
// Check if there are changes | |
const hasChanges = execSync('git status --porcelain').toString().trim().length > 0; | |
if (hasChanges) { | |
// Commit version changes | |
execSync('git add .'); | |
execSync(`git commit -m "chore: bump version to ${version}"`); | |
console.log(`β Committed version changes`); | |
} else { | |
console.log('βΉοΈ No changes to commit'); | |
} | |
// Create and push tag | |
execSync(`git tag -a v${version} -m "Release v${version}"`); | |
execSync('git push --follow-tags'); | |
console.log(`β Created and pushed git tag v${version}`); | |
} catch (error) { | |
console.error('β Git operation failed:', error.message); | |
} | |
console.log('π Done!'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment