Skip to content

docs: canonical workflow templates for Indigo plugins#40

Merged
simons-plugins merged 3 commits into
mainfrom
feat/workflow-templates
May 10, 2026
Merged

docs: canonical workflow templates for Indigo plugins#40
simons-plugins merged 3 commits into
mainfrom
feat/workflow-templates

Conversation

@simons-plugins
Copy link
Copy Markdown
Owner

@simons-plugins simons-plugins commented May 9, 2026

Summary

  • Add docs/plugin-dev/workflows/version-check.yml and create-release.yml as canonical templates that any Indigo plugin can drop in unmodified — they auto-detect the bundle via find -name '*.indigoPlugin'.
  • README in the same folder explains conventions (v-prefix tags, actions/checkout@v4, softprops/action-gh-release@v2) and how to copy into a plugin repo.
  • Bumps plugin.json + marketplace.json to 1.9.2.

Why

Workspace audit found 9 of 11 Indigo plugin repos hardcode the bundle name in their CI, 8 still use softprops/action-gh-release@v1 (Node 16, deprecated), 2 have no CI at all, and indigo-home-intelligence has a zip-filename bug that breaks installs. The templates here are the single source of truth for the rollout to all 11 repos.

Test plan

  • CI version-check passes (1.9.1 → 1.9.2 bump in both manifests)
  • Templates are syntactically valid YAML (rendered via GitHub UI)
  • After merge, copy these files into pentair-pool (greenfield) and verify version-check + create-release run on a no-op PR

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores

    • Updated plugin to version 1.9.2.
  • Documentation

    • Added comprehensive guides for GitHub Actions workflows that enable automated version checking and streamlined release creation for plugin developers, including tag management, bundle packaging conventions, and coexistence guidance with other CI workflows.

Review Change Stack

Add reference version-check.yml + create-release.yml that auto-detect the
plugin bundle via find, so the same files work in any plugin repo without
edits. Will roll out to all 11 Indigo plugin repos.

Bumps to 1.9.2 (docs).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 9, 2026

Warning

Rate limit exceeded

@simons-plugins has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 45 minutes and 47 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 39fc585f-b754-46c6-91d0-bdd724fcfa07

📥 Commits

Reviewing files that changed from the base of the PR and between 7cd9c44 and f7c8c94.

📒 Files selected for processing (3)
  • docs/plugin-dev/workflows/README.md
  • docs/plugin-dev/workflows/create-release.yml
  • docs/plugin-dev/workflows/version-check.yml
📝 Walkthrough

Walkthrough

This PR bumps the Indigo plugin version from 1.9.1 to 1.9.2 across manifest files, and introduces two drop-in GitHub Actions workflows: a PR-time version-check workflow that enforces version uniqueness, and a main/master release-automation workflow that creates plugin bundles and publishes GitHub releases.

Changes

Plugin Release Automation

Layer / File(s) Summary
Version Manifests
.claude-plugin/marketplace.json, .claude-plugin/plugin.json
Plugin version incremented from 1.9.1 to 1.9.2 in both marketplace and plugin manifest files.
Workflow Documentation
docs/plugin-dev/workflows/README.md
README documents the two workflows, conventions (tag format v$VERSION, auto-detection rules), and usage instructions for copying workflows into target repositories.
PR Version Check Workflow
docs/plugin-dev/workflows/version-check.yml
Triggered on pull requests to main/master, detects plugin bundle, extracts PluginVersion from Info.plist, and fails if the version tag already exists.
Release Automation Workflow
docs/plugin-dev/workflows/create-release.yml
Triggered on pushes to main/master, detects plugin, extracts version, checks for existing tag, and conditionally creates a zip bundle and GitHub Release only if the tag does not exist.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 A version bumps, workflows bloom in GitHub's light,
Two actions check and release with all their might,
From 1.9.1 to 1.9.2, we dance and leap,
With auto-detection keeping tags so neat! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'docs: canonical workflow templates for Indigo plugins' clearly and concisely summarizes the main purpose of the pull request—adding canonical GitHub Actions workflow templates for Indigo plugins as documented in the PR objectives and file changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/workflow-templates

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
docs/plugin-dev/workflows/version-check.yml (1)

30-41: ⚡ Quick win

Consider using a more robust XML parser.

The grep | sed approach to extract PluginVersion is fragile for the same reasons noted in create-release.yml. Since both workflows need to parse the same Info.plist, consider using xmllint with XPath or Python's plistlib for consistency and robustness.

🔧 Alternative implementations

Option 1: Using xmllint

       - name: Extract version from Info.plist
         id: get_version
         run: |
           PLUGIN_NAME="${{ steps.get_plugin_name.outputs.plugin_name }}"
-          VERSION=$(grep -A1 '<key>PluginVersion</key>' "${PLUGIN_NAME}.indigoPlugin/Contents/Info.plist" | grep '<string>' | sed 's/.*<string>\(.*\)<\/string>.*/\1/')
+          VERSION=$(xmllint --xpath 'string(//key[text()="PluginVersion"]/following-sibling::string[1])' "${PLUGIN_NAME}.indigoPlugin/Contents/Info.plist")
           if [ -z "$VERSION" ]; then
             echo "Error: Could not extract PluginVersion from Info.plist." >&2
             exit 1
           fi
           echo "version=$VERSION" >> $GITHUB_OUTPUT
           echo "Extracted version: $VERSION"

Option 2: Using Python plistlib

       - name: Extract version from Info.plist
         id: get_version
         run: |
           PLUGIN_NAME="${{ steps.get_plugin_name.outputs.plugin_name }}"
-          VERSION=$(grep -A1 '<key>PluginVersion</key>' "${PLUGIN_NAME}.indigoPlugin/Contents/Info.plist" | grep '<string>' | sed 's/.*<string>\(.*\)<\/string>.*/\1/')
+          VERSION=$(python3 -c "import plistlib; print(plistlib.load(open('${PLUGIN_NAME}.indigoPlugin/Contents/Info.plist', 'rb'))['PluginVersion'])")
           if [ -z "$VERSION" ]; then
             echo "Error: Could not extract PluginVersion from Info.plist." >&2
             exit 1
           fi
           echo "version=$VERSION" >> $GITHUB_OUTPUT
           echo "Extracted version: $VERSION"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/plugin-dev/workflows/version-check.yml` around lines 30 - 41, Replace
the fragile grep|sed parsing in the get_version step (where PLUGIN_NAME and
VERSION are used to read "${PLUGIN_NAME}.indigoPlugin/Contents/Info.plist") with
a robust XML/plist parser; for example, call xmllint with an XPath that selects
the PluginVersion string or run a short Python snippet using plistlib to load
Info.plist and print the PluginVersion, preserve the existing error check and
exit behavior if PluginVersion is missing, and continue to write the result to
GITHUB_OUTPUT exactly as "version=$VERSION" so downstream steps receive the same
variable.
docs/plugin-dev/workflows/README.md (1)

1-31: 💤 Low value

Use capitalized "Plugin" when referring to Indigo Plugins.

The README uses lowercase "plugin" in several places when referring to Indigo Plugins. As per coding guidelines, use "Plugin" (capitalized) to distinguish Indigo Plugins from this project's Claude Code plugin components.

Instances to update:

  • Line 1: "Indigo plugins" → "Indigo Plugins"
  • Line 3: "Indigo plugin" → "Indigo Plugin"
  • Line 13: "plugin bundle" → "Plugin bundle"
  • Line 18: "plugin name" → "Plugin name"

As per coding guidelines: Use 'Plugin' (capitalized) when referring to Indigo plugins (the tools this project helps build).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/plugin-dev/workflows/README.md` around lines 1 - 31, Update all
occurrences that refer to Indigo plugins to use the capitalized form "Plugin":
change the header "# Canonical CI workflows for Indigo plugins" to "Plugins",
change the sentence "Drop-in GitHub Actions workflows for any Indigo plugin in
the workspace" to "Indigo Plugin", change "plugin bundle" in the
Files/Conventions bullets to "Plugin bundle", and change "plugin name" in Usage
to "Plugin name"; ensure mentions of PluginVersion and Info.plist remain
unchanged (they identify the plist key), and keep filenames version-check.yml
and create-release.yml as-is.
docs/plugin-dev/workflows/create-release.yml (1)

32-43: ⚡ Quick win

Consider using a more robust XML parser.

The grep | sed approach to extract PluginVersion from Info.plist is fragile and may break with whitespace changes or formatting variations. Consider using xmllint with XPath or Python's plistlib for more reliable parsing.

🔧 Alternative implementation using xmllint
       - name: Extract version from Info.plist
         id: get_version
         run: |
           PLUGIN_NAME="${{ steps.get_plugin_name.outputs.plugin_name }}"
-          VERSION=$(grep -A1 '<key>PluginVersion</key>' "${PLUGIN_NAME}.indigoPlugin/Contents/Info.plist" | grep '<string>' | sed 's/.*<string>\(.*\)<\/string>.*/\1/')
+          VERSION=$(xmllint --xpath 'string(//key[text()="PluginVersion"]/following-sibling::string[1])' "${PLUGIN_NAME}.indigoPlugin/Contents/Info.plist")
           if [ -z "$VERSION" ]; then
             echo "Error: Could not extract PluginVersion from Info.plist." >&2
             exit 1
           fi
           echo "version=$VERSION" >> $GITHUB_OUTPUT
           echo "Extracted version: $VERSION"

Alternatively, using Python's plistlib (available in standard library):

       - name: Extract version from Info.plist
         id: get_version
         run: |
           PLUGIN_NAME="${{ steps.get_plugin_name.outputs.plugin_name }}"
-          VERSION=$(grep -A1 '<key>PluginVersion</key>' "${PLUGIN_NAME}.indigoPlugin/Contents/Info.plist" | grep '<string>' | sed 's/.*<string>\(.*\)<\/string>.*/\1/')
+          VERSION=$(python3 -c "import plistlib; print(plistlib.load(open('${PLUGIN_NAME}.indigoPlugin/Contents/Info.plist', 'rb'))['PluginVersion'])")
           if [ -z "$VERSION" ]; then
             echo "Error: Could not extract PluginVersion from Info.plist." >&2
             exit 1
           fi
           echo "version=$VERSION" >> $GITHUB_OUTPUT
           echo "Extracted version: $VERSION"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/plugin-dev/workflows/create-release.yml` around lines 32 - 43, Replace
the fragile grep/sed extraction in the GitHub Actions step id get_version with a
robust XML/plist parse: call a reliable parser (e.g., xmllint with an XPath or
Python's plistlib) to read "${PLUGIN_NAME}.indigoPlugin/Contents/Info.plist" and
extract the PluginVersion key, assign it to VERSION, validate non-empty, and
then echo "version=$VERSION" >> $GITHUB_OUTPUT; update references to PLUGIN_NAME
and VERSION within the get_version step and preserve the existing error/exit
behavior if extraction fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@docs/plugin-dev/workflows/create-release.yml`:
- Around line 32-43: Replace the fragile grep/sed extraction in the GitHub
Actions step id get_version with a robust XML/plist parse: call a reliable
parser (e.g., xmllint with an XPath or Python's plistlib) to read
"${PLUGIN_NAME}.indigoPlugin/Contents/Info.plist" and extract the PluginVersion
key, assign it to VERSION, validate non-empty, and then echo "version=$VERSION"
>> $GITHUB_OUTPUT; update references to PLUGIN_NAME and VERSION within the
get_version step and preserve the existing error/exit behavior if extraction
fails.

In `@docs/plugin-dev/workflows/README.md`:
- Around line 1-31: Update all occurrences that refer to Indigo plugins to use
the capitalized form "Plugin": change the header "# Canonical CI workflows for
Indigo plugins" to "Plugins", change the sentence "Drop-in GitHub Actions
workflows for any Indigo plugin in the workspace" to "Indigo Plugin", change
"plugin bundle" in the Files/Conventions bullets to "Plugin bundle", and change
"plugin name" in Usage to "Plugin name"; ensure mentions of PluginVersion and
Info.plist remain unchanged (they identify the plist key), and keep filenames
version-check.yml and create-release.yml as-is.

In `@docs/plugin-dev/workflows/version-check.yml`:
- Around line 30-41: Replace the fragile grep|sed parsing in the get_version
step (where PLUGIN_NAME and VERSION are used to read
"${PLUGIN_NAME}.indigoPlugin/Contents/Info.plist") with a robust XML/plist
parser; for example, call xmllint with an XPath that selects the PluginVersion
string or run a short Python snippet using plistlib to load Info.plist and print
the PluginVersion, preserve the existing error check and exit behavior if
PluginVersion is missing, and continue to write the result to GITHUB_OUTPUT
exactly as "version=$VERSION" so downstream steps receive the same variable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9e32e06f-5fd9-411b-a3d1-c305c12ae6b5

📥 Commits

Reviewing files that changed from the base of the PR and between 5e226a3 and 7cd9c44.

📒 Files selected for processing (5)
  • .claude-plugin/marketplace.json
  • .claude-plugin/plugin.json
  • docs/plugin-dev/workflows/README.md
  • docs/plugin-dev/workflows/create-release.yml
  • docs/plugin-dev/workflows/version-check.yml

simons-plugins and others added 2 commits May 9, 2026 20:38
Heatmiser uses HeatmiserNeo.IndigoPlugin (capital I). Linux runners are
case-sensitive so -name "*.indigoPlugin" misses it. Switch to -iname so
the canonical workflows work for both legacy capitalized bundles and
modern lowercase ones.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
basename "$PLUGIN_BUNDLE" .indigoPlugin is case-sensitive: for
HeatmiserNeo.IndigoPlugin (capital I) the suffix wasn't stripped, so
later steps tried to read HeatmiserNeo.IndigoPlugin.indigoPlugin/...
and failed.

Drop the basename suffix-strip entirely. The plugin_bundle output now
contains the actual directory name (e.g. "HeatmiserNeo.IndigoPlugin"
or "Domio.indigoPlugin") which is used verbatim for paths and the
asset zip. Asset name preserves original case.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@simons-plugins simons-plugins merged commit a80ba32 into main May 10, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant