# How to Version and Publish Plugins to the Marketplace: A Semantic Versioning and CI/CD Guide

> Learn to version and publish plugins to the marketplace using semantic versioning and CI/CD. Follow this guide for structured configuration, testing, and submission.

- Repository: [OpenAI/plugins](https://github.com/openai/plugins)
- Tags: how-to-guide
- Published: 2026-06-07

---

**Publishing a plugin to a marketplace requires maintaining a semantic version in the plugin manifest and following a structured configuration, testing, and submission workflow.**

The `openai/plugins` repository provides end-to-end documentation and reference implementations for building marketplace-ready integrations. Whether you are targeting Zoom, Wix, or another platform, you must version and publish plugins to the marketplace using a repeatable workflow that prevents drift between your source code and the published artifact. The repository's guides cover everything from manifest versioning to OAuth scope configuration and review submission.

## Semantic Versioning for Plugin Manifests

Most marketplaces require a machine-readable version identifier in the app manifest to track changes and enforce backward-compatibility. According to the `openai/plugins` source code, the repository adopts **semantic versioning** (`MAJOR.MINOR.PATCH`) as the standard across all plugin projects. Keeping a stable version in the manifest guarantees that existing installations continue working when you ship new features or bug fixes.

### Version Bump Policy

Follow these rules when incrementing the `version` field:

- **MAJOR** — bump when you introduce a breaking API or data-model change that would break existing installations.
- **MINOR** — bump when you add a back-compatible feature or capability.
- **PATCH** — bump for bug fixes, documentation updates, or non-functional tweaks.

The repository's authoritative policy lives in [`plugins/zoom/skills/references/versioning-and-drift.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/skills/references/versioning-and-drift.md). That guide explains how to keep the marketplace entry in sync with the code and avoid version drift.

### Where the Version Lives

Most plugins expose a JSON or YAML manifest file such as [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) or [`manifest.yaml`](https://github.com/openai/plugins/blob/main/manifest.yaml) that contains a top-level `version` field. When this value is updated, the CI/CD pipeline detects the change and triggers a new build. The repository recommends automating this step with tools like `npm version` or a custom script that parses `git tag` history and writes the result into the manifest before the build runs.

```json
{
  "name": "my-awesome-zoom-app",
  "description": "Adds AI-powered insights to Zoom meetings",
  "version": "1.4.0",
  "author": "Acme Corp",
  "dependencies": {
    "@zoom/appssdk": "^0.16.26"
  }
}

```

## Publishing Plugins to the Marketplace

The core publishing flow is documented in [`plugins/zoom/skills/general/use-cases/marketplace-publishing.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/skills/general/use-cases/marketplace-publishing.md). While the examples reference Zoom, the same concepts apply to Wix, Atlassian, and other marketplaces.

### Create the Marketplace App Entry

Begin by signing into the target marketplace console and creating a new app. For Zoom, this means visiting the Zoom Marketplace, clicking **Create App**, and choosing the appropriate visibility type (**Public** or **Private**). You will fill out basic metadata including the app name, short description, logo, and **Home URL** that the client will render.

### Configure OAuth Credentials and Environment Variables

The marketplace generates a **client ID** and **client secret** that must be stored in your plugin's `.env` file. Never commit raw credential values to version control. The [`plugins/zoom/skills/zoom-apps-sdk/references/environment-variables.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/skills/zoom-apps-sdk/references/environment-variables.md) file lists the required variables:

```text
ZOOM_APP_CLIENT_ID=...
ZOOM_APP_CLIENT_SECRET=...

```

Your application code should reference these values via environment variables rather than hard-coding them. For full details on web-redirect and in-client authentication, see [`plugins/zoom/skills/zoom-apps-sdk/references/oauth.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/skills/zoom-apps-sdk/references/oauth.md).

### Domain Allow-Lists and OAuth Scopes

You must whitelist the domain that serves your assets in the marketplace UI under **Feature → Add Allow List**. Missing entries here cause runtime failures when the client attempts to load your plugin. Each API endpoint your plugin calls also requires a matching OAuth scope; omitted scopes trigger `PERMISSION_DENIED` errors at runtime. Both requirements are detailed in [`plugins/zoom/skills/zoom-apps-sdk/troubleshooting/common-issues.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/skills/zoom-apps-sdk/troubleshooting/common-issues.md).

### Local Testing and URL Synchronization

Run the plugin locally using a tunnel such as `ngrok` or `cloudflared`. Because tunnel URLs change on every restart, you must update four fields in the marketplace dashboard: Home URL, OAuth redirect URI, domain allow-list, and any webhook URLs. The [`plugins/zoom/skills/zoom-apps-sdk/troubleshooting/debugging.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/skills/zoom-apps-sdk/troubleshooting/debugging.md) guide explains how to keep these values in sync during development.

You can automate the update with a Server-to-Server OAuth token and the marketplace API:

```bash
NGROK_URL=$(ngrok http 3000 --log=stdout | grep -o 'https://[0-9a-z]*\.ngrok\.io')

curl -X PATCH "https://api.zoom.us/v2/apps/${APP_ID}" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d "{
        \"home_url\": \"$NGROK_URL\",
        \"redirect_url\": \"$NGROK_URL/callback\"
      }"

```

### Submit for Review and Publish

Once end-to-end tests pass, click **Submit for Review** in the marketplace console. The review team validates security headers, privacy compliance, and functional correctness. After approval, toggle the app's visibility to **Public** so users can install it. The version declared in your manifest becomes the published version that users see.

## Automating Version Bumps and Releases

A manual versioning process is error-prone, so the repository recommends automating it in CI/CD. The repository's CI pipeline, referenced in [`.github/workflows/publish.yml`](https://github.com/openai/plugins/blob/main/.github/workflows/publish.yml), reads the `manifest.version` field and invokes the marketplace CLI to upload the bundle.

A typical Node.js release workflow looks like this:

```bash

# 1. Bump version (patch example)

npm version patch

# 2. Push tag and commit

git push && git push --tags

# 3. CI/CD reads the new version, builds the plugin, and runs the release script

```

When you add new OAuth scopes, remember to request them in both the marketplace UI and your initialization code. For example, after adding `meeting:write` in the Zoom dashboard, update the plugin code:

```javascript
const zoom = ZoomSdk.init({
  clientId: process.env.ZOOM_APP_CLIENT_ID,
  scope: "meeting:write recording:read"
});

```

After verifying the new scope locally, resubmit the app for review because scope changes require re-approval.

## Summary

- **Semantic versioning** (`MAJOR.MINOR.PATCH`) is the standard for plugin manifests in the `openai/plugins` repository.
- Store the version in the top-level `version` field of [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) or [`manifest.yaml`](https://github.com/openai/plugins/blob/main/manifest.yaml) and automate bumps via `npm version` or `git tag` parsers.
- Publishing requires creating a marketplace entry, configuring OAuth credentials in `.env`, whitelisting domains, and selecting correct OAuth scopes as documented in [`plugins/zoom/skills/zoom-apps-sdk/references/environment-variables.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/skills/zoom-apps-sdk/references/environment-variables.md).
- Use `ngrok` or `cloudflared` for local testing, but sync the tunnel URLs in the marketplace dashboard or via API to avoid drift.
- Submit the plugin for review, then toggle it to **Public** after approval; repeat the entire workflow for every subsequent release.

## Frequently Asked Questions

### What version format should I use for marketplace plugins?

You should use **semantic versioning** (`MAJOR.MINOR.PATCH`). This is the de-facto standard documented in [`plugins/zoom/skills/references/versioning-and-drift.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/skills/references/versioning-and-drift.md). It ensures backward-compatibility guarantees and satisfies marketplace compliance requirements.

### How do I keep marketplace URLs in sync during local testing?

Run your local server behind a tunnel such as `ngrok`, then update the Home URL, redirect URI, and allow-list entries in the marketplace console. You can also automate this with a Server-to-Server OAuth token and a `PATCH` request to the marketplace API, as shown in [`plugins/zoom/skills/zoom-apps-sdk/troubleshooting/debugging.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/skills/zoom-apps-sdk/troubleshooting/debugging.md).

### Why am I seeing a PERMISSION_DENIED error after configuring OAuth?

A `PERMISSION_DENIED` error usually means you added an API call without requesting the matching OAuth scope in the marketplace UI. Every Zoom API endpoint requires a specific scope, and missing entries cause runtime failures. Verify your scopes against [`plugins/zoom/skills/zoom-apps-sdk/troubleshooting/common-issues.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/skills/zoom-apps-sdk/troubleshooting/common-issues.md).

### Can I update a plugin after it has been published?

Yes, but every update requires a version bump in the manifest and a new submission for review. Increment the version according to the semantic policy, test all changes locally, then resubmit the app. The **Versioning & Drift** guide in [`plugins/zoom/skills/references/versioning-and-drift.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/skills/references/versioning-and-drift.md) explains how to keep the marketplace entry aligned with your codebase.