How to Version a Codex Plugin: Complete Guide to Semantic Versioning
You version a Codex plugin by updating the version field in .codex-plugin/plugin.json following semantic versioning (MAJOR.MINOR.PATCH), then committing the change and creating a matching Git tag.
In the OpenAI plugins repository, the manifest file serves as the single source of truth for plugin identity and release management. The plugin.json file located in the .codex-plugin/ directory contains the authoritative version string that the Codex plugin evaluator, marketplace UI, and CI pipelines all reference during validation and publishing workflows.
Understanding the Codex Plugin Manifest
The .codex-plugin/plugin.json file is the canonical source for plugin metadata. According to the specification in .agents/skills/plugin-creator/references/plugin-json-spec.md, this JSON object must include a version property that follows strict semantic versioning rules.
The Zoom plugin provides a concrete example of this structure:
{
"name": "zoom",
"version": "1.0.2",
...
}
All downstream tooling reads the version from this location exclusively. The evaluator script at plugins/plugin-eval/src/evaluators/plugin.js validates that this field exists and conforms to expected formats before allowing publication.
Semantic Versioning Requirements
Codex plugins follow semantic versioning (MAJOR.MINOR.PATCH) to communicate compatibility guarantees:
- MAJOR – Increment when introducing breaking API changes that require users to update their integration code.
- MINOR – Increment when adding backward-compatible features or enhancements.
- PATCH – Increment when making backward-compatible bug fixes or documentation updates.
The version string in .codex-plugin/plugin.json must strictly adhere to this format without prefixes or suffixes (unless using pre-release labels specified in the plugin JSON spec).
Step-by-Step Versioning Workflow
1. Choose the Appropriate Version Bump
Determine whether your changes warrant a major, minor, or patch increment based on the scope of modifications. Breaking changes to the plugin's API surface require a major version bump, while new capabilities that maintain backward compatibility warrant a minor bump.
2. Update the Manifest File
Edit .codex-plugin/plugin.json to reflect the new version number. This is the only location where the version is stored; all other systems read from this file.
For automated updates using sed:
sed -i "s/\"version\": \".*\"/\"version\": \"1.1.0\"/" .codex-plugin/plugin.json
For Node.js-based plugins, you can leverage npm version which updates both package.json and writes the corresponding version to the Codex manifest:
npm version minor
3. Commit and Tag the Release
Create a Git commit with the manifest changes, then tag the commit with a version tag matching the manifest:
git commit -am "Bump to 1.1.0"
git tag v1.1.0
This tagging convention allows CI systems to locate the exact source code corresponding to any release.
4. Validate Before Publishing
Run the built-in evaluator to catch manifest errors before they reach production:
pnpm run plugin-eval
# Or directly:
node plugins/plugin-eval/src/evaluators/plugin.js
The validator checks for the presence of required fields including the version property and ensures proper formatting.
5. Update the Marketplace Entry (Optional)
If your plugin appears in the marketplace index, update the version field in .agents/plugins/marketplace.json to ensure the UI displays the latest version to users:
{
"plugins": [
{
"name": "zoom",
"version": "1.1.0"
}
]
}
Automation Examples
Node.js Version Bumping Script
Use this helper script to programmatically increment versions using the semver library:
// bump-version.js – run from repo root
const fs = require('fs');
const path = require('path');
const semver = require('semver');
const manifestPath = path.join(__dirname, 'plugins/zoom/.codex-plugin/plugin.json');
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
const newVersion = semver.inc(manifest.version, 'patch'); // 'patch' | 'minor' | 'major'
manifest.version = newVersion;
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
console.log(`✅ Bumped to ${newVersion}`);
Python Marketplace Updater
For updating the marketplace registry programmatically:
import json, pathlib
marketplace_path = pathlib.Path('.agents/plugins/marketplace.json')
data = json.loads(marketplace_path.read_text())
# Find the entry and update its version
for p in data['plugins']:
if p['name'] == 'zoom':
p['version'] = '1.0.3' # match the manifest version
break
marketplace_path.write_text(json.dumps(data, indent=2))
print("Marketplace version updated.")
CI Validation Pipeline
This GitHub Actions workflow verifies that Git tags match the manifest version before publishing:
name: Release Plugin
on:
push:
tags: 'v*.*.*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Verify manifest version matches tag
run: |
TAG=${GITHUB_REF#refs/tags/}
VERSION=$(jq -r .version .codex-plugin/plugin.json)
if [ "v$VERSION" != "$TAG" ]; then
echo "Version mismatch! Manifest $VERSION vs Tag $TAG"
exit 1
fi
- name: Publish
run: ./scripts/publish.sh
Key Files in the Versioning System
.codex-plugin/plugin.json– Primary manifest containing the authoritative version string..agents/skills/plugin-creator/references/plugin-json-spec.md– Specification document defining version semantics and validation rules.plugins/plugin-eval/src/evaluators/plugin.js– Validation logic that checks version field presence and format..agents/plugins/marketplace.json– Marketplace index for UI version display.
Summary
- Store versions exclusively in
.codex-plugin/plugin.json– this is the single source of truth referenced by all tools. - Follow semantic versioning (MAJOR.MINOR.PATCH) to communicate compatibility guarantees to users.
- Automate version bumps using
npm version, custom scripts, or CI pipelines to maintain consistency across Git tags and marketplace entries. - Validate changes with the
plugin-evalevaluator before publishing to catch malformed manifests early. - Tag releases in Git with the
vprefix matching the manifest version to enable reproducible builds.
Frequently Asked Questions
Where is the version number stored in a Codex plugin?
The version number is stored in the .codex-plugin/plugin.json file within the version field. This file serves as the single source of truth, and all tooling—including the evaluator in plugins/plugin-eval/src/evaluators/plugin.js and the marketplace registry—reads the version from this location.
What happens if my version doesn't follow semantic versioning?
The Codex plugin evaluator checks the version field during validation. While the system may accept non-semver strings, following semantic versioning is strongly recommended because the marketplace UI and downstream CI pipelines expect this format. Breaking these conventions may cause integration failures with automated release tools.
How do I automate version bumps for my plugin?
Use the npm version <major|minor|patch> command for Node.js projects, which updates the manifest and creates Git tags automatically. Alternatively, implement a custom script using the semver library to increment versions in .codex-plugin/plugin.json, then commit the changes and push tags to trigger CI/CD pipelines.
Should I update the marketplace.json file manually?
Yes, if your plugin is listed in .agents/plugins/marketplace.json, you must manually update the version field there after bumping the manifest version. This ensures the marketplace displays the correct version to users. Some organizations automate this through the plugin-creator skill or CI scripts that sync the marketplace entry with the manifest.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →