Skip to main content

Releasing Extensions

Once you’ve built an extension, you can share it with others. There are two primary methods for releasing extensions: through a Git repository or via GitHub Releases.

Distribution Methods

Pros:
  • Simple to set up
  • Flexible branching strategies
  • Easy rollbacks
  • Supports any Git hosting service
Cons:
  • Requires full repository clone on install
  • All files downloaded (including dev files)
Best for: Most extensions, especially those without build steps

GitHub Releases

Pros:
  • Faster installation (single archive)
  • Can include pre-built binaries
  • Platform-specific builds
  • Smaller download size
Cons:
  • GitHub-specific
  • Requires release workflow
  • More complex setup
Best for: Extensions with build steps, platform-specific code, or large dependencies

Releasing Through Git Repository

This is the simplest and most flexible approach.

Setup

  1. Create a Public Repository Create a public repository on GitHub, GitLab, or any Git hosting service:
    git init
    git add .
    git commit -m "Initial extension release"
    git remote add origin https://github.com/username/my-extension.git
    git push -u origin main
    
  2. Users Install With
    # Full URL
    qwen extensions install https://github.com/username/my-extension
    
    # Shorthand (GitHub only)
    qwen extensions install username/my-extension
    

Version Management

Update the version in qwen-extension.json when you make changes:
{
  "name": "my-extension",
  "version": "1.1.0"
}
Commit and push:
git add qwen-extension.json
git commit -m "chore: bump version to 1.1.0"
git push
Users will be prompted to update when you push to the branch they’re tracking.

Managing Release Channels

Use branches or tags for different release channels:

Option 1: Branch-Based Channels

# Default branch (stable)
git checkout main

# Preview/beta channel
git checkout -b preview
git push origin preview

# Development channel
git checkout -b dev
git push origin dev
Users install:
# Stable (default branch)
qwen extensions install username/my-extension

# Preview
qwen extensions install username/my-extension --ref=preview

# Dev
qwen extensions install username/my-extension --ref=dev

Option 2: Tag-Based Versions

# Create release tags
git tag v1.0.0
git push origin v1.0.0

git tag v1.1.0
git push origin v1.1.0
Users install specific version:
qwen extensions install username/my-extension --ref=v1.0.0
For extensions with stable/preview/dev channels:
  1. Development Branch (dev)
    • Active development happens here
    • Frequent changes
    • May be unstable
  2. Preview Branch (preview)
    • Merge from dev when ready for testing
    • More stable than dev
    • Feature-complete for next release
  3. Main Branch (main or master)
    • Production-ready
    • Only merge from preview after testing
    • Default installation target
Workflow:
# Develop
git checkout dev
# ... make changes ...
git commit -m "feat: add new feature"
git push

# Promote to preview
git checkout preview
git merge dev
git push

# After testing, promote to stable
git checkout main
git merge preview
git push

Auto-Update

Users can enable auto-updates:
qwen extensions install username/my-extension --auto-update
Their installation will automatically update when you push changes to the tracked branch.

Releasing Through GitHub Releases

GitHub Releases provide a more optimized installation experience.

Creating a Release

  1. Tag Your Version
    git tag v1.0.0
    git push origin v1.0.0
    
  2. Create Release on GitHub Go to your repository on GitHub:
    • Click “Releases” → “Create a new release”
    • Select your tag (v1.0.0)
    • Add title and description
    • Attach assets (if needed)
    • Check “Set as the latest release”
    • Click “Publish release”
  3. Users Install
    qwen extensions install username/my-extension
    
    Qwen Code automatically detects and uses GitHub Releases.

Simple Releases (No Build)

If your extension doesn’t require a build step:
  1. Tag and push
  2. Create GitHub release
  3. GitHub automatically creates archive
Done! No manual asset creation needed.

Custom Pre-Built Archives

For extensions with build steps or platform-specific code:

Archive Structure

Archives must contain the complete extension at the root:
my-extension.tar.gz
└── (root)
    ├── qwen-extension.json
    ├── dist/
    │   └── server.js
    └── README.md
Not like this:
❌ my-extension.tar.gz
    └── my-extension/          # Extra nesting level
        ├── qwen-extension.json
        └── ...

Platform-Specific Assets

Naming convention for platform-specific archives: Format: {platform}.{arch}.{name}.{extension} Platform values:
  • darwin - macOS
  • linux - Linux
  • win32 - Windows
Architecture values:
  • x64 - x86-64/AMD64
  • arm64 - ARM 64-bit
Extensions:
  • .tar.gz - Recommended for macOS/Linux
  • .zip - Recommended for Windows
Examples:
darwin.arm64.my-extension.tar.gz    # Apple Silicon Macs
darwin.x64.my-extension.tar.gz      # Intel Macs
linux.x64.my-extension.tar.gz       # Linux x86-64
linux.arm64.my-extension.tar.gz     # Linux ARM64
win32.x64.my-extension.zip          # Windows x86-64
Platform-only (any architecture):
darwin.my-extension.tar.gz          # All Macs
linux.my-extension.tar.gz           # All Linux
win32.my-extension.zip              # All Windows
Generic (single asset): If you attach only one asset, it’s used for all platforms:
my-extension.tar.gz                 # Works everywhere

Building Platform Archives

Example build script: scripts/build-release.sh:
#!/bin/bash
set -e

VERSION=$1
NAME="my-extension"

if [ -z "$VERSION" ]; then
  echo "Usage: $0 <version>"
  exit 1
fi

# Clean
rm -rf dist release
mkdir -p release

# Build
npm run build

# Create base archive structure
mkdir -p build-temp
cp qwen-extension.json build-temp/
cp -r dist build-temp/
cp README.md build-temp/

# Platform-specific builds
cd build-temp

# macOS ARM64
tar -czf ../release/darwin.arm64.${NAME}.tar.gz .

# macOS x64
tar -czf ../release/darwin.x64.${NAME}.tar.gz .

# Linux x64
tar -czf ../release/linux.x64.${NAME}.tar.gz .

# Windows x64
zip -r ../release/win32.x64.${NAME}.zip .

cd ..
rm -rf build-temp

echo "Archives created in release/"
ls -lh release/
Usage:
chmod +x scripts/build-release.sh
./scripts/build-release.sh v1.0.0

GitHub Actions Workflow

Automate releases with GitHub Actions: .github/workflows/release.yml:
name: Release Extension

on:
  push:
    tags:
      - 'v*'

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build
        run: npm run build
      
      - name: Create archives
        run: |
          mkdir -p release
          
          # Create base structure
          mkdir -p build-temp
          cp qwen-extension.json build-temp/
          cp -r dist build-temp/
          cp README.md build-temp/
          
          # Create platform archives
          cd build-temp
          tar -czf ../release/darwin.arm64.my-extension.tar.gz .
          tar -czf ../release/darwin.x64.my-extension.tar.gz .
          tar -czf ../release/linux.x64.my-extension.tar.gz .
          zip -r ../release/win32.x64.my-extension.zip .
      
      - name: Create Release
        uses: softprops/action-gh-release@v1
        with:
          files: release/*
          draft: false
          prerelease: false
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Trigger a release:
git tag v1.0.0
git push origin v1.0.0
GitHub Actions automatically builds and creates the release.

Pre-Release Versions

Create pre-releases for testing:
git tag v1.1.0-beta.1
git push origin v1.1.0-beta.1
On GitHub, check “Set as a pre-release” when creating the release. Users opt-in to pre-releases:
qwen extensions install username/my-extension --pre-release

Extension README

Include a comprehensive README in your extension: README.md:
# My Extension Name

Brief description of what your extension does.

## Features

- Feature 1
- Feature 2
- Feature 3

## Installation

\`\`\`bash
qwen extensions install username/my-extension
\`\`\`

## Configuration

This extension requires:

1. API key from [Service Name](https://example.com)
2. Configure with:
   \`\`\`bash
   qwen extensions settings set my-extension "API Key"
   \`\`\`

## Usage

### Commands

- `/command-name` - Description
- `/other-command` - Description

### Tools

- `tool_name` - What it does
- `other_tool` - What it does

## Examples

\`\`\`
Example usage here
\`\`\`

## Development

To work on this extension:

\`\`\`bash
git clone https://github.com/username/my-extension
cd my-extension
npm install
npm run build
qwen extensions link .
\`\`\`

## License

MIT

Best Practices

1. Semantic Versioning

Use Semantic Versioning:
  • 1.0.0 - Initial release
  • 1.0.1 - Bug fix
  • 1.1.0 - New feature (backwards compatible)
  • 2.0.0 - Breaking change

2. Changelog

Maintain a CHANGELOG.md:
# Changelog

## [1.1.0] - 2024-01-15

### Added
- New `search` command
- Support for filtering results

### Fixed
- Issue with API timeout

### Changed
- Improved error messages

## [1.0.0] - 2024-01-01

- Initial release

3. Git Tags

Tag all releases:
git tag -a v1.0.0 -m "Release version 1.0.0"
git push origin v1.0.0

4. Clean Repository

Exclude unnecessary files: .gitignore:
node_modules/
dist/
*.log
.DS_Store
.env
For GitHub Releases, include built files in archives but not in the repository.

5. License

Include a LICENSE file:
MIT License

Copyright (c) 2024 Your Name

Permission is hereby granted...

6. Documentation

Provide clear documentation:
  • README with installation and usage
  • Examples for all features
  • Configuration instructions
  • Troubleshooting section

Testing Before Release

Local Testing

# Link for testing
qwen extensions link .

# Test all features
# ...

# Unlink when done
qwen extensions uninstall my-extension

Install from Git (Before Release)

Push to a branch and test installation:
git checkout -b test-release
git push origin test-release

qwen extensions install username/my-extension --ref=test-release
Verify everything works, then merge to main and create release.

Updating Extensions

When users have your extension installed:

Git Repository Installs

Users update with:
qwen extensions update my-extension
Or update all:
qwen extensions update --all

GitHub Release Installs

Users are notified when new releases are available. They can update with:
qwen extensions update my-extension

Troubleshooting

”Extension not found”

Ensure:
  • Repository is public
  • qwen-extension.json is in root
  • Repository URL is correct

”Invalid extension structure”

Verify:
  • Archive has extension files at root (no extra nesting)
  • qwen-extension.json is valid JSON
  • Required files are included

”Build files missing”

For extensions with build steps:
  • Include built files in archives
  • Don’t rely on users building
  • Test archive contents before release

Next Steps