Skip to content

Commit 4c33773

Browse files
committed
chore: sync versioning across all targets and update build scripts
Introduced a new script to synchronize version numbers across multiple files, ensuring consistency. Updated build scripts to incorporate version checks and adjustments for both desktop and iOS builds. Adjusted references in configuration files to reflect the new versioning approach.
1 parent c92e3a5 commit 4c33773

8 files changed

Lines changed: 192 additions & 45 deletions

File tree

next-env.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// <reference types="next" />
22
/// <reference types="next/image-types/global" />
3-
import "./.next/types/routes.d.ts";
3+
import "./.next/dev/types/routes.d.ts";
44

55
// NOTE: This file should not be edited
66
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
"desktop:dev": "pnpm exec tauri dev",
99
"ios:dev": "node scripts/tauri-ios-dev.mjs",
1010
"desktop:check": "tsc --noEmit",
11-
"desktop:build": "cross-env CI=true pnpm exec tauri build --bundles app",
11+
"desktop:build": "node scripts/sync-versions.mjs --check && cross-env CI=true pnpm exec tauri build --bundles app",
1212
"desktop:package": "cross-env CI=true pnpm exec tauri build",
13-
"ios:build": "cross-env CI=true pnpm exec tauri ios build",
13+
"ios:build": "node scripts/sync-versions.mjs --check && cross-env CI=true pnpm exec tauri ios build",
1414
"desktop:build:debug": "pnpm exec tauri build --debug",
1515
"desktop:release": "pnpm desktop:check && pnpm desktop:package",
1616
"desktop:sign": "./scripts/sign-and-deploy.sh",
@@ -28,6 +28,9 @@
2828
"secrets:scan": "bash ./scripts/secrets-scan.sh history",
2929
"secrets:scan:staged": "bash ./scripts/secrets-scan.sh staged",
3030
"secrets:baseline": "bash ./scripts/secrets-scan.sh baseline",
31+
"version:sync": "node scripts/sync-versions.mjs",
32+
"version:check": "node scripts/sync-versions.mjs --check",
33+
"release": "node scripts/release.mjs",
3134
"policy:skill-first": "node scripts/preflight-skill-first.mjs staged",
3235
"policy:skill-first:ci": "node scripts/preflight-skill-first.mjs ci",
3336
"prepare": "husky"

