How to Test Your Plugin Before Publishing
This guide shows you how to thoroughly test your IDA plugin before publishing it to the plugin repository, ensuring it meets quality standards and works correctly across different environments.
Problem Statement
You've developed an IDA plugin and want to test it comprehensively before releasing it to ensure:
- The plugin metadata is valid
- It installs correctly
- It works across supported IDA versions
- Python dependencies are properly declared
- There are no common packaging errors
Prerequisites
- HCLI installed (see Installation)
- Your plugin with
ida-plugin.jsonfile - Valid IDA Pro installation (for runtime testing)
- Authentication configured (for dependency installation)
Quick Validation Checklist
Before deep testing, ensure these basics:
-
ida-plugin.jsonexists in plugin root - Plugin version follows semantic versioning (e.g.,
1.0.0) - Repository URL is correct
- Entry point file exists
- No trailing commas in JSON
Step-by-Step Testing Guide
Step 1: Validate Plugin Metadata with Lint
The first step is to validate your plugin structure and metadata:
hcli plugin lint /path/to/your-plugin
For a directory:
cd /path/to/your-plugin
hcli plugin lint .
For a ZIP archive:
hcli plugin lint your-plugin-v1.0.0.zip
For a GitHub release:
hcli plugin lint https://github.com/username/plugin/releases/download/v1.0.0/plugin.zip
Step 2: Understand Lint Output
Success output:
When lint finds nothing to report, it prints:
no recommendations
If optional metadata is missing, lint prints a recommendation for each field instead. These don't block publishing, but address them to make your plugin easier to find:
Recommendation (/path/to/your-plugin): ida-plugin.json: provide plugin.description
A one-line description improves discoverability in the plugin repository
Recommendation (/path/to/your-plugin): ida-plugin.json: provide plugin.logoPath
A logo image (16:9 aspect ratio) makes your plugin more visually appealing
Recommendation (/path/to/your-plugin): ida-plugin.json: provide plugin.keywords
Keywords improve search discoverability in the plugin repository
Error output:
When ida-plugin.json can't be loaded, lint prints the error and stops, so fix it and run lint again to find the next one. For example, a manifest without plugin.version:
Error: ida-plugin.json validation failed
Missing required field: plugin.version
Step 3: Fix Common Validation Errors
Error: "Invalid JSON"
Cause: Trailing commas or syntax errors in ida-plugin.json.
Error: ida-plugin.json validation failed
Invalid value for : Invalid JSON: trailing comma at line 15 column 3
Solution: Use a JSON validator or jq:
cat ida-plugin.json | jq .
Fix trailing commas:
{
"plugin": {
"name": "my-plugin",
"version": "1.0.0" // ← Remove comma if this is the last field
}
}
Error: "Missing required field: plugin.version"
Cause: Version field is missing.
Solution: Add semantic version:
{
"plugin": {
"version": "1.0.0"
}
}
Error: "Entry point file not found"
Cause: File specified in entryPoint doesn't exist.
Error: ida-plugin.json validation failed: Entry point file not found in directory: 'plugin_entry.py'
Solution: Verify the file exists and path is correct. This path is relative to ida-plugin.json:
# Check entry point
ls -l plugin_entry.py
# Update ida-plugin.json
{
"plugin": {
"entryPoint": "plugin_entry.py" // Must match actual filename
}
}
Error: "failed to parse version"
Cause: The version can't be parsed, most often because of a leading v.
Error: ida-plugin.json validation failed
Invalid value for plugin.version: Value error, failed to parse version: Version string lacks a numerical component: 'v1.0.0'
Solution: Use format MAJOR.MINOR.PATCH, without a leading v:
// ✗ Wrong
{"version": "v1.0.0"}
// ✓ Correct
{"version": "1.0.0"}
{"version": "2.1.3"}
Note
Lint does not check pythonDependencies against PyPI, so it won't catch a misspelled package name. Check names on pypi.org and test installation (Step 4).
Step 4: Test Local Installation
Install your plugin from the local directory:
# Install from directory
hcli plugin install /path/to/your-plugin
# Or from ZIP
hcli plugin install ./your-plugin-v1.0.0.zip
Expected output:
Installing plugin: my-awesome-plugin==1.0.0
Installing Python dependencies: requests>=2.28.0, pydantic>=2.0
✓ Installed plugin: my-awesome-plugin==1.0.0
Step 5: Verify Installation
Check that the plugin is installed:
hcli plugin status
Output should include your plugin:
✓ my-awesome-plugin 1.0.0 /path/to/.idapro/plugins/my-awesome-plugin/
requests 2.31.0
pydantic 2.5.0
Verify plugin files were copied:
# macOS/Linux
ls ~/.idapro/plugins/my-awesome-plugin/
# Windows
dir %APPDATA%\.idapro\plugins\my-awesome-plugin\
Step 6: Test in IDA Pro
Launch IDA Pro and verify:
- Plugin loads without errors:
- Check IDA console output for Python errors
-
Look for your plugin in Edit → Plugins menu
-
Plugin functionality works:
- Execute main plugin features
- Test edge cases
-
Verify hotkeys (if any)
-
Check for errors:
# In IDA Python console import ida_loader ida_loader.load_and_run_plugin("my-awesome-plugin", 0)
Step 7: Test Across IDA Versions
If your plugin supports multiple IDA versions, test each one:
# Set specific IDA installation
export HCLI_CURRENT_IDA_INSTALL_DIR="/Applications/IDA Professional 9.1.app"
hcli plugin install /path/to/your-plugin
# Test in IDA 9.1
/Applications/IDA\ Professional\ 9.1.app/Contents/MacOS/ida64
# Repeat for IDA 9.2
export HCLI_CURRENT_IDA_INSTALL_DIR="/Applications/IDA Professional 9.2.app"
hcli plugin install /path/to/your-plugin --force
# Test in IDA 9.2
/Applications/IDA\ Professional\ 9.2.app/Contents/MacOS/ida64
Verify:
- No API compatibility issues
- All features work as expected
- No deprecation warnings
Step 8: Test Plugin Configuration (if applicable)
If your plugin uses settings:
# List plugin settings
hcli plugin config list my-awesome-plugin
# Set a configuration value
hcli plugin config set my-awesome-plugin api_key "test-key-123"
# Get the value
hcli plugin config get my-awesome-plugin api_key
# Test in plugin
# Your plugin should read: ida_settings.get_current_plugin_setting("api_key")
Step 9: Test Uninstallation
Verify clean removal:
hcli plugin uninstall my-awesome-plugin
Check that files are removed:
ls ~/.idapro/plugins/my-awesome-plugin/ # Should not exist
Re-install to continue testing:
hcli plugin install /path/to/your-plugin
Pre-Publishing Checklist
Before creating a GitHub release:
Metadata Completeness
-
versionfollows semantic versioning -
descriptionis clear and concise -
keywordsadded for discoverability -
licensespecified -
authorsand/ormaintainerswith email -
urls.repositorypoints to correct GitHub repo -
idaVersionslists all supported versions -
platformsspecified (or omit for all platforms) -
logoPathincluded (optional but recommended) -
dependencieslists companion plugins correctly (if applicable)
Testing Complete
-
hcli plugin lintpasses without errors - Plugin installs from ZIP archive
- Plugin loads in IDA Pro without errors
- Core functionality works as expected
- Tested on all supported IDA versions
- Python dependencies install correctly
- Settings/configuration works (if applicable)
- Plugin uninstalls cleanly
Documentation
- README.md with usage instructions
- CHANGELOG.md with version history
- LICENSE file included
- Example usage provided
- Known issues documented
Repository Setup
- GitHub repository is public
-
ida-plugin.jsonis present - Release tags follow semantic versioning (e.g.,
v1.0.0) - ZIP archive attached to release (for non-Python plugins)
- Release notes describe changes
Common Testing Pitfalls
1. Not Testing on Clean IDA Installation
Problem: Plugin works on your system but fails for users.
Solution: Test with fresh IDA installation:
# Backup existing plugins
mv ~/.idapro/plugins ~/.idapro/plugins.bak
# Test plugin installation
hcli plugin install /path/to/plugin
# Restore
mv ~/.idapro/plugins.bak ~/.idapro/plugins
2. Hardcoded Paths
Problem: Plugin uses absolute paths that don't exist on other systems.
Solution: Use IDA SDK functions:
import ida_diskio
import idaapi
# ✗ Wrong
config_path = "/Users/me/.plugin-config"
# ✓ Correct
config_path = os.path.join(ida_diskio.get_user_idadir(), "plugin-config")
3. Missing Python Dependency Versions
Problem: Plugin works with latest dependency but breaks with older versions.
Solution: Specify minimum versions:
{
"pythonDependencies": [
"requests>=2.28.0", // Specify minimum version
"pydantic>=2.0,<3.0" // Or version range
]
}
Prefer not to pin to specific versions (==2.28.0) because it's difficult for many plugins to agree on precisely the same version.
Reference Documentation
For more detailed information:
- Packaging Your Existing Plugin
- Plugin Packaging and Format
- Plugin Manager User Guide
- Plugin Repository Architecture
- Plugin Bundles for offline distribution
Getting Help
If you encounter issues:
- Check the linter output:
hcli plugin lintprovides detailed error messages - Review example plugins
- Open an issue
- Contact Hex-Rays
Publishing Your Plugin
Once all tests pass:
- Create a GitHub release with a semantic version tag (e.g.,
v1.0.0) - Attach ZIP archive (if needed for native plugins)
- Wait for the daily indexer run
- Verify plugin appears:
hcli plugin search your-plugin
The community plugin repository automatically discovers and indexes plugins with valid ida-plugin.json files from GitHub releases.