Skip to content

Commit 9307ac5

Browse files
ARHAEEMclaude
andcommitted
fix(ci): auto-detect registry versions to prevent publish collisions
The release workflow now queries the VS Code Marketplace and npm for the latest published version before bumping. It uses whichever is higher (local or registry) as the base, so the next version is always unpublished. Example: package.json=2.0.14, marketplace=2.0.15 → bumps from 2.0.15 → publishes 2.0.16. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 804746a commit 9307ac5

1 file changed

Lines changed: 58 additions & 12 deletions

File tree

.github/workflows/release.yml

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,51 +56,97 @@ jobs:
5656
- run: pnpm install -wD @vscode/vsce ovsx
5757

5858
# ── Compute versions ───────────────────────────────────────
59+
# For each target, we check both package.json AND the registry.
60+
# We bump from whichever is higher, so we never collide with
61+
# an already-published version.
62+
5963
- name: Bump extension version
6064
id: ext_version
6165
if: inputs.target == 'extension' || inputs.target == 'both'
6266
run: |
6367
PKG="packages/extension/package.json"
64-
CURRENT=$(node -p "require('./$PKG').version")
68+
LOCAL=$(node -p "require('./$PKG').version")
69+
70+
# Query VS Code Marketplace for the latest published version
71+
PUBLISHED=$(npx vsce show Nskha.airtable-formula --json 2>/dev/null \
72+
| node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{
73+
try{console.log(JSON.parse(d).versions[0].version)}
74+
catch{console.log('0.0.0')}
75+
})" || echo "0.0.0")
76+
77+
echo "Local: ${LOCAL}, Marketplace: ${PUBLISHED}"
78+
79+
# Pick the higher version as the base for bumping
80+
BASE=$(node -e "
81+
const a = '${LOCAL}'.split('.').map(Number);
82+
const b = '${PUBLISHED}'.split('.').map(Number);
83+
const cmp = a[0]-b[0] || a[1]-b[1] || a[2]-b[2];
84+
console.log(cmp >= 0 ? '${LOCAL}' : '${PUBLISHED}');
85+
")
86+
6587
NEXT=$(node -e "
66-
const [major, minor, patch] = '${CURRENT}'.split('.').map(Number);
88+
const [major, minor, patch] = '${BASE}'.split('.').map(Number);
6789
const bump = '${{ inputs.bump }}';
6890
if (bump === 'major') console.log((major+1)+'.0.0');
6991
else if (bump === 'minor') console.log(major+'.'+(minor+1)+'.0');
7092
else console.log(major+'.'+minor+'.'+(patch+1));
7193
")
72-
echo "current=${CURRENT}" >> $GITHUB_OUTPUT
94+
95+
echo "current=${BASE}" >> $GITHUB_OUTPUT
7396
echo "next=${NEXT}" >> $GITHUB_OUTPUT
97+
7498
# Write new version to package.json
7599
node -e "
76100
const fs = require('fs');
77-
const raw = fs.readFileSync('$PKG', 'utf8');
78-
fs.writeFileSync('$PKG', raw.replace(/\"version\": \"${CURRENT}\"/, '\"version\": \"${NEXT}\"'));
101+
const p = '$PKG';
102+
const pkg = JSON.parse(fs.readFileSync(p, 'utf8'));
103+
pkg.version = '${NEXT}';
104+
fs.writeFileSync(p, JSON.stringify(pkg, null, 2) + '\n');
79105
"
80-
echo "Extension: ${CURRENT} → ${NEXT}"
106+
echo "Extension: ${BASE} → ${NEXT}"
107+
env:
108+
VSCE_PAT: ${{ secrets.VSCE_PAT }}
81109

82110
- name: Bump MCP server version
83111
id: mcp_version
84112
if: inputs.target == 'mcp-server' || inputs.target == 'both'
85113
run: |
86114
PKG="packages/mcp-server/package.json"
87-
CURRENT=$(node -p "require('./$PKG').version")
115+
LOCAL=$(node -p "require('./$PKG').version")
116+
117+
# Query npm for the latest published version
118+
PUBLISHED=$(npm view airtable-user-mcp version 2>/dev/null || echo "0.0.0")
119+
120+
echo "Local: ${LOCAL}, npm: ${PUBLISHED}"
121+
122+
# Pick the higher version as the base for bumping
123+
BASE=$(node -e "
124+
const a = '${LOCAL}'.split('.').map(Number);
125+
const b = '${PUBLISHED}'.split('.').map(Number);
126+
const cmp = a[0]-b[0] || a[1]-b[1] || a[2]-b[2];
127+
console.log(cmp >= 0 ? '${LOCAL}' : '${PUBLISHED}');
128+
")
129+
88130
NEXT=$(node -e "
89-
const [major, minor, patch] = '${CURRENT}'.split('.').map(Number);
131+
const [major, minor, patch] = '${BASE}'.split('.').map(Number);
90132
const bump = '${{ inputs.bump }}';
91133
if (bump === 'major') console.log((major+1)+'.0.0');
92134
else if (bump === 'minor') console.log(major+'.'+(minor+1)+'.0');
93135
else console.log(major+'.'+minor+'.'+(patch+1));
94136
")
95-
echo "current=${CURRENT}" >> $GITHUB_OUTPUT
137+
138+
echo "current=${BASE}" >> $GITHUB_OUTPUT
96139
echo "next=${NEXT}" >> $GITHUB_OUTPUT
140+
97141
# Write new version to package.json
98142
node -e "
99143
const fs = require('fs');
100-
const raw = fs.readFileSync('$PKG', 'utf8');
101-
fs.writeFileSync('$PKG', raw.replace(/\"version\": \"${CURRENT}\"/, '\"version\": \"${NEXT}\"'));
144+
const p = '$PKG';
145+
const pkg = JSON.parse(fs.readFileSync(p, 'utf8'));
146+
pkg.version = '${NEXT}';
147+
fs.writeFileSync(p, JSON.stringify(pkg, null, 2) + '\n');
102148
"
103-
echo "MCP server: ${CURRENT} → ${NEXT}"
149+
echo "MCP server: ${BASE} → ${NEXT}"
104150
105151
# ── Build & Test ───────────────────────────────────────────
106152
- name: Build all packages

0 commit comments

Comments
 (0)