scripts/build-release.sh

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,14 @@ verify() {
110110
((FAIL++))
111111
fi
112112

113-
# 8. Version consistency
114-
log "Version consistency…"
115-
PKG_V=$(node -e "console.log(require('./package.json').version)")
116-
TAURI_V=$(node -e "console.log(require('./src-tauri/tauri.conf.json').version)")
117-
if [ "$PKG_V" = "$TAURI_V" ]; then
118-
ok "Versions match: v$PKG_V"
113+
# 8. Version consistency (desktop + iOS — all 5 locations)
114+
log "Version consistency (all targets)…"
115+
if node scripts/sync-versions.mjs --check 2>/dev/null; then
116+
ok "All version locations match: v$(node -e "console.log(require('./package.json').version)")"
119117
((PASS++))
120118
else
121-
warn "Version mismatch: package.json=$PKG_V tauri.conf.json=$TAURI_V"
119+
warn "Version drift detected — run: pnpm version:sync"
120+
node scripts/sync-versions.mjs --check 2>&1 | grep "" || true
122121
((FAIL++))
123122
fi
124123

scripts/release-macos.sh

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,14 @@ xcrun notarytool store-credentials --help > /dev/null 2>&1 || {
6363
command -v gh > /dev/null || { echo " ✗ gh CLI not found"; exit 1; }
6464
echo " ✓ All checks passed"
6565

66-
# ── 2. Bump versions ────────────────────────────────────────────────
66+
# ── 2. Bump versions (all targets via sync-versions) ────────────────
6767
echo ""
68-
echo "▸ [2/10] Bumping version to ${VERSION}..."
68+
echo "▸ [2/10] Bumping version to ${VERSION} (desktop + iOS)..."
6969

70-
# package.json
71-
sed -i '' "s/\"version\": \"[^\"]*\"/\"version\": \"${VERSION}\"/" package.json
70+
node scripts/sync-versions.mjs "${VERSION}"
71+
node scripts/sync-versions.mjs --check
7272

73-
# tauri.conf.json
74-
sed -i '' "s/\"version\": \"[^\"]*\"/\"version\": \"${VERSION}\"/" src-tauri/tauri.conf.json
75-
76-
# Cargo.toml (only the first version line)
77-
sed -i '' "0,/^version = \".*\"/s//version = \"${VERSION}\"/" src-tauri/Cargo.toml
78-
79-
echo " ✓ package.json, tauri.conf.json, Cargo.toml → ${VERSION}"
73+
echo " ✓ All version locations → ${VERSION}"
8074

8175
# ── 3. Build frontend + Tauri ───────────────────────────────────────
8276
echo ""
@@ -158,7 +152,7 @@ echo ""
158152
echo "▸ [9/10] Committing and tagging..."
159153

160154
git add package.json src-tauri/tauri.conf.json src-tauri/Cargo.toml src-tauri/Cargo.lock src-tauri/Entitlements.plist 2>/dev/null || true
161-
git add package.json src-tauri/tauri.conf.json src-tauri/Cargo.toml
155+
git add package.json src-tauri/tauri.conf.json src-tauri/Cargo.toml src-tauri/gen/apple/project.yml src-tauri/gen/apple/app_iOS/Info.plist
162156
git commit -m "chore: release v${VERSION}" --allow-empty 2>/dev/null || true
163157
git tag -f "v${VERSION}" -m "v${VERSION}"
164158
git push origin main 2>/dev/null || true

scripts/release.mjs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
#!/usr/bin/env node
22
/**
3-
* Release helper — bumps version, commits, tags, and optionally pushes.
3+
* Release helper — bumps version across ALL targets, commits, tags, and optionally pushes.
44
*
55
* Usage:
66
* pnpm release <version> [--push]
77
*
88
* Examples:
9-
* pnpm release 1.0.0 # bump + tag locally
10-
* pnpm release 1.2.0 --push # bump + tag + push (triggers CI release)
9+
* pnpm release 1.11.0 # bump + tag locally
10+
* pnpm release 1.11.0 --push # bump + tag + push (triggers CI release)
11+
*
12+
* Bumps: package.json, tauri.conf.json, Cargo.toml, project.yml, Info.plist
1113
*/
1214

1315
import { execSync } from 'child_process'
14-
import { readFileSync, writeFileSync } from 'fs'
1516
import { resolve, dirname } from 'path'
1617
import { fileURLToPath } from 'url'
1718

@@ -20,7 +21,7 @@ const args = process.argv.slice(2)
2021
const version = args.find(a => /^\d+\.\d+\.\d+(\S+)?$/.test(a))
2122

2223
if (!version) {
23-
console.error('Usage: pnpm release <version> e.g. pnpm release 1.0.0 --push')
24+
console.error('Usage: pnpm release <version> e.g. pnpm release 1.11.0 --push')
2425
process.exit(1)
2526
}
2627

@@ -38,24 +39,23 @@ try {
3839
process.exit(1)
3940
}
4041

41-
// ── Bump package.json ──────────────────────────────────────────────────────
42-
const pkgPath = resolve(root, 'package.json')
43-
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'))
44-
const prev = pkg.version
45-
pkg.version = version
46-
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n')
47-
console.log(` package.json ${prev}${version}`)
42+
// ── Bump ALL version locations via sync-versions ──────────────────────────
43+
execSync(`node scripts/sync-versions.mjs ${version}`, { stdio: 'inherit', cwd: root })
4844

49-
// ── Bump src-tauri/tauri.conf.json ────────────────────────────────────────
50-
const tauriConfPath = resolve(root, 'src-tauri/tauri.conf.json')
51-
const tauriConf = JSON.parse(readFileSync(tauriConfPath, 'utf8'))
52-
tauriConf.version = version
53-
writeFileSync(tauriConfPath, JSON.stringify(tauriConf, null, 2) + '\n')
54-
console.log(` tauri.conf.json → ${version}`)
45+
// ── Verify they all match ─────────────────────────────────────────────────
46+
execSync('node scripts/sync-versions.mjs --check', { stdio: 'inherit', cwd: root })
5547

5648
// ── Commit & tag ──────────────────────────────────────────────────────────
5749
const tag = `v${version}`
58-
execSync('git add package.json src-tauri/tauri.conf.json', { stdio: 'inherit', cwd: root })
50+
const filesToStage = [
51+
'package.json',
52+
'src-tauri/tauri.conf.json',
53+
'src-tauri/Cargo.toml',
54+
'src-tauri/gen/apple/project.yml',
55+
'src-tauri/gen/apple/app_iOS/Info.plist',
56+
].join(' ')
57+
58+
execSync(`git add ${filesToStage}`, { stdio: 'inherit', cwd: root })
5959
execSync(`git commit -m "chore: release ${tag}"`, { stdio: 'inherit', cwd: root })
6060
execSync(`git tag ${tag}`, { stdio: 'inherit', cwd: root })
6161
console.log(`\n Tagged ${tag}`)

scripts/sync-versions.mjs

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#!/usr/bin/env node
2+
/**
3+
* Single source of truth: package.json → all other version locations.
4+
*
5+
* Usage:
6+
* node scripts/sync-versions.mjs # sync from package.json
7+
* node scripts/sync-versions.mjs 1.11.0 # set explicit version everywhere
8+
* node scripts/sync-versions.mjs --check # assert all locations match (exit 1 on drift)
9+
*/
10+
11+
import { readFileSync, writeFileSync } from 'fs'
12+
import { resolve, dirname } from 'path'
13+
import { fileURLToPath } from 'url'
14+
15+
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..')
16+
17+
const LOCATIONS = {
18+
'package.json': {
19+
read(content) {
20+
return JSON.parse(content).version
21+
},
22+
write(content, version) {
23+
const obj = JSON.parse(content)
24+
obj.version = version
25+
return JSON.stringify(obj, null, 2) + '\n'
26+
},
27+
},
28+
'src-tauri/tauri.conf.json': {
29+
read(content) {
30+
return JSON.parse(content).version
31+
},
32+
write(content, version) {
33+
const obj = JSON.parse(content)
34+
obj.version = version
35+
return JSON.stringify(obj, null, 2) + '\n'
36+
},
37+
},
38+
'src-tauri/Cargo.toml': {
39+
read(content) {
40+
const m = content.match(/^version\s*=\s*"([^"]+)"/m)
41+
return m ? m[1] : null
42+
},
43+
write(content, version) {
44+
return content.replace(/^(version\s*=\s*")[^"]+(")/m, `$1${version}$2`)
45+
},
46+
},
47+
'src-tauri/gen/apple/project.yml': {
48+
read(content) {
49+
const m = content.match(/CFBundleShortVersionString:\s*(\S+)/)
50+
return m ? m[1] : null
51+
},
52+
write(content, version) {
53+
return content
54+
.replace(/(CFBundleShortVersionString:\s*)\S+/, `$1${version}`)
55+
.replace(/(CFBundleVersion:\s*)"[^"]+"/, `$1"${version}"`)
56+
},
57+
},
58+
'src-tauri/gen/apple/app_iOS/Info.plist': {
59+
read(content) {
60+
const m = content.match(/<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/)
61+
return m ? m[1] : null
62+
},
63+
write(content, version) {
64+
return content
65+
.replace(
66+
/(<key>CFBundleShortVersionString<\/key>\s*<string>)[^<]+(<\/string>)/,
67+
`$1${version}$2`,
68+
)
69+
.replace(
70+
/(<key>CFBundleVersion<\/key>\s*<string>)[^<]+(<\/string>)/,
71+
`$1${version}$2`,
72+
)
73+
},
74+
},
75+
}
76+
77+
function readVersions() {
78+
const versions = {}
79+
for (const [file, handler] of Object.entries(LOCATIONS)) {
80+
const fullPath = resolve(root, file)
81+
try {
82+
const content = readFileSync(fullPath, 'utf8')
83+
versions[file] = handler.read(content)
84+
} catch {
85+
versions[file] = null
86+
}
87+
}
88+
return versions
89+
}
90+
91+
function check() {
92+
const versions = readVersions()
93+
const source = versions['package.json']
94+
let ok = true
95+
96+
console.log(`\n Version contract check (source: package.json → ${source})\n`)
97+
98+
for (const [file, ver] of Object.entries(versions)) {
99+
if (ver === source) {
100+
console.log(` ✓ ${file.padEnd(45)} ${ver}`)
101+
} else {
102+
console.log(` ✗ ${file.padEnd(45)} ${ver ?? 'NOT FOUND'} (expected ${source})`)
103+
ok = false
104+
}
105+
}
106+
107+
console.log('')
108+
if (!ok) {
109+
console.error(' Version drift detected. Run: pnpm version:sync\n')
110+
process.exit(1)
111+
}
112+
console.log(' All versions in sync.\n')
113+
}
114+
115+
function sync(version) {
116+
console.log(`\n Syncing all version locations → ${version}\n`)
117+
118+
for (const [file, handler] of Object.entries(LOCATIONS)) {
119+
const fullPath = resolve(root, file)
120+
try {
121+
const content = readFileSync(fullPath, 'utf8')
122+
const current = handler.read(content)
123+
if (current === version) {
124+
console.log(` · ${file.padEnd(45)} ${version} (unchanged)`)
125+
continue
126+
}
127+
const updated = handler.write(content, version)
128+
writeFileSync(fullPath, updated)
129+
console.log(` ✓ ${file.padEnd(45)} ${current ?? '?'}${version}`)
130+
} catch (e) {
131+
console.error(` ✗ ${file.padEnd(45)} ${e.message}`)
132+
process.exit(1)
133+
}
134+
}
135+
136+
console.log('\n Done.\n')
137+
}
138+
139+
// ── CLI ────────────────────────────────────────────────────────────
140+
const arg = process.argv[2]
141+
142+
if (arg === '--check') {
143+
check()
144+
} else {
145+
const version = arg || JSON.parse(readFileSync(resolve(root, 'package.json'), 'utf8')).version
146+
if (!/^\d+\.\d+\.\d+/.test(version)) {
147+
console.error(`Invalid version: ${version}`)
148+
process.exit(1)
149+
}
150+
sync(version)
151+
}

src-tauri/gen/apple/app_iOS/Info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
<key>CFBundlePackageType</key>
1616
<string>APPL</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>1.6.0</string>
18+
<string>1.10.0</string>
1919
<key>CFBundleVersion</key>
20-
<string>1.6.0</string>
20+
<string>1.10.0</string>
2121
<key>LSRequiresIPhoneOS</key>
2222
<true/>
2323
<key>UILaunchStoryboardName</key>

src-tauri/gen/apple/project.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ targets:
5252
- UIInterfaceOrientationPortraitUpsideDown
5353
- UIInterfaceOrientationLandscapeLeft
5454
- UIInterfaceOrientationLandscapeRight
55-
CFBundleShortVersionString: 1.6.0
56-
CFBundleVersion: "1.6.0"
55+
CFBundleShortVersionString: 1.10.0
56+
CFBundleVersion: "1.10.0"
5757
entitlements:
5858
path: app_iOS/app_iOS.entitlements
5959
scheme:

0 commit comments

Comments
 (0)