How to Manage Different Versions of an OpenAI Plugin: A Complete Guide

To manage different versions of an OpenAI plugin, update the version field in the plugin's .codex-plugin/plugin.json manifest, commit the change, and create a matching Git tag (e.g., v1.2.0) that triggers your CI/CD pipeline.

OpenAI plugins in the openai/plugins repository follow a self-contained directory structure where each plugin manages its own lifecycle independently. Because every plugin stores its canonical version inside a plugin.json manifest file, you can release updates to individual plugins without affecting others in the monorepo.

Understanding the Plugin Version Structure

Each plugin resides in its own subdirectory under plugins/ and follows a standardized layout that isolates version metadata from implementation code.

The Canonical Manifest File

The .codex-plugin/plugin.json file serves as the canonical manifest that declares the plugin's identity and version. According to the openai/plugins source code, this JSON file contains the version field that the OpenAI Plugin Store and Codex runtime read during installation.

In plugins/zoom/.codex-plugin/plugin.json, the version field follows semantic versioning conventions:

{
  "name": "zoom",
  "version": "1.1.0",
  "description": "Schedule and manage Zoom meetings"
}

Supporting Configuration Files

While plugin.json holds the authoritative version, two additional components complete the plugin structure:

  • .app.json – Stores application-specific identifiers such as OAuth client IDs and secrets (e.g., plugins/zoom/.app.json)
  • skills/ – Directory containing skill definitions that implement the plugin's behavior (e.g., plugins/zoom/skills/)

Version Management Workflow

Managing releases requires coordination between manifest updates and repository tags. The version declared in plugin.json must match the Git tag for automated publishing to function correctly.

Semantic Versioning Best Practices

Increment the version field following semantic versioning (MAJOR.MINOR.PATCH):

  • MAJOR – Breaking changes to the API or skill definitions
  • MINOR – New functionality that maintains backward compatibility
  • PATCH – Bug fixes and minor improvements

Update plugins/zoom/.codex-plugin/plugin.json only after testing changes in the corresponding skills/ directory.

Git Tagging Strategy

After updating the manifest, create a Git tag that matches the version string exactly. If the manifest reads 1.1.0, tag the commit as v1.1.0 or 1.1.0 depending on your CI configuration.

This two-step process ensures that:

  • The Codex runtime detects the new version when loading the plugin
  • CI pipelines can validate that the tag and manifest agree before publishing

Automating Version Validation

Manual version updates introduce human error. Implement GitHub Actions to enforce consistency between Git tags and plugin.json declarations.

CI Pipeline Implementation

The following workflow triggers on version tags and validates that the tag matches the manifest version:

name: Verify Plugin Version
on:
  push:
    tags:
      - 'v*'

jobs:
  check-version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Extract version from plugin.json
        id: version
        run: |
          PLUGIN=$(git diff --name-only ${{ github.ref }}~1 ${{ github.ref }} | head -n1 | cut -d'/' -f1-3)
          VERSION=$(jq -r .version $PLUGIN/.codex-plugin/plugin.json)
          echo "plugin=$PLUGIN" >> $GITHUB_OUTPUT
          echo "version=$VERSION" >> $GITHUB_OUTPUT
      - name: Fail if tag ≠ version
        run: |
          TAG=${{ github.ref_name }}
          if [[ "$TAG" != "v${{ steps.version.outputs.version }}" ]]; then
            echo "Tag $TAG does not match version ${{ steps.version.outputs.version }}"
            exit 1
          fi

This validation prevents mismatched releases where the Git history claims version 1.2.0 but the manifest still reads 1.1.0.

Handling Multiple Release Streams

Because each plugin lives in an isolated directory under plugins/, you can maintain different versions across plugins without interference. However, supporting multiple release streams (stable and beta) for a single plugin requires branch management.

Branching Strategies

Create separate branches for different release channels:

  • main – Stable releases tagged with standard semantic versions
  • beta – Pre-release versions tagged with suffixes like v1.2.0-beta.1

Update plugin.json in the respective branch, then tag accordingly. CI pipelines can route beta tags to staging environments while releasing stable tags to the Plugin Store.

Practical Version Update Examples

Updating Versions with jq

Automate version bumps using jq to modify JSON and standard Git commands:


# Example: update the Zoom plugin from 1.0.2 → 1.1.0

PLUGIN_DIR=plugins/zoom/.codex-plugin
NEW_VERSION=1.1.0

jq --arg v "$NEW_VERSION" '.version = $v' "$PLUGIN_DIR/plugin.json" \
  > "$PLUGIN_DIR/plugin.json.tmp" && mv "$PLUGIN_DIR/plugin.json.tmp" "$PLUGIN_DIR/plugin.json"

git add "$PLUGIN_DIR/plugin.json"
git commit -m "chore(zoom): bump version to $NEW_VERSION"
git tag "v$NEW_VERSION"
git push && git push --tags

This script atomically updates the manifest and creates the corresponding Git tag.

Runtime Version Detection

When users invoke your plugin in Codex, the runtime automatically transmits the version specified in plugin.json:

You are now using the **Zoom** plugin version **1.1.0**.  
Search my recent Zoom meetings for the discussion about pricing.

This transparency helps users report issues against specific versions and ensures compatibility with breaking changes.

Summary

  • Single source of truth: The version field in .codex-plugin/plugin.json defines the plugin version that OpenAI's systems recognize.
  • Git tag alignment: Always create Git tags matching the manifest version (e.g., v1.1.0 for version 1.1.0) to enable automated publishing.
  • Isolated versioning: Each plugin directory under plugins/ maintains independent versioning, allowing different release cycles per plugin.
  • Automated validation: Use CI pipelines to verify that Git tags and plugin.json versions match before deployment.
  • Semantic versioning: Follow MAJOR.MINOR.PATCH conventions to communicate breaking changes and feature additions clearly.

Frequently Asked Questions

Where is the version number stored in an OpenAI plugin?

The version number is stored in the plugin.json file located within the plugin's .codex-plugin directory (e.g., plugins/zoom/.codex-plugin/plugin.json). This manifest file serves as the canonical source that the OpenAI Plugin Store and Codex runtime read when loading the plugin.

What versioning scheme should I use for OpenAI plugins?

OpenAI plugins follow semantic versioning (MAJOR.MINOR.PATCH). Increment the MAJOR version for breaking API changes, MINOR for new backward-compatible features, and PATCH for bug fixes. This scheme helps users understand the impact of updates and maintains compatibility expectations.

How do I automate version validation in CI/CD?

Configure a GitHub Action that triggers on tag pushes (e.g., v*), extracts the version from plugin.json using jq, and compares it against the Git tag name. Fail the build if they don't match to prevent publishing mismatched releases. The validation script should locate the modified plugin using git diff commands.

Can I maintain different versions of the same plugin simultaneously?

Yes, by using Git branches for different release streams (e.g., main for stable and beta for pre-releases). Each branch maintains its own plugin.json version, and you tag releases accordingly (e.g., v1.0.0 vs v1.1.0-beta.1). This allows you to support stable users while testing new features.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →