diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 8a1ac56..f6f4a11 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -4,8 +4,7 @@ "name": "Composio" }, "metadata": { - "description": "Your agent decides what to do; Composio handles the rest — just-in-time tool calls across 1,000+ apps with managed auth, via the composio CLI.", - "version": "0.2.0" + "description": "Your agent decides what to do; Composio handles the rest — just-in-time tool calls across 1,000+ apps with managed auth, via the composio CLI." }, "plugins": [ { diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8d642fa..20a31c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,7 +5,24 @@ on: branches: [master, main] pull_request: +permissions: + contents: read + jobs: + version-bump: + name: Require plugin version bump + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + with: + fetch-depth: 0 + + - name: Check plugin.json version vs merge-base + env: + BASE_REF: ${{ github.base_ref }} + run: bash scripts/check-version-bump.sh "origin/$BASE_REF" + test: name: Validate plugin runs-on: ubuntu-latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..59d118a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,48 @@ +name: Release + +on: + push: + branches: [master] + +permissions: + contents: write + +jobs: + tag-release: + name: Tag and release on version bump + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + with: + fetch-depth: 2 + + - name: Detect plugin version change + id: plugin + run: | + plugin_json="plugins/composio/.claude-plugin/plugin.json" + version="$(python3 -c "import json; print(json.load(open('$plugin_json'))['version'])")" + previous="" + if content="$(git show "HEAD^:$plugin_json" 2>/dev/null)"; then + previous="$(printf '%s' "$content" | python3 -c 'import json, sys; print(json.load(sys.stdin)["version"])')" + fi + echo "version=$version" >> "$GITHUB_OUTPUT" + if [ "$version" != "$previous" ]; then + echo "changed=true" >> "$GITHUB_OUTPUT" + else + echo "changed=false" >> "$GITHUB_OUTPUT" + fi + + # Releases created with GITHUB_TOKEN do not trigger `release`-event + # workflows. Nothing downstream depends on that event — the tag + + # release exist purely as a queryable "latest plugin version" signal. + - name: Create tag and GitHub release + if: steps.plugin.outputs.changed == 'true' + env: + GH_TOKEN: ${{ github.token }} + TAG: v${{ steps.plugin.outputs.version }} + run: | + if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then + echo "Release $TAG already exists; skipping." + exit 0 + fi + gh release create "$TAG" --repo "$GITHUB_REPOSITORY" --target "$GITHUB_SHA" --title "$TAG" --generate-notes diff --git a/plugins/composio/.claude-plugin/plugin.json b/plugins/composio/.claude-plugin/plugin.json index 17e6a4c..a3b898f 100644 --- a/plugins/composio/.claude-plugin/plugin.json +++ b/plugins/composio/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "composio", "displayName": "Composio", - "version": "0.2.2", + "version": "0.2.3", "description": "Your agent decides what to do — Composio handles the rest. Just-in-time tool calls across 1,000+ apps (Slack, GitHub, Gmail, Notion, Linear…) with fully managed auth, driven by the composio CLI.", "author": { "name": "Composio", diff --git a/scripts/check-version-bump.sh b/scripts/check-version-bump.sh new file mode 100755 index 0000000..f57d791 --- /dev/null +++ b/scripts/check-version-bump.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# Fails when plugins/** changed relative to the merge-base with +# but the plugin.json version was not bumped. +# Usage: scripts/check-version-bump.sh (e.g. origin/master) +set -euo pipefail + +PLUGIN_JSON="plugins/composio/.claude-plugin/plugin.json" +BASE_REF="${1:?usage: check-version-bump.sh }" + +merge_base="$(git merge-base "$BASE_REF" HEAD)" + +if git diff --quiet "$merge_base" HEAD -- plugins/; then + echo "No changes under plugins/ vs merge-base $merge_base; version bump not required." + exit 0 +fi + +version_at() { + local content + content="$(git show "$1:$PLUGIN_JSON" 2>/dev/null)" || return 1 + printf '%s' "$content" | python3 -c 'import json, sys; print(json.load(sys.stdin)["version"])' +} + +head_version="$(version_at HEAD)" +if ! printf '%s' "$head_version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "::error::$PLUGIN_JSON version '$head_version' is not X.Y.Z semver." + exit 1 +fi + +if ! base_version="$(version_at "$merge_base")"; then + echo "$PLUGIN_JSON absent at merge-base; accepting initial version $head_version." + exit 0 +fi + +if [ "$head_version" = "$base_version" ]; then + echo "::error::plugins/** changed but $PLUGIN_JSON version is still $base_version. Claude Code only delivers plugin updates on a version bump — bump the version in this PR." + exit 1 +fi + +if [ "$(printf '%s\n%s\n' "$base_version" "$head_version" | sort -V | tail -n1)" != "$head_version" ]; then + echo "::error::$PLUGIN_JSON version went backwards: $base_version -> $head_version." + exit 1 +fi + +echo "Version bump OK: $base_version -> $head_version"