From 8a8b75bfbd18b9a13407ebd8da53d047e5c72a47 Mon Sep 17 00:00:00 2001 From: Arad Soutehkeshan Date: Sun, 28 Sep 2025 14:58:39 +0100 Subject: [PATCH 01/24] Fix typo (#121) --- docs/installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index a03cd67..7a77258 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -5,9 +5,9 @@ Installation includes the following steps: - Install the MCP server - Clone this repository - - Instal uv (Python virtual environment manager) + - Install uv (Python virtual environment manager) - Install and configure the Language model client - - Instal any language model client (We demo with Claude Desktop) + - Install any language model client (We demo with Claude Desktop) - Configure the client to run the MCP server and connect automatically on launch. - Install and launch Rosbridge From 48ae8f83e3a1bc243e759f5d32ec1a0aede947ac Mon Sep 17 00:00:00 2001 From: Rohit John Varghese <93564012+rjohn-v@users.noreply.github.com> Date: Sun, 28 Sep 2025 22:56:31 -0500 Subject: [PATCH 02/24] Fixed installation errors in the pypi distribution of the mcp server (#124) --- config/__init__.py | 1 + pyproject.toml | 9 +++++---- server.json | 4 ++-- utils/__init__.py | 1 + uv.lock | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 config/__init__.py create mode 100644 utils/__init__.py diff --git a/config/__init__.py b/config/__init__.py new file mode 100644 index 0000000..5e3e631 --- /dev/null +++ b/config/__init__.py @@ -0,0 +1 @@ +# Config package for ROS MCP Server diff --git a/pyproject.toml b/pyproject.toml index 7b7eadc..e8821bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,16 +1,15 @@ [project] name = "ros-mcp" -version = "2.1.2" +version = "2.1.3" description = "Connect AI Language Models with Robots on ROS using MCP" readme = "README.md" requires-python = ">=3.10" -license = { text = "Apache 2.0" } +license = "Apache-2.0" authors = [ { name = "Rohit John Varghese"}, { name = "Jungsoo Lee"}, { name = "Youngmok Yun"}, { name = "Stefano Dalla Gasperina"} - ] @@ -33,11 +32,13 @@ dev = [ ros-mcp = "server:main" [build-system] -requires = ["setuptools>=45", "wheel"] +requires = ["setuptools>=68", "wheel"] build-backend = "setuptools.build_meta" [tool.setuptools] include-package-data = true +py-modules = ["server"] +packages = ["utils", "config"] [tool.setuptools.data-files] "." = ["server.json"] diff --git a/server.json b/server.json index c54559d..ef8ccf9 100644 --- a/server.json +++ b/server.json @@ -2,12 +2,12 @@ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json", "name": "io.github.robotmcp/ros-mcp-server", "description": "Connect AI models like Claude & ChatGPT with ROS robots using MCP", - "version": "2.1.2", + "version": "2.1.3", "packages": [ { "registry_type": "pypi", "identifier": "ros-mcp", - "version": "2.1.2" + "version": "2.1.3" } ], "transport": { diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 0000000..292207e --- /dev/null +++ b/utils/__init__.py @@ -0,0 +1 @@ +# Utils package for ROS MCP Server diff --git a/uv.lock b/uv.lock index fe027dc..62883f9 100644 --- a/uv.lock +++ b/uv.lock @@ -1213,7 +1213,7 @@ wheels = [ [[package]] name = "ros-mcp" -version = "2.1.2" +version = "2.1.3" source = { editable = "." } dependencies = [ { name = "fastmcp" }, From bd5fbbf4752f01265ebcdcc1adf248b38fdb4836 Mon Sep 17 00:00:00 2001 From: Rohit John Varghese Date: Mon, 29 Sep 2025 18:02:17 -0500 Subject: [PATCH 03/24] updated version to v2.1.4 --- pyproject.toml | 2 +- server.json | 4 ++-- uv.lock | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e8821bd..f4089c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "ros-mcp" -version = "2.1.3" +version = "2.1.4" description = "Connect AI Language Models with Robots on ROS using MCP" readme = "README.md" requires-python = ">=3.10" diff --git a/server.json b/server.json index ef8ccf9..59f0b47 100644 --- a/server.json +++ b/server.json @@ -2,12 +2,12 @@ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json", "name": "io.github.robotmcp/ros-mcp-server", "description": "Connect AI models like Claude & ChatGPT with ROS robots using MCP", - "version": "2.1.3", + "version": "2.1.4", "packages": [ { "registry_type": "pypi", "identifier": "ros-mcp", - "version": "2.1.3" + "version": "2.1.4" } ], "transport": { diff --git a/uv.lock b/uv.lock index 62883f9..c222de7 100644 --- a/uv.lock +++ b/uv.lock @@ -1213,7 +1213,7 @@ wheels = [ [[package]] name = "ros-mcp" -version = "2.1.3" +version = "2.1.4" source = { editable = "." } dependencies = [ { name = "fastmcp" }, From 990e0dd1eb94e6420a554f6a11d849b6bc70e216 Mon Sep 17 00:00:00 2001 From: Stefano Date: Tue, 7 Oct 2025 00:02:05 -0500 Subject: [PATCH 04/24] Added metrics workflows (tested in separate repo) --- .github/workflows/clone-metrics.yml | 72 +++++++++++++++++++++++++++++ .github/workflows/view-metrics.yml | 72 +++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 .github/workflows/clone-metrics.yml create mode 100644 .github/workflows/view-metrics.yml diff --git a/.github/workflows/clone-metrics.yml b/.github/workflows/clone-metrics.yml new file mode 100644 index 0000000..181f81c --- /dev/null +++ b/.github/workflows/clone-metrics.yml @@ -0,0 +1,72 @@ +name: Track Clone Metrics via GitHub App + +on: + schedule: + - cron: "30 4 * * *" # Daily at 04:00 UTC + workflow_dispatch: + +jobs: + track-clone-metrics: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Authenticate as GitHub App + id: generate_token + uses: tibdex/github-app-token@v2.1.0 + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Retrieve clone data + env: + TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + mkdir -p .metrics + echo "Fetching clone data for ${{ github.repository }}..." + curl -s -H "Authorization: Bearer $TOKEN" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/${{ github.repository }}/traffic/clones?per=day" \ + > .metrics/clones.json + jq '. | {total_14d: .count, unique_14d: .uniques, days: (.clones|length)}' .metrics/clones.json + + - name: Update unified clone metrics CSV + run: | + mkdir -p .metrics + CSV=".metrics/clone_metrics.csv" + + TOTAL=$(jq '.count' .metrics/clones.json) + UNIQUE_TOTAL=$(jq '.uniques' .metrics/clones.json) + + if [ ! -f "$CSV" ]; then + echo "date,clones,unique_cloners,total_clones_14d,unique_cloners_14d" > "$CSV" + fi + + jq -r --arg total "$TOTAL" --arg uniques "$UNIQUE_TOTAL" \ + '.clones[] | "\(.timestamp[0:10]),\(.count),\(.uniques),\($total),\($uniques)"' \ + .metrics/clones.json \ + | while IFS= read -r line; do + date=$(echo "$line" | cut -d',' -f1) + if ! grep -q "^$date," "$CSV"; then + echo "$line" >> "$CSV" + fi + done + + echo "Updated metrics summary:" + tail -n 5 "$CSV" + + - name: Commit and push results + env: + TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + git config user.name "CloneMetrics[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git add .metrics/clone_metrics.csv + git commit -m "Automated update: repository clone metrics" || echo "No new data to commit." + git pull --rebase origin develop || true + git push https://x-access-token:${TOKEN}@github.com/${{ github.repository }} HEAD diff --git a/.github/workflows/view-metrics.yml b/.github/workflows/view-metrics.yml new file mode 100644 index 0000000..9538789 --- /dev/null +++ b/.github/workflows/view-metrics.yml @@ -0,0 +1,72 @@ +name: Track View Metrics via GitHub App + +on: + schedule: + - cron: "30 4 * * *" # Daily at 04:00 UTC + workflow_dispatch: + +jobs: + track-view-metrics: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Authenticate as GitHub App + id: generate_token + uses: tibdex/github-app-token@v2.1.0 + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Retrieve view data + env: + TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + mkdir -p .metrics + echo "Fetching view data for ${{ github.repository }}..." + curl -s -H "Authorization: Bearer $TOKEN" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/${{ github.repository }}/traffic/views?per=day" \ + > .metrics/views.json + jq '. | {total_14d: .count, unique_14d: .uniques, days: (.views|length)}' .metrics/views.json + + - name: Update unified view metrics CSV + run: | + mkdir -p .metrics + CSV=".metrics/view_metrics.csv" + + TOTAL=$(jq '.count' .metrics/views.json) + UNIQUE_TOTAL=$(jq '.uniques' .metrics/views.json) + + if [ ! -f "$CSV" ]; then + echo "date,views,unique_viewers,total_views_14d,unique_viewers_14d" > "$CSV" + fi + + jq -r --arg total "$TOTAL" --arg uniques "$UNIQUE_TOTAL" \ + '.views[] | "\(.timestamp[0:10]),\(.count),\(.uniques),\($total),\($uniques)"' \ + .metrics/views.json \ + | while IFS= read -r line; do + date=$(echo "$line" | cut -d',' -f1) + if ! grep -q "^$date," "$CSV"; then + echo "$line" >> "$CSV" + fi + done + + echo "Updated metrics summary:" + tail -n 5 "$CSV" + + - name: Commit and push results + env: + TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + git config user.name "ViewMetrics[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git add .metrics/view_metrics.csv + git commit -m "Automated update: repository view metrics" || echo "No new data to commit." + git pull --rebase origin develop || true + git push https://x-access-token:${TOKEN}@github.com/${{ github.repository }} HEAD From 1b87ec897d877bf4db8e3fc7a86549e43941e650 Mon Sep 17 00:00:00 2001 From: Stefano Date: Tue, 7 Oct 2025 00:02:56 -0500 Subject: [PATCH 05/24] Removed non-working workflows --- .github/workflows/clone-trend.yml | 63 -------------- .github/workflows/traffic-trend.yml | 127 ---------------------------- 2 files changed, 190 deletions(-) delete mode 100644 .github/workflows/clone-trend.yml delete mode 100644 .github/workflows/traffic-trend.yml diff --git a/.github/workflows/clone-trend.yml b/.github/workflows/clone-trend.yml deleted file mode 100644 index b398401..0000000 --- a/.github/workflows/clone-trend.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: Track clone stats -on: - schedule: [{ cron: "7 3 * * *" }] # daily at 03:07 UTC - workflow_dispatch: -permissions: - contents: write - actions: read - id-token: write -jobs: - track: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Install jq - run: sudo apt-get update && sudo apt-get install -y jq - - - name: Fetch last 14 days of clone data - env: - REPO: ${{ github.repository }} # owner/repo - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -H "Authorization: Bearer $GH_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/$REPO/traffic/clones?per=day" > clones.json - cat clones.json | jq '.' - - - name: Ensure data directory and CSV - run: | - mkdir -p analytics - if [ ! -f analytics/clone_history.csv ]; then - echo "date,clones,unique_cloners" > analytics/clone_history.csv - fi - - - name: Merge new data into CSV (de-duplicate by date) - run: | - # Build a temp map of existing dates to avoid duplicates - awk -F, 'NR>1 {print $1}' analytics/clone_history.csv | sort > existing_dates.txt - - # Append any missing dates from API response - jq -r '.clones[] | "\(.timestamp[0:10]),\(.count),\(.uniques)"' clones.json \ - | while IFS= read -r line; do - d=$(echo "$line" | cut -d',' -f1) - if ! grep -qx "$d" existing_dates.txt; then - echo "$line" >> analytics/clone_history.csv - fi - done - - # Sort CSV by date (header stays on top) - { head -n1 analytics/clone_history.csv && tail -n +2 analytics/clone_history.csv | sort; } > analytics/clone_history.sorted.csv - mv analytics/clone_history.sorted.csv analytics/clone_history.csv - - - name: Commit changes - run: | - if git diff --quiet; then - echo "No changes." - else - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add analytics/clone_history.csv - git commit -m "Update clone history" - git push - fi diff --git a/.github/workflows/traffic-trend.yml b/.github/workflows/traffic-trend.yml deleted file mode 100644 index 1c13725..0000000 --- a/.github/workflows/traffic-trend.yml +++ /dev/null @@ -1,127 +0,0 @@ -name: Track clones & downloads -on: - schedule: [{ cron: "12 9 * * *" }] # daily 09:12 UTC (~04:12 America/Chicago) - workflow_dispatch: - -permissions: - contents: write - actions: read - id-token: write - -jobs: - track: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Install jq - run: sudo apt-get update && sudo apt-get install -y jq - - # ---------- CLONE STATS (14-day window, accumulated to CSV) ---------- - - name: Fetch last 14 days of clone data - env: - REPO: ${{ github.repository }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -H "Authorization: Bearer $GH_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/$REPO/traffic/clones?per=day" > clones.json - - - name: Merge clones into CSV - run: | - mkdir -p analytics - CSV="analytics/clone_history.csv" - [ -f "$CSV" ] || echo "date,clones,unique_cloners" > "$CSV" - - # existing dates to avoid dupes - awk -F, 'NR>1 {print $1}' "$CSV" | sort -u > .existing_clone_dates.txt || true - - jq -r '.clones[] | "\(.timestamp[0:10]),\(.count),\(.uniques)"' clones.json \ - | while IFS= read -r line; do - d="${line%%,*}" - if ! grep -qx "$d" .existing_clone_dates.txt; then - echo "$line" >> "$CSV" - fi - done - - # sort by date (keep header) - { head -n1 "$CSV"; tail -n +2 "$CSV" | sort; } > "$CSV.sorted" - mv "$CSV.sorted" "$CSV" - - # ---------- RELEASE DOWNLOADS (cumulative snapshot per day) ---------- - - name: Fetch all releases (paginate) - env: - REPO: ${{ github.repository }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - set -e - tmpdir=$(mktemp -d) - page=1 - > "$tmpdir/all.json" - while :; do - resp=$(curl -s -H "Authorization: Bearer $GH_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/$REPO/releases?per_page=100&page=$page") - count=$(echo "$resp" | jq 'length') - if [ "$count" -eq 0 ]; then break; fi - echo "$resp" | jq '.[]' >> "$tmpdir/all.json" - page=$((page+1)) - done - - # Wrap into an array if we added anything - if [ -s "$tmpdir/all.json" ]; then - echo "[" > releases.json - # join with commas - sed -e '$!s/$/,/' "$tmpdir/all.json" >> releases.json - echo "]" >> releases.json - else - echo "[]" > releases.json - fi - - - name: Merge downloads into CSVs - run: | - mkdir -p analytics - SNAPCSV="analytics/downloads_snapshot.csv" - TOTCSV="analytics/downloads_totals.csv" - today=$(date -u +%F) - - # Create CSVs if missing - [ -f "$SNAPCSV" ] || echo "date,release_tag,asset_id,asset_name,download_count" > "$SNAPCSV" - [ -f "$TOTCSV" ] || echo "date,total_downloads" > "$TOTCSV" - - # Avoid duplicating today's snapshot rows - # (filter if today's rows already recorded) - if grep -q "^$today," "$SNAPCSV"; then - echo "Download snapshot for $today already exists; skipping append." - else - # Snapshot rows: one per asset - jq -r ' - .[] - | select(.draft==false) - | .tag_name as $tag - | (.assets // []) - | .[] - | [$tag, .id, .name, (.download_count // 0)] - | @csv - ' releases.json \ - | sed 's/^/'"$today"',/' >> "$SNAPCSV" - fi - - # Totals row: sum all asset download_count across all releases - if ! grep -q "^$today," "$TOTCSV"; then - total=$(jq '[ .[] | select(.draft==false) | (.assets // []) | .[] | (.download_count // 0) ] | add // 0' releases.json) - echo "$today,$total" >> "$TOTCSV" - fi - - # ---------- COMMIT ---------- - - name: Commit changes - run: | - if git diff --quiet; then - echo "No changes." - else - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add analytics/clone_history.csv analytics/downloads_snapshot.csv analytics/downloads_totals.csv - git commit -m "Update clone & download history" - git push - fi From 1692c012b2acd51cf2a5ec965171fd9c285ef4c7 Mon Sep 17 00:00:00 2001 From: Stefano Date: Tue, 7 Oct 2025 00:36:56 -0500 Subject: [PATCH 06/24] Added download-metrics.yml + commit/push to metrics branch --- .github/workflows/clone-metrics.yml | 7 ++- .github/workflows/download-metrics.yml | 84 ++++++++++++++++++++++++++ .github/workflows/view-metrics.yml | 7 ++- 3 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/download-metrics.yml diff --git a/.github/workflows/clone-metrics.yml b/.github/workflows/clone-metrics.yml index 181f81c..e66dd1a 100644 --- a/.github/workflows/clone-metrics.yml +++ b/.github/workflows/clone-metrics.yml @@ -2,7 +2,7 @@ name: Track Clone Metrics via GitHub App on: schedule: - - cron: "30 4 * * *" # Daily at 04:00 UTC + - cron: "30 4 * * *" # Every day at 4:30 AM UTC workflow_dispatch: jobs: @@ -14,6 +14,9 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + ref: metrics + fetch-depth: 0 - name: Authenticate as GitHub App id: generate_token @@ -68,5 +71,5 @@ jobs: git add .metrics/clone_metrics.csv git commit -m "Automated update: repository clone metrics" || echo "No new data to commit." - git pull --rebase origin develop || true + git pull --rebase origin metrics || true git push https://x-access-token:${TOKEN}@github.com/${{ github.repository }} HEAD diff --git a/.github/workflows/download-metrics.yml b/.github/workflows/download-metrics.yml new file mode 100644 index 0000000..fad8bb1 --- /dev/null +++ b/.github/workflows/download-metrics.yml @@ -0,0 +1,84 @@ +name: Track Download Metrics via GitHub App + +on: + schedule: + - cron: "30 4 * * *" # Every day at 4:30 AM UTC + workflow_dispatch: + +jobs: + track-download-metrics: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: metrics + fetch-depth: 0 + + - name: Authenticate as GitHub App + id: generate_token + uses: tibdex/github-app-token@v2.1.0 + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Retrieve download data + env: + TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + mkdir -p .metrics + echo "Fetching download data for ${{ github.repository }}..." + + # Fetch all pages of releases + curl -s -H "Authorization: Bearer $TOKEN" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/${{ github.repository }}/releases?per_page=100" \ + > .metrics/releases.json + + echo "Raw releases data (first 3 releases):" + jq '.[0:3] | .[] | {tag_name, assets_count: (.assets | length), assets: [.assets[] | {name: .name, download_count: .download_count}]}' .metrics/releases.json + + # Extract download counts from releases + jq '[.[] | {tag_name: .tag_name, published_at: .published_at, assets: [.assets[] | {name: .name, download_count: .download_count}]}]' .metrics/releases.json > .metrics/downloads.json + + echo "Download data summary:" + jq '[.[] | {tag: .tag_name, date: .published_at, total_downloads: ([.assets[].download_count] | add), assets_count: (.assets | length)}]' .metrics/downloads.json + + - name: Update unified download metrics CSV + run: | + mkdir -p .metrics + CSV=".metrics/download_metrics.csv" + + if [ ! -f "$CSV" ]; then + echo "date,release_tag,asset_name,downloads,total_release_downloads" > "$CSV" + fi + + jq -r '.[] | + if (.assets | length > 0) then + .assets[] as $asset | + "\(.published_at[0:10]),\(.tag_name),\($asset.name),\($asset.download_count),\([.assets[].download_count] | add)" + else + "\(.published_at[0:10]),\(.tag_name),,0,0" + end' \ + .metrics/downloads.json \ + | while IFS= read -r line; do + echo "$line" >> "$CSV" + done + + echo "Updated metrics summary:" + tail -n 5 "$CSV" + + - name: Commit and push results + env: + TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + git config user.name "DownloadMetrics[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git add .metrics/download_metrics.csv + git commit -m "Automated update: repository download metrics" || echo "No new data to commit." + git pull --rebase origin metrics || true + git push https://x-access-token:${TOKEN}@github.com/${{ github.repository }} HEAD diff --git a/.github/workflows/view-metrics.yml b/.github/workflows/view-metrics.yml index 9538789..97e7f36 100644 --- a/.github/workflows/view-metrics.yml +++ b/.github/workflows/view-metrics.yml @@ -2,7 +2,7 @@ name: Track View Metrics via GitHub App on: schedule: - - cron: "30 4 * * *" # Daily at 04:00 UTC + - cron: "0 */2 * * *" # Every 2 hours workflow_dispatch: jobs: @@ -14,6 +14,9 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + ref: metrics + fetch-depth: 0 - name: Authenticate as GitHub App id: generate_token @@ -68,5 +71,5 @@ jobs: git add .metrics/view_metrics.csv git commit -m "Automated update: repository view metrics" || echo "No new data to commit." - git pull --rebase origin develop || true + git pull --rebase origin metrics || true git push https://x-access-token:${TOKEN}@github.com/${{ github.repository }} HEAD From 6129d8c32b8da0cf6830711481710b70e666103a Mon Sep 17 00:00:00 2001 From: Stefano Dalla Gasperina Date: Tue, 7 Oct 2025 09:18:25 -0500 Subject: [PATCH 07/24] Hotfix: added metrics workflow to monitor clone/views (#147) * Added metrics workflows (tested in separate repo) * Removed non-working workflows * Added download-metrics.yml + commit/push to metrics branch --- .github/workflows/clone-metrics.yml | 75 +++++++++++++++ .github/workflows/clone-trend.yml | 63 ------------ .github/workflows/download-metrics.yml | 84 ++++++++++++++++ .github/workflows/traffic-trend.yml | 127 ------------------------- .github/workflows/view-metrics.yml | 75 +++++++++++++++ 5 files changed, 234 insertions(+), 190 deletions(-) create mode 100644 .github/workflows/clone-metrics.yml delete mode 100644 .github/workflows/clone-trend.yml create mode 100644 .github/workflows/download-metrics.yml delete mode 100644 .github/workflows/traffic-trend.yml create mode 100644 .github/workflows/view-metrics.yml diff --git a/.github/workflows/clone-metrics.yml b/.github/workflows/clone-metrics.yml new file mode 100644 index 0000000..e66dd1a --- /dev/null +++ b/.github/workflows/clone-metrics.yml @@ -0,0 +1,75 @@ +name: Track Clone Metrics via GitHub App + +on: + schedule: + - cron: "30 4 * * *" # Every day at 4:30 AM UTC + workflow_dispatch: + +jobs: + track-clone-metrics: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: metrics + fetch-depth: 0 + + - name: Authenticate as GitHub App + id: generate_token + uses: tibdex/github-app-token@v2.1.0 + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Retrieve clone data + env: + TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + mkdir -p .metrics + echo "Fetching clone data for ${{ github.repository }}..." + curl -s -H "Authorization: Bearer $TOKEN" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/${{ github.repository }}/traffic/clones?per=day" \ + > .metrics/clones.json + jq '. | {total_14d: .count, unique_14d: .uniques, days: (.clones|length)}' .metrics/clones.json + + - name: Update unified clone metrics CSV + run: | + mkdir -p .metrics + CSV=".metrics/clone_metrics.csv" + + TOTAL=$(jq '.count' .metrics/clones.json) + UNIQUE_TOTAL=$(jq '.uniques' .metrics/clones.json) + + if [ ! -f "$CSV" ]; then + echo "date,clones,unique_cloners,total_clones_14d,unique_cloners_14d" > "$CSV" + fi + + jq -r --arg total "$TOTAL" --arg uniques "$UNIQUE_TOTAL" \ + '.clones[] | "\(.timestamp[0:10]),\(.count),\(.uniques),\($total),\($uniques)"' \ + .metrics/clones.json \ + | while IFS= read -r line; do + date=$(echo "$line" | cut -d',' -f1) + if ! grep -q "^$date," "$CSV"; then + echo "$line" >> "$CSV" + fi + done + + echo "Updated metrics summary:" + tail -n 5 "$CSV" + + - name: Commit and push results + env: + TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + git config user.name "CloneMetrics[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git add .metrics/clone_metrics.csv + git commit -m "Automated update: repository clone metrics" || echo "No new data to commit." + git pull --rebase origin metrics || true + git push https://x-access-token:${TOKEN}@github.com/${{ github.repository }} HEAD diff --git a/.github/workflows/clone-trend.yml b/.github/workflows/clone-trend.yml deleted file mode 100644 index b398401..0000000 --- a/.github/workflows/clone-trend.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: Track clone stats -on: - schedule: [{ cron: "7 3 * * *" }] # daily at 03:07 UTC - workflow_dispatch: -permissions: - contents: write - actions: read - id-token: write -jobs: - track: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Install jq - run: sudo apt-get update && sudo apt-get install -y jq - - - name: Fetch last 14 days of clone data - env: - REPO: ${{ github.repository }} # owner/repo - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -H "Authorization: Bearer $GH_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/$REPO/traffic/clones?per=day" > clones.json - cat clones.json | jq '.' - - - name: Ensure data directory and CSV - run: | - mkdir -p analytics - if [ ! -f analytics/clone_history.csv ]; then - echo "date,clones,unique_cloners" > analytics/clone_history.csv - fi - - - name: Merge new data into CSV (de-duplicate by date) - run: | - # Build a temp map of existing dates to avoid duplicates - awk -F, 'NR>1 {print $1}' analytics/clone_history.csv | sort > existing_dates.txt - - # Append any missing dates from API response - jq -r '.clones[] | "\(.timestamp[0:10]),\(.count),\(.uniques)"' clones.json \ - | while IFS= read -r line; do - d=$(echo "$line" | cut -d',' -f1) - if ! grep -qx "$d" existing_dates.txt; then - echo "$line" >> analytics/clone_history.csv - fi - done - - # Sort CSV by date (header stays on top) - { head -n1 analytics/clone_history.csv && tail -n +2 analytics/clone_history.csv | sort; } > analytics/clone_history.sorted.csv - mv analytics/clone_history.sorted.csv analytics/clone_history.csv - - - name: Commit changes - run: | - if git diff --quiet; then - echo "No changes." - else - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add analytics/clone_history.csv - git commit -m "Update clone history" - git push - fi diff --git a/.github/workflows/download-metrics.yml b/.github/workflows/download-metrics.yml new file mode 100644 index 0000000..fad8bb1 --- /dev/null +++ b/.github/workflows/download-metrics.yml @@ -0,0 +1,84 @@ +name: Track Download Metrics via GitHub App + +on: + schedule: + - cron: "30 4 * * *" # Every day at 4:30 AM UTC + workflow_dispatch: + +jobs: + track-download-metrics: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: metrics + fetch-depth: 0 + + - name: Authenticate as GitHub App + id: generate_token + uses: tibdex/github-app-token@v2.1.0 + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Retrieve download data + env: + TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + mkdir -p .metrics + echo "Fetching download data for ${{ github.repository }}..." + + # Fetch all pages of releases + curl -s -H "Authorization: Bearer $TOKEN" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/${{ github.repository }}/releases?per_page=100" \ + > .metrics/releases.json + + echo "Raw releases data (first 3 releases):" + jq '.[0:3] | .[] | {tag_name, assets_count: (.assets | length), assets: [.assets[] | {name: .name, download_count: .download_count}]}' .metrics/releases.json + + # Extract download counts from releases + jq '[.[] | {tag_name: .tag_name, published_at: .published_at, assets: [.assets[] | {name: .name, download_count: .download_count}]}]' .metrics/releases.json > .metrics/downloads.json + + echo "Download data summary:" + jq '[.[] | {tag: .tag_name, date: .published_at, total_downloads: ([.assets[].download_count] | add), assets_count: (.assets | length)}]' .metrics/downloads.json + + - name: Update unified download metrics CSV + run: | + mkdir -p .metrics + CSV=".metrics/download_metrics.csv" + + if [ ! -f "$CSV" ]; then + echo "date,release_tag,asset_name,downloads,total_release_downloads" > "$CSV" + fi + + jq -r '.[] | + if (.assets | length > 0) then + .assets[] as $asset | + "\(.published_at[0:10]),\(.tag_name),\($asset.name),\($asset.download_count),\([.assets[].download_count] | add)" + else + "\(.published_at[0:10]),\(.tag_name),,0,0" + end' \ + .metrics/downloads.json \ + | while IFS= read -r line; do + echo "$line" >> "$CSV" + done + + echo "Updated metrics summary:" + tail -n 5 "$CSV" + + - name: Commit and push results + env: + TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + git config user.name "DownloadMetrics[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git add .metrics/download_metrics.csv + git commit -m "Automated update: repository download metrics" || echo "No new data to commit." + git pull --rebase origin metrics || true + git push https://x-access-token:${TOKEN}@github.com/${{ github.repository }} HEAD diff --git a/.github/workflows/traffic-trend.yml b/.github/workflows/traffic-trend.yml deleted file mode 100644 index 1c13725..0000000 --- a/.github/workflows/traffic-trend.yml +++ /dev/null @@ -1,127 +0,0 @@ -name: Track clones & downloads -on: - schedule: [{ cron: "12 9 * * *" }] # daily 09:12 UTC (~04:12 America/Chicago) - workflow_dispatch: - -permissions: - contents: write - actions: read - id-token: write - -jobs: - track: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Install jq - run: sudo apt-get update && sudo apt-get install -y jq - - # ---------- CLONE STATS (14-day window, accumulated to CSV) ---------- - - name: Fetch last 14 days of clone data - env: - REPO: ${{ github.repository }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -H "Authorization: Bearer $GH_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/$REPO/traffic/clones?per=day" > clones.json - - - name: Merge clones into CSV - run: | - mkdir -p analytics - CSV="analytics/clone_history.csv" - [ -f "$CSV" ] || echo "date,clones,unique_cloners" > "$CSV" - - # existing dates to avoid dupes - awk -F, 'NR>1 {print $1}' "$CSV" | sort -u > .existing_clone_dates.txt || true - - jq -r '.clones[] | "\(.timestamp[0:10]),\(.count),\(.uniques)"' clones.json \ - | while IFS= read -r line; do - d="${line%%,*}" - if ! grep -qx "$d" .existing_clone_dates.txt; then - echo "$line" >> "$CSV" - fi - done - - # sort by date (keep header) - { head -n1 "$CSV"; tail -n +2 "$CSV" | sort; } > "$CSV.sorted" - mv "$CSV.sorted" "$CSV" - - # ---------- RELEASE DOWNLOADS (cumulative snapshot per day) ---------- - - name: Fetch all releases (paginate) - env: - REPO: ${{ github.repository }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - set -e - tmpdir=$(mktemp -d) - page=1 - > "$tmpdir/all.json" - while :; do - resp=$(curl -s -H "Authorization: Bearer $GH_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/$REPO/releases?per_page=100&page=$page") - count=$(echo "$resp" | jq 'length') - if [ "$count" -eq 0 ]; then break; fi - echo "$resp" | jq '.[]' >> "$tmpdir/all.json" - page=$((page+1)) - done - - # Wrap into an array if we added anything - if [ -s "$tmpdir/all.json" ]; then - echo "[" > releases.json - # join with commas - sed -e '$!s/$/,/' "$tmpdir/all.json" >> releases.json - echo "]" >> releases.json - else - echo "[]" > releases.json - fi - - - name: Merge downloads into CSVs - run: | - mkdir -p analytics - SNAPCSV="analytics/downloads_snapshot.csv" - TOTCSV="analytics/downloads_totals.csv" - today=$(date -u +%F) - - # Create CSVs if missing - [ -f "$SNAPCSV" ] || echo "date,release_tag,asset_id,asset_name,download_count" > "$SNAPCSV" - [ -f "$TOTCSV" ] || echo "date,total_downloads" > "$TOTCSV" - - # Avoid duplicating today's snapshot rows - # (filter if today's rows already recorded) - if grep -q "^$today," "$SNAPCSV"; then - echo "Download snapshot for $today already exists; skipping append." - else - # Snapshot rows: one per asset - jq -r ' - .[] - | select(.draft==false) - | .tag_name as $tag - | (.assets // []) - | .[] - | [$tag, .id, .name, (.download_count // 0)] - | @csv - ' releases.json \ - | sed 's/^/'"$today"',/' >> "$SNAPCSV" - fi - - # Totals row: sum all asset download_count across all releases - if ! grep -q "^$today," "$TOTCSV"; then - total=$(jq '[ .[] | select(.draft==false) | (.assets // []) | .[] | (.download_count // 0) ] | add // 0' releases.json) - echo "$today,$total" >> "$TOTCSV" - fi - - # ---------- COMMIT ---------- - - name: Commit changes - run: | - if git diff --quiet; then - echo "No changes." - else - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add analytics/clone_history.csv analytics/downloads_snapshot.csv analytics/downloads_totals.csv - git commit -m "Update clone & download history" - git push - fi diff --git a/.github/workflows/view-metrics.yml b/.github/workflows/view-metrics.yml new file mode 100644 index 0000000..97e7f36 --- /dev/null +++ b/.github/workflows/view-metrics.yml @@ -0,0 +1,75 @@ +name: Track View Metrics via GitHub App + +on: + schedule: + - cron: "0 */2 * * *" # Every 2 hours + workflow_dispatch: + +jobs: + track-view-metrics: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: metrics + fetch-depth: 0 + + - name: Authenticate as GitHub App + id: generate_token + uses: tibdex/github-app-token@v2.1.0 + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Retrieve view data + env: + TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + mkdir -p .metrics + echo "Fetching view data for ${{ github.repository }}..." + curl -s -H "Authorization: Bearer $TOKEN" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/${{ github.repository }}/traffic/views?per=day" \ + > .metrics/views.json + jq '. | {total_14d: .count, unique_14d: .uniques, days: (.views|length)}' .metrics/views.json + + - name: Update unified view metrics CSV + run: | + mkdir -p .metrics + CSV=".metrics/view_metrics.csv" + + TOTAL=$(jq '.count' .metrics/views.json) + UNIQUE_TOTAL=$(jq '.uniques' .metrics/views.json) + + if [ ! -f "$CSV" ]; then + echo "date,views,unique_viewers,total_views_14d,unique_viewers_14d" > "$CSV" + fi + + jq -r --arg total "$TOTAL" --arg uniques "$UNIQUE_TOTAL" \ + '.views[] | "\(.timestamp[0:10]),\(.count),\(.uniques),\($total),\($uniques)"' \ + .metrics/views.json \ + | while IFS= read -r line; do + date=$(echo "$line" | cut -d',' -f1) + if ! grep -q "^$date," "$CSV"; then + echo "$line" >> "$CSV" + fi + done + + echo "Updated metrics summary:" + tail -n 5 "$CSV" + + - name: Commit and push results + env: + TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + git config user.name "ViewMetrics[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git add .metrics/view_metrics.csv + git commit -m "Automated update: repository view metrics" || echo "No new data to commit." + git pull --rebase origin metrics || true + git push https://x-access-token:${TOKEN}@github.com/${{ github.repository }} HEAD From 1f6e53d7258c0fc4e1e1a83e56fc1b4f3817ac20 Mon Sep 17 00:00:00 2001 From: Stefano Date: Tue, 7 Oct 2025 09:43:52 -0500 Subject: [PATCH 08/24] Minor fix to download-metrics.yml --- .github/workflows/download-metrics.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/download-metrics.yml b/.github/workflows/download-metrics.yml index fad8bb1..e55a2a1 100644 --- a/.github/workflows/download-metrics.yml +++ b/.github/workflows/download-metrics.yml @@ -63,10 +63,7 @@ jobs: else "\(.published_at[0:10]),\(.tag_name),,0,0" end' \ - .metrics/downloads.json \ - | while IFS= read -r line; do - echo "$line" >> "$CSV" - done + .metrics/downloads.json >> "$CSV" echo "Updated metrics summary:" tail -n 5 "$CSV" From 6cc93fe66a4b45f3dde7166ab45303c098128b34 Mon Sep 17 00:00:00 2001 From: Stefano Dalla Gasperina Date: Tue, 7 Oct 2025 09:45:24 -0500 Subject: [PATCH 09/24] Hotfix/sdg/metrics workflow (#149) * Minor fix to download-metrics.yml --- .github/workflows/download-metrics.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/download-metrics.yml b/.github/workflows/download-metrics.yml index fad8bb1..e55a2a1 100644 --- a/.github/workflows/download-metrics.yml +++ b/.github/workflows/download-metrics.yml @@ -63,10 +63,7 @@ jobs: else "\(.published_at[0:10]),\(.tag_name),,0,0" end' \ - .metrics/downloads.json \ - | while IFS= read -r line; do - echo "$line" >> "$CSV" - done + .metrics/downloads.json >> "$CSV" echo "Updated metrics summary:" tail -n 5 "$CSV" From 50f058592c64a4cba530bc388192babdd1a306df Mon Sep 17 00:00:00 2001 From: Stefano Date: Tue, 7 Oct 2025 09:47:37 -0500 Subject: [PATCH 10/24] Minor fix to download-metrics.yml --- .github/workflows/download-metrics.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/download-metrics.yml b/.github/workflows/download-metrics.yml index e55a2a1..6af1d32 100644 --- a/.github/workflows/download-metrics.yml +++ b/.github/workflows/download-metrics.yml @@ -53,16 +53,10 @@ jobs: CSV=".metrics/download_metrics.csv" if [ ! -f "$CSV" ]; then - echo "date,release_tag,asset_name,downloads,total_release_downloads" > "$CSV" + echo "date,release_tag,total_downloads" > "$CSV" fi - jq -r '.[] | - if (.assets | length > 0) then - .assets[] as $asset | - "\(.published_at[0:10]),\(.tag_name),\($asset.name),\($asset.download_count),\([.assets[].download_count] | add)" - else - "\(.published_at[0:10]),\(.tag_name),,0,0" - end' \ + jq -r '.[] | "\(.published_at[0:10]),\(.tag_name),\([.assets[].download_count] | add)"' \ .metrics/downloads.json >> "$CSV" echo "Updated metrics summary:" From c8bb1cfce7d2ac6b277631ad7264b0991fb4a7aa Mon Sep 17 00:00:00 2001 From: Stefano Dalla Gasperina Date: Tue, 7 Oct 2025 09:49:44 -0500 Subject: [PATCH 11/24] Hotfix/sdg/metrics workflow (#150) * Minor fix to download-metrics.yml --- .github/workflows/download-metrics.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/download-metrics.yml b/.github/workflows/download-metrics.yml index e55a2a1..6af1d32 100644 --- a/.github/workflows/download-metrics.yml +++ b/.github/workflows/download-metrics.yml @@ -53,16 +53,10 @@ jobs: CSV=".metrics/download_metrics.csv" if [ ! -f "$CSV" ]; then - echo "date,release_tag,asset_name,downloads,total_release_downloads" > "$CSV" + echo "date,release_tag,total_downloads" > "$CSV" fi - jq -r '.[] | - if (.assets | length > 0) then - .assets[] as $asset | - "\(.published_at[0:10]),\(.tag_name),\($asset.name),\($asset.download_count),\([.assets[].download_count] | add)" - else - "\(.published_at[0:10]),\(.tag_name),,0,0" - end' \ + jq -r '.[] | "\(.published_at[0:10]),\(.tag_name),\([.assets[].download_count] | add)"' \ .metrics/downloads.json >> "$CSV" echo "Updated metrics summary:" From 3c609636d55cd625a8095be7c67bcb90e2c27370 Mon Sep 17 00:00:00 2001 From: Stefano Date: Tue, 7 Oct 2025 10:06:55 -0500 Subject: [PATCH 12/24] Download-metrics.yml rewrites the file entirely --- .github/workflows/download-metrics.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/download-metrics.yml b/.github/workflows/download-metrics.yml index 6af1d32..873fa6e 100644 --- a/.github/workflows/download-metrics.yml +++ b/.github/workflows/download-metrics.yml @@ -52,12 +52,9 @@ jobs: mkdir -p .metrics CSV=".metrics/download_metrics.csv" - if [ ! -f "$CSV" ]; then - echo "date,release_tag,total_downloads" > "$CSV" - fi - - jq -r '.[] | "\(.published_at[0:10]),\(.tag_name),\([.assets[].download_count] | add)"' \ - .metrics/downloads.json >> "$CSV" + (echo "date,release_tag,total_downloads"; \ + jq -r '.[] | "\(.published_at[0:10]),\(.tag_name),\([.assets[].download_count] | add)"' \ + .metrics/downloads.json) > "$CSV" echo "Updated metrics summary:" tail -n 5 "$CSV" From 45bcdd31a1f142ffef5b89c53308fb20866ae24e Mon Sep 17 00:00:00 2001 From: Stefano Dalla Gasperina Date: Wed, 8 Oct 2025 01:44:24 -0500 Subject: [PATCH 13/24] Updated workflows (#155) --- .github/workflows/clone-metrics.yml | 149 +++++++++++++++++++------ .github/workflows/download-metrics.yml | 108 ++++++++++++------ .github/workflows/view-metrics.yml | 149 +++++++++++++++++++------ 3 files changed, 296 insertions(+), 110 deletions(-) diff --git a/.github/workflows/clone-metrics.yml b/.github/workflows/clone-metrics.yml index e66dd1a..5a17822 100644 --- a/.github/workflows/clone-metrics.yml +++ b/.github/workflows/clone-metrics.yml @@ -2,11 +2,11 @@ name: Track Clone Metrics via GitHub App on: schedule: - - cron: "30 4 * * *" # Every day at 4:30 AM UTC + - cron: '30 * * * *' # Run every hour at minute 30 workflow_dispatch: jobs: - track-clone-metrics: + clone-stats: runs-on: ubuntu-latest permissions: contents: write @@ -15,61 +15,136 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 with: - ref: metrics - fetch-depth: 0 + fetch-depth: 0 # Fetch all history for proper branch operations - - name: Authenticate as GitHub App + - name: Generate GitHub App token id: generate_token uses: tibdex/github-app-token@v2.1.0 with: app_id: ${{ secrets.APP_ID }} private_key: ${{ secrets.APP_PRIVATE_KEY }} - - name: Retrieve clone data + - name: Switch to metrics branch + run: | + # Checkout or create metrics branch + if git show-ref --verify --quiet refs/remotes/origin/metrics; then + echo "📋 Checking out existing metrics branch..." + git checkout -b metrics origin/metrics || git checkout metrics + else + echo "🆕 Creating new metrics branch..." + git checkout -b metrics + fi + + - name: Fetch clone data env: TOKEN: ${{ steps.generate_token.outputs.token }} run: | mkdir -p .metrics - echo "Fetching clone data for ${{ github.repository }}..." - curl -s -H "Authorization: Bearer $TOKEN" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/${{ github.repository }}/traffic/clones?per=day" \ - > .metrics/clones.json - jq '. | {total_14d: .count, unique_14d: .uniques, days: (.clones|length)}' .metrics/clones.json - - - name: Update unified clone metrics CSV + # Fetch clone metrics (contains both daily breakdown and 14-day totals) + curl -s -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $TOKEN" \ + https://api.github.com/repos/${{ github.repository }}/traffic/clones \ + > .metrics/clone_stats.json + + echo "Clone metrics:" + cat .metrics/clone_stats.json + + - name: Update daily metrics run: | - mkdir -p .metrics - CSV=".metrics/clone_metrics.csv" + # Process each day from the clones array + LAST_UPDATED=$(date -u +"%Y-%m-%d %H:%M:%S UTC") + + # Create daily CSV with header if it doesn't exist + if [ ! -f .metrics/daily_clone_metrics.csv ]; then + echo "date,total_clones,unique_cloners,last_updated" > .metrics/daily_clone_metrics.csv + fi + + echo "📊 Processing daily metrics..." + jq -r '.clones[] | "\(.timestamp | split("T")[0]),\(.count),\(.uniques)"' .metrics/clone_stats.json | while IFS=',' read -r day_date count uniques; do + echo "Processing $day_date: $count clones, $uniques unique" + + # Check if this date already exists in the CSV + if grep -q "^$day_date" .metrics/daily_clone_metrics.csv; then + echo "📝 Updating existing entry for $day_date..." + # Update existing entry + awk -v date="$day_date" -v count="$count" -v uniques="$uniques" -v last_updated="$LAST_UPDATED" ' + BEGIN { FS=","; OFS="," } + /^[0-9]{4}-[0-9]{2}-[0-9]{2}/ && $1 == date { + print $1, count, uniques, last_updated; + updated=1; + next + } + { print } + ' .metrics/daily_clone_metrics.csv > .metrics/daily_clone_metrics_temp.csv + mv .metrics/daily_clone_metrics_temp.csv .metrics/daily_clone_metrics.csv + else + echo "➕ Adding new daily entry for $day_date..." + echo "$day_date,$count,$uniques,$LAST_UPDATED" >> .metrics/daily_clone_metrics.csv + fi + done - TOTAL=$(jq '.count' .metrics/clones.json) - UNIQUE_TOTAL=$(jq '.uniques' .metrics/clones.json) + echo "Daily metrics:" + tail -n 5 .metrics/daily_clone_metrics.csv - if [ ! -f "$CSV" ]; then - echo "date,clones,unique_cloners,total_clones_14d,unique_cloners_14d" > "$CSV" + - name: Update 14-day rolling metrics + run: | + # Process 14-day metrics + COUNT_14D=$(jq '.count' .metrics/clone_stats.json) + UNIQUES_14D=$(jq '.uniques' .metrics/clone_stats.json) + DATE_ONLY=$(date -u +"%Y-%m-%d") + LAST_UPDATED=$(date -u +"%Y-%m-%d %H:%M:%S UTC") + + echo "📊 Processing 14-day metrics... for date: $DATE_ONLY" + echo "Processing values: $COUNT_14D clones, $UNIQUES_14D unique" + + # Create 14-day CSV with header if it doesn't exist + if [ ! -f .metrics/rolling_14d_clone_metrics.csv ]; then + echo "date,total_clones_14d,unique_cloners_14d,last_updated" > .metrics/rolling_14d_clone_metrics.csv + echo "📄 Created new 14-day rolling CSV file" fi - jq -r --arg total "$TOTAL" --arg uniques "$UNIQUE_TOTAL" \ - '.clones[] | "\(.timestamp[0:10]),\(.count),\(.uniques),\($total),\($uniques)"' \ - .metrics/clones.json \ - | while IFS= read -r line; do - date=$(echo "$line" | cut -d',' -f1) - if ! grep -q "^$date," "$CSV"; then - echo "$line" >> "$CSV" - fi - done + # Check if today's date already exists in the 14-day CSV + if grep -q "^$DATE_ONLY" .metrics/rolling_14d_clone_metrics.csv; then + echo "📝 Updating existing 14-day rolling entry for $DATE_ONLY..." + # Update existing entry + awk -v date="$DATE_ONLY" -v count="$COUNT_14D" -v uniques="$UNIQUES_14D" -v last_updated="$LAST_UPDATED" ' + BEGIN { FS=","; OFS=","; updated=0 } + /^[0-9]{4}-[0-9]{2}-[0-9]{2}/ && $1 == date { + print $1, count, uniques, last_updated; + updated=1; + next + } + { print } + END { if (!updated) print date, count, uniques, last_updated } + ' .metrics/rolling_14d_clone_metrics.csv > .metrics/rolling_14d_clone_metrics_temp.csv + mv .metrics/rolling_14d_clone_metrics_temp.csv .metrics/rolling_14d_clone_metrics.csv + echo "✅ Updated existing entry" + else + echo "➕ Adding new 14-day rolling entry for $DATE_ONLY..." + echo "$DATE_ONLY,$COUNT_14D,$UNIQUES_14D,$LAST_UPDATED" >> .metrics/rolling_14d_clone_metrics.csv + echo "✅ Added new entry" + fi - echo "Updated metrics summary:" - tail -n 5 "$CSV" + echo "14-day rolling metrics:" + tail -n 5 .metrics/rolling_14d_clone_metrics.csv - name: Commit and push results env: - TOKEN: ${{ steps.generate_token.outputs.token }} + GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} run: | - git config user.name "CloneMetrics[bot]" + git config user.name "CloneMetricsBot[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add .metrics/clone_metrics.csv - git commit -m "Automated update: repository clone metrics" || echo "No new data to commit." - git pull --rebase origin metrics || true - git push https://x-access-token:${TOKEN}@github.com/${{ github.repository }} HEAD + # Add both CSV files + git add .metrics/daily_clone_metrics.csv .metrics/rolling_14d_clone_metrics.csv + + # Check if there are changes to commit + if git diff --staged --quiet; then + echo "â„šī¸ No changes to commit - CSV data is up to date" + else + echo "📝 Committing changes..." + git commit -m "Automated update: repository clone metrics $(date)" + + echo "🚀 Pushing to metrics branch..." + git push --force-with-lease origin metrics + fi diff --git a/.github/workflows/download-metrics.yml b/.github/workflows/download-metrics.yml index 873fa6e..b554a00 100644 --- a/.github/workflows/download-metrics.yml +++ b/.github/workflows/download-metrics.yml @@ -2,11 +2,11 @@ name: Track Download Metrics via GitHub App on: schedule: - - cron: "30 4 * * *" # Every day at 4:30 AM UTC + - cron: '30 * * * *' # Run every hour at minute 30 workflow_dispatch: jobs: - track-download-metrics: + download-stats: runs-on: ubuntu-latest permissions: contents: write @@ -15,58 +15,94 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 with: - ref: metrics - fetch-depth: 0 + fetch-depth: 0 # Fetch all history for proper branch operations - - name: Authenticate as GitHub App + - name: Generate GitHub App token id: generate_token uses: tibdex/github-app-token@v2.1.0 with: app_id: ${{ secrets.APP_ID }} private_key: ${{ secrets.APP_PRIVATE_KEY }} - - name: Retrieve download data + - name: Switch to metrics branch + run: | + # Checkout or create metrics branch + if git show-ref --verify --quiet refs/remotes/origin/metrics; then + echo "📋 Checking out existing metrics branch..." + git checkout -b metrics origin/metrics || git checkout metrics + else + echo "🆕 Creating new metrics branch..." + git checkout -b metrics + fi + + - name: Fetch download data env: TOKEN: ${{ steps.generate_token.outputs.token }} run: | mkdir -p .metrics - echo "Fetching download data for ${{ github.repository }}..." - - # Fetch all pages of releases - curl -s -H "Authorization: Bearer $TOKEN" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/${{ github.repository }}/releases?per_page=100" \ - > .metrics/releases.json - - echo "Raw releases data (first 3 releases):" - jq '.[0:3] | .[] | {tag_name, assets_count: (.assets | length), assets: [.assets[] | {name: .name, download_count: .download_count}]}' .metrics/releases.json - - # Extract download counts from releases - jq '[.[] | {tag_name: .tag_name, published_at: .published_at, assets: [.assets[] | {name: .name, download_count: .download_count}]}]' .metrics/releases.json > .metrics/downloads.json + # Fetch download metrics from releases + curl -s -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $TOKEN" \ + "https://api.github.com/repos/${{ github.repository }}/releases?per_page=100" \ + > .metrics/releases.json - echo "Download data summary:" - jq '[.[] | {tag: .tag_name, date: .published_at, total_downloads: ([.assets[].download_count] | add), assets_count: (.assets | length)}]' .metrics/downloads.json - - - name: Update unified download metrics CSV + echo "Download metrics:" + jq '[.[] | {tag: .tag_name, date: .published_at, total_downloads: ([.assets[].download_count] | add), assets_count: (.assets | length)}]' .metrics/releases.json + + - name: Update total download metrics run: | - mkdir -p .metrics - CSV=".metrics/download_metrics.csv" + # Process each release from the releases array + LAST_UPDATED=$(date -u +"%Y-%m-%d %H:%M:%S UTC") + + # Create total download CSV with header if it doesn't exist + if [ ! -f .metrics/total_download_metrics.csv ]; then + echo "date,release_tag,total_downloads,last_updated" > .metrics/total_download_metrics.csv + fi - (echo "date,release_tag,total_downloads"; \ - jq -r '.[] | "\(.published_at[0:10]),\(.tag_name),\([.assets[].download_count] | add)"' \ - .metrics/downloads.json) > "$CSV" + echo "📊 Processing total download metrics..." + jq -r '.[] | "\(.published_at[0:10]),\(.tag_name),\([.assets[].download_count] | add)"' .metrics/releases.json | while IFS=',' read -r release_date tag_name total_downloads; do + echo "Processing $release_date: $tag_name - $total_downloads downloads" + + # Check if this release already exists in the CSV + if grep -q ",$tag_name," .metrics/total_download_metrics.csv; then + echo "📝 Updating existing entry for $tag_name..." + # Update existing entry + awk -v tag="$tag_name" -v downloads="$total_downloads" -v last_updated="$LAST_UPDATED" ' + BEGIN { FS=","; OFS="," } + $2 == tag { + print $1, $2, downloads, last_updated; + updated=1; + next + } + { print } + ' .metrics/total_download_metrics.csv > .metrics/total_download_metrics_temp.csv + mv .metrics/total_download_metrics_temp.csv .metrics/total_download_metrics.csv + else + echo "➕ Adding new download entry for $tag_name..." + echo "$release_date,$tag_name,$total_downloads,$LAST_UPDATED" >> .metrics/total_download_metrics.csv + fi + done - echo "Updated metrics summary:" - tail -n 5 "$CSV" + echo "Total download metrics:" + tail -n 5 .metrics/total_download_metrics.csv - name: Commit and push results env: - TOKEN: ${{ steps.generate_token.outputs.token }} + GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} run: | - git config user.name "DownloadMetrics[bot]" + git config user.name "DownloadMetricsBot[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add .metrics/download_metrics.csv - git commit -m "Automated update: repository download metrics" || echo "No new data to commit." - git pull --rebase origin metrics || true - git push https://x-access-token:${TOKEN}@github.com/${{ github.repository }} HEAD + # Add CSV file + git add .metrics/total_download_metrics.csv + + # Check if there are changes to commit + if git diff --staged --quiet; then + echo "â„šī¸ No changes to commit - CSV data is up to date" + else + echo "📝 Committing changes..." + git commit -m "Automated update: repository download metrics $(date)" + + echo "🚀 Pushing to metrics branch..." + git push --force-with-lease origin metrics + fi diff --git a/.github/workflows/view-metrics.yml b/.github/workflows/view-metrics.yml index 97e7f36..6759b1b 100644 --- a/.github/workflows/view-metrics.yml +++ b/.github/workflows/view-metrics.yml @@ -2,11 +2,11 @@ name: Track View Metrics via GitHub App on: schedule: - - cron: "0 */2 * * *" # Every 2 hours + - cron: '30 * * * *' # Run every hour at minute 30 workflow_dispatch: jobs: - track-view-metrics: + view-stats: runs-on: ubuntu-latest permissions: contents: write @@ -15,61 +15,136 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 with: - ref: metrics - fetch-depth: 0 + fetch-depth: 0 # Fetch all history for proper branch operations - - name: Authenticate as GitHub App + - name: Generate GitHub App token id: generate_token uses: tibdex/github-app-token@v2.1.0 with: app_id: ${{ secrets.APP_ID }} private_key: ${{ secrets.APP_PRIVATE_KEY }} - - name: Retrieve view data + - name: Switch to metrics branch + run: | + # Checkout or create metrics branch + if git show-ref --verify --quiet refs/remotes/origin/metrics; then + echo "📋 Checking out existing metrics branch..." + git checkout -b metrics origin/metrics || git checkout metrics + else + echo "🆕 Creating new metrics branch..." + git checkout -b metrics + fi + + - name: Fetch view data env: TOKEN: ${{ steps.generate_token.outputs.token }} run: | mkdir -p .metrics - echo "Fetching view data for ${{ github.repository }}..." - curl -s -H "Authorization: Bearer $TOKEN" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/${{ github.repository }}/traffic/views?per=day" \ - > .metrics/views.json - jq '. | {total_14d: .count, unique_14d: .uniques, days: (.views|length)}' .metrics/views.json - - - name: Update unified view metrics CSV + # Fetch view metrics (contains both daily breakdown and 14-day totals) + curl -s -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $TOKEN" \ + https://api.github.com/repos/${{ github.repository }}/traffic/views \ + > .metrics/view_stats.json + + echo "View metrics:" + cat .metrics/view_stats.json + + - name: Update daily metrics run: | - mkdir -p .metrics - CSV=".metrics/view_metrics.csv" + # Process each day from the views array + LAST_UPDATED=$(date -u +"%Y-%m-%d %H:%M:%S UTC") + + # Create daily CSV with header if it doesn't exist + if [ ! -f .metrics/daily_view_metrics.csv ]; then + echo "date,total_views,unique_visitors,last_updated" > .metrics/daily_view_metrics.csv + fi - TOTAL=$(jq '.count' .metrics/views.json) - UNIQUE_TOTAL=$(jq '.uniques' .metrics/views.json) + echo "📊 Processing daily metrics..." + jq -r '.views[] | "\(.timestamp | split("T")[0]),\(.count),\(.uniques)"' .metrics/view_stats.json | while IFS=',' read -r day_date count uniques; do + echo "Processing $day_date: $count views, $uniques unique" + + # Check if this date already exists in the CSV + if grep -q "^$day_date" .metrics/daily_view_metrics.csv; then + echo "📝 Updating existing entry for $day_date..." + # Update existing entry + awk -v date="$day_date" -v count="$count" -v uniques="$uniques" -v last_updated="$LAST_UPDATED" ' + BEGIN { FS=","; OFS="," } + /^[0-9]{4}-[0-9]{2}-[0-9]{2}/ && $1 == date { + print $1, count, uniques, last_updated; + updated=1; + next + } + { print } + ' .metrics/daily_view_metrics.csv > .metrics/daily_view_metrics_temp.csv + mv .metrics/daily_view_metrics_temp.csv .metrics/daily_view_metrics.csv + else + echo "➕ Adding new daily entry for $day_date..." + echo "$day_date,$count,$uniques,$LAST_UPDATED" >> .metrics/daily_view_metrics.csv + fi + done - if [ ! -f "$CSV" ]; then - echo "date,views,unique_viewers,total_views_14d,unique_viewers_14d" > "$CSV" + echo "Daily metrics:" + tail -n 5 .metrics/daily_view_metrics.csv + + - name: Update 14-day rolling metrics + run: | + # Process 14-day metrics + COUNT_14D=$(jq '.count' .metrics/view_stats.json) + UNIQUES_14D=$(jq '.uniques' .metrics/view_stats.json) + DATE_ONLY=$(date -u +"%Y-%m-%d") + LAST_UPDATED=$(date -u +"%Y-%m-%d %H:%M:%S UTC") + + echo "📊 Processing 14-day metrics... for date: $DATE_ONLY" + echo "Processing values: $COUNT_14D views, $UNIQUES_14D unique" + + # Create 14-day CSV with header if it doesn't exist + if [ ! -f .metrics/rolling_14d_view_metrics.csv ]; then + echo "date,total_views_14d,unique_visitors_14d,last_updated" > .metrics/rolling_14d_view_metrics.csv + echo "📄 Created new 14-day rolling CSV file" fi - jq -r --arg total "$TOTAL" --arg uniques "$UNIQUE_TOTAL" \ - '.views[] | "\(.timestamp[0:10]),\(.count),\(.uniques),\($total),\($uniques)"' \ - .metrics/views.json \ - | while IFS= read -r line; do - date=$(echo "$line" | cut -d',' -f1) - if ! grep -q "^$date," "$CSV"; then - echo "$line" >> "$CSV" - fi - done + # Check if today's date already exists in the 14-day CSV + if grep -q "^$DATE_ONLY" .metrics/rolling_14d_view_metrics.csv; then + echo "📝 Updating existing 14-day rolling entry for $DATE_ONLY..." + # Update existing entry + awk -v date="$DATE_ONLY" -v count="$COUNT_14D" -v uniques="$UNIQUES_14D" -v last_updated="$LAST_UPDATED" ' + BEGIN { FS=","; OFS=","; updated=0 } + /^[0-9]{4}-[0-9]{2}-[0-9]{2}/ && $1 == date { + print $1, count, uniques, last_updated; + updated=1; + next + } + { print } + END { if (!updated) print date, count, uniques, last_updated } + ' .metrics/rolling_14d_view_metrics.csv > .metrics/rolling_14d_view_metrics_temp.csv + mv .metrics/rolling_14d_view_metrics_temp.csv .metrics/rolling_14d_view_metrics.csv + echo "✅ Updated existing entry" + else + echo "➕ Adding new 14-day rolling entry for $DATE_ONLY..." + echo "$DATE_ONLY,$COUNT_14D,$UNIQUES_14D,$LAST_UPDATED" >> .metrics/rolling_14d_view_metrics.csv + echo "✅ Added new entry" + fi - echo "Updated metrics summary:" - tail -n 5 "$CSV" + echo "14-day rolling metrics:" + tail -n 5 .metrics/rolling_14d_view_metrics.csv - name: Commit and push results env: - TOKEN: ${{ steps.generate_token.outputs.token }} + GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} run: | - git config user.name "ViewMetrics[bot]" + git config user.name "ViewMetricsBot[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add .metrics/view_metrics.csv - git commit -m "Automated update: repository view metrics" || echo "No new data to commit." - git pull --rebase origin metrics || true - git push https://x-access-token:${TOKEN}@github.com/${{ github.repository }} HEAD + # Add both CSV files + git add .metrics/daily_view_metrics.csv .metrics/rolling_14d_view_metrics.csv + + # Check if there are changes to commit + if git diff --staged --quiet; then + echo "â„šī¸ No changes to commit - CSV data is up to date" + else + echo "📝 Committing changes..." + git commit -m "Automated update: repository view metrics $(date)" + + echo "🚀 Pushing to metrics branch..." + git push --force-with-lease origin metrics + fi \ No newline at end of file From afbf1fb890a0053b9d72117386c0c53176db8f7a Mon Sep 17 00:00:00 2001 From: Rohit John Varghese Date: Wed, 8 Oct 2025 20:44:02 -0500 Subject: [PATCH 14/24] added server name to the readme file --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7f26704..23fff23 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ ![GitHub Repo stars](https://img.shields.io/github/stars/robotmcp/ros-mcp-server?style=social) ![GitHub last commit](https://img.shields.io/github/last-commit/robotmcp/ros-mcp-server) +

From 52fcec95530d4f17f7e7641dd059273b7431ce3f Mon Sep 17 00:00:00 2001 From: Rohit John Varghese Date: Wed, 8 Oct 2025 20:56:23 -0500 Subject: [PATCH 15/24] added workflow dispatch to the publish github action --- .github/workflows/publish.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b94aeeb..23700d4 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,6 +4,7 @@ on: push: tags: - "v*" + workflow_dispatch: concurrency: group: publish-${{ github.ref }} From 7d49715347d7ba332e5a5b6a8f7585934ceb5d5f Mon Sep 17 00:00:00 2001 From: Rohit John Varghese Date: Wed, 8 Oct 2025 21:06:12 -0500 Subject: [PATCH 16/24] updated version number in the hotfix --- pyproject.toml | 2 +- server.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f4089c7..8d05588 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "ros-mcp" -version = "2.1.4" +version = "2.1.5" description = "Connect AI Language Models with Robots on ROS using MCP" readme = "README.md" requires-python = ">=3.10" diff --git a/server.json b/server.json index 59f0b47..ba50755 100644 --- a/server.json +++ b/server.json @@ -2,12 +2,12 @@ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json", "name": "io.github.robotmcp/ros-mcp-server", "description": "Connect AI models like Claude & ChatGPT with ROS robots using MCP", - "version": "2.1.4", + "version": "2.1.5", "packages": [ { "registry_type": "pypi", "identifier": "ros-mcp", - "version": "2.1.4" + "version": "2.1.5" } ], "transport": { From 6ec1a45b474ef8aedf586f877fd71704e6d6cf6e Mon Sep 17 00:00:00 2001 From: Stefano Dalla Gasperina Date: Wed, 8 Oct 2025 21:46:27 -0500 Subject: [PATCH 17/24] Feature/sdg/registry (#161) * Auto-generated server.json * Merged main changes on version/README * Auto-generated server.json * Added workflow_dispatch * Added separate workflows * Remove trigger on tag --- .github/workflows/publish.yml | 3 -- .github/workflows/publish_mcp.yml | 40 ++++++++++++++++++++ .github/workflows/publish_pypi.yml | 60 ++++++++++++++++++++++++++++++ server.json | 25 ++++++++----- 4 files changed, 115 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/publish_mcp.yml create mode 100644 .github/workflows/publish_pypi.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 23700d4..47da792 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,9 +1,6 @@ name: Publish (PyPI + MCP Registry) on: - push: - tags: - - "v*" workflow_dispatch: concurrency: diff --git a/.github/workflows/publish_mcp.yml b/.github/workflows/publish_mcp.yml new file mode 100644 index 0000000..6d0cebd --- /dev/null +++ b/.github/workflows/publish_mcp.yml @@ -0,0 +1,40 @@ +name: Publish MCP Registry + +on: + workflow_dispatch: + workflow_run: + workflows: ["Build"] # exact name of workflow 1 + types: + - completed + push: + tags: + - "v*" + +concurrency: + group: publish-${{ github.ref }} + cancel-in-progress: true + +jobs: + registry: + name: Publish to MCP Registry + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # REQUIRED for MCP Registry GitHub OIDC login + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install MCP Publisher + run: | + set -e + OS=$(uname -s | tr '[:upper:]' '[:lower:]') + ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') + curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.0.0/mcp-publisher_1.0.0_${OS}_${ARCH}.tar.gz" \ + | tar xz mcp-publisher + + - name: Login to MCP Registry (OIDC) + run: ./mcp-publisher login github-oidc + + - name: Publish server.json to MCP Registry + run: ./mcp-publisher publish diff --git a/.github/workflows/publish_pypi.yml b/.github/workflows/publish_pypi.yml new file mode 100644 index 0000000..9cca07e --- /dev/null +++ b/.github/workflows/publish_pypi.yml @@ -0,0 +1,60 @@ +name: Publish to PyPI Only + +on: + workflow_dispatch: + push: + tags: + - "v*" + +concurrency: + group: publish-pypi-${{ github.ref }} + cancel-in-progress: true + +jobs: + pypi: + name: Publish to PyPI + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # REQUIRED for PyPI Trusted Publishing (OIDC) + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install uv + run: pipx install uv + + # --- Optional checks (keep for now; can be moved to PR CI later) --- + - name: Sync deps + run: uv sync + + - name: Ruff lint + run: uvx ruff check . + + - name: Ruff format check + run: uvx ruff format --check . + + - name: Run tests (if present) + run: | + if [ -d tests ]; then + uv run pytest -q + else + echo "No tests/ directory; skipping." + fi + + # --- Build artifacts for PyPI --- + - name: Build sdist & wheel + run: uv build + + # --- Publish using Trusted Publishing (no tokens) --- + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist + # For a dress rehearsal, you can set: + # repository-url: https://test.pypi.org/legacy/ \ No newline at end of file diff --git a/server.json b/server.json index ba50755..4f0d28f 100644 --- a/server.json +++ b/server.json @@ -1,18 +1,23 @@ { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", "name": "io.github.robotmcp/ros-mcp-server", "description": "Connect AI models like Claude & ChatGPT with ROS robots using MCP", + "repository": { + "url": "https://github.com/robotmcp/ros-mcp-server", + "source": "github" + }, "version": "2.1.5", "packages": [ { - "registry_type": "pypi", + "registryType": "pypi", + "registryBaseUrl": "https://pypi.org", "identifier": "ros-mcp", - "version": "2.1.5" + "version": "2.1.5", + "transport": { + "type": "stdio", + "command": "ros-mcp", + "args": [] + } } - ], - "transport": { - "type": "stdio", - "command": "ros-mcp", - "args": [] - } -} + ] +} \ No newline at end of file From b2c45184233d7faaeaac105dfd9001b5953d445b Mon Sep 17 00:00:00 2001 From: Stefano Dalla Gasperina Date: Wed, 8 Oct 2025 22:08:50 -0500 Subject: [PATCH 18/24] Feature/sdg/registry (#162) * Modified mcp-publisher to use latest release --- .github/workflows/publish_mcp.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish_mcp.yml b/.github/workflows/publish_mcp.yml index 6d0cebd..ef23c66 100644 --- a/.github/workflows/publish_mcp.yml +++ b/.github/workflows/publish_mcp.yml @@ -30,11 +30,19 @@ jobs: set -e OS=$(uname -s | tr '[:upper:]' '[:lower:]') ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') - curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.0.0/mcp-publisher_1.0.0_${OS}_${ARCH}.tar.gz" \ + echo "Get the latest release version" + LATEST_VERSION=$(curl -s https://api.github.com/repos/modelcontextprotocol/registry/releases/latest | jq -r '.tag_name') + echo "Installing MCP Publisher version: $LATEST_VERSION" + echo "Download and extract the latest release" + curl -L "https://github.com/modelcontextprotocol/registry/releases/download/${LATEST_VERSION}/mcp-publisher_${LATEST_VERSION#v}_${OS}_${ARCH}.tar.gz" \ | tar xz mcp-publisher - name: Login to MCP Registry (OIDC) - run: ./mcp-publisher login github-oidc + run: | + echo "Login to MCP Registry (OIDC)" + ./mcp-publisher login github-oidc - name: Publish server.json to MCP Registry - run: ./mcp-publisher publish + run: | + echo "Publish server.json to MCP Registry" + ./mcp-publisher publish From 3457f703c4ec89eda35ae8a2022b4ec999ce82c4 Mon Sep 17 00:00:00 2001 From: Stefano Dalla Gasperina Date: Wed, 8 Oct 2025 22:24:00 -0500 Subject: [PATCH 19/24] Feature/sdg/registry (#163) * Fallback for duplicate push on MCP Registry --- .github/workflows/publish_mcp.yml | 27 +++++++++++++++++++++++++-- .github/workflows/publish_pypi.yml | 4 ++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish_mcp.yml b/.github/workflows/publish_mcp.yml index ef23c66..7008ab6 100644 --- a/.github/workflows/publish_mcp.yml +++ b/.github/workflows/publish_mcp.yml @@ -33,7 +33,6 @@ jobs: echo "Get the latest release version" LATEST_VERSION=$(curl -s https://api.github.com/repos/modelcontextprotocol/registry/releases/latest | jq -r '.tag_name') echo "Installing MCP Publisher version: $LATEST_VERSION" - echo "Download and extract the latest release" curl -L "https://github.com/modelcontextprotocol/registry/releases/download/${LATEST_VERSION}/mcp-publisher_${LATEST_VERSION#v}_${OS}_${ARCH}.tar.gz" \ | tar xz mcp-publisher @@ -45,4 +44,28 @@ jobs: - name: Publish server.json to MCP Registry run: | echo "Publish server.json to MCP Registry" - ./mcp-publisher publish + # Try to publish, with fallback for duplicate version + if ./mcp-publisher publish; then + echo "Successfully published to MCP Registry" + else + PUBLISH_EXIT_CODE=$? + echo "Publish failed with exit code: $PUBLISH_EXIT_CODE" + + # Check if it's a duplicate version error + if [ $PUBLISH_EXIT_CODE -ne 0 ]; then + echo "Checking if version already exists in registry..." + + # Get current version from server.json + CURRENT_VERSION=$(jq -r '.version' server.json) + echo "Current version: $CURRENT_VERSION" + + # Check if version exists in registry + if curl -s "https://registry.modelcontextprotocol.io/v0/servers/io.github.robotmcp/ros-mcp-server" | jq -e ".version == \"$CURRENT_VERSION\"" > /dev/null; then + echo "Version $CURRENT_VERSION already exists in registry. Skipping publication." + echo "Server is already published with version $CURRENT_VERSION" + else + echo "Publication failed for unknown reason" + exit $PUBLISH_EXIT_CODE + fi + fi + fi diff --git a/.github/workflows/publish_pypi.yml b/.github/workflows/publish_pypi.yml index 9cca07e..a821dc2 100644 --- a/.github/workflows/publish_pypi.yml +++ b/.github/workflows/publish_pypi.yml @@ -1,4 +1,4 @@ -name: Publish to PyPI Only +name: Publish PyPI on: workflow_dispatch: @@ -12,7 +12,7 @@ concurrency: jobs: pypi: - name: Publish to PyPI + name: Publish PyPI runs-on: ubuntu-latest permissions: contents: read From f72c69bcdfde316ae9d1a9a7ad548f431b23c1a0 Mon Sep 17 00:00:00 2001 From: Stefano Dalla Gasperina Date: Wed, 8 Oct 2025 22:45:41 -0500 Subject: [PATCH 20/24] Feature/sdg/registry Minor changes to workflows to chain PyPI (#164) * Removed unified publish workflow --- .github/workflows/publish.yml | 86 ------------------------------- .github/workflows/publish_mcp.yml | 14 +---- 2 files changed, 1 insertion(+), 99 deletions(-) delete mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 47da792..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: Publish (PyPI + MCP Registry) - -on: - workflow_dispatch: - -concurrency: - group: publish-${{ github.ref }} - cancel-in-progress: true - -jobs: - pypi: - name: Publish to PyPI - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write # REQUIRED for PyPI Trusted Publishing (OIDC) - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install uv - run: pipx install uv - - # --- Optional checks (keep for now; can be moved to PR CI later) --- - - name: Sync deps - run: uv sync - - - name: Ruff lint - run: uvx ruff check . - - - name: Ruff format check - run: uvx ruff format --check . - - - name: Run tests (if present) - run: | - if [ -d tests ]; then - uv run pytest -q - else - echo "No tests/ directory; skipping." - fi - - # --- Build artifacts for PyPI --- - - name: Build sdist & wheel - run: uv build - - # --- Publish using Trusted Publishing (no tokens) --- - - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - with: - packages-dir: dist - # For a dress rehearsal, you can set: - # repository-url: https://test.pypi.org/legacy/ - - registry: - name: Publish to MCP Registry - runs-on: ubuntu-latest - needs: pypi - permissions: - contents: read - id-token: write # REQUIRED for MCP Registry GitHub OIDC login - steps: - - name: Checkout - uses: actions/checkout@v4 - - # Small delay to allow PyPI metadata to propagate - - name: Wait briefly - run: sleep 20 - - - name: Install MCP Publisher - run: | - set -e - OS=$(uname -s | tr '[:upper:]' '[:lower:]') - ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') - curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.0.0/mcp-publisher_1.0.0_${OS}_${ARCH}.tar.gz" \ - | tar xz mcp-publisher - - - name: Login to MCP Registry (OIDC) - run: ./mcp-publisher login github-oidc - - - name: Publish server.json to MCP Registry - run: ./mcp-publisher publish diff --git a/.github/workflows/publish_mcp.yml b/.github/workflows/publish_mcp.yml index 7008ab6..26c07d1 100644 --- a/.github/workflows/publish_mcp.yml +++ b/.github/workflows/publish_mcp.yml @@ -3,12 +3,9 @@ name: Publish MCP Registry on: workflow_dispatch: workflow_run: - workflows: ["Build"] # exact name of workflow 1 + workflows: ["Publish PyPI"] # exact name of PyPI workflow types: - completed - push: - tags: - - "v*" concurrency: group: publish-${{ github.ref }} @@ -58,14 +55,5 @@ jobs: # Get current version from server.json CURRENT_VERSION=$(jq -r '.version' server.json) echo "Current version: $CURRENT_VERSION" - - # Check if version exists in registry - if curl -s "https://registry.modelcontextprotocol.io/v0/servers/io.github.robotmcp/ros-mcp-server" | jq -e ".version == \"$CURRENT_VERSION\"" > /dev/null; then - echo "Version $CURRENT_VERSION already exists in registry. Skipping publication." - echo "Server is already published with version $CURRENT_VERSION" - else - echo "Publication failed for unknown reason" - exit $PUBLISH_EXIT_CODE - fi fi fi From f583ba437a2738492071851a9661cfe7135030b2 Mon Sep 17 00:00:00 2001 From: Stefano Dalla Gasperina Date: Wed, 8 Oct 2025 23:27:03 -0500 Subject: [PATCH 21/24] Hotfix/v2.1.6 (#165) * hotfix/2.1.6 --- .github/workflows/clone-metrics.yml | 4 +- .github/workflows/download-metrics.yml | 8 ++-- .github/workflows/publish_mcp.yml | 51 ++++++++++---------------- pyproject.toml | 2 +- server.json | 4 +- uv.lock | 4 +- 6 files changed, 32 insertions(+), 41 deletions(-) diff --git a/.github/workflows/clone-metrics.yml b/.github/workflows/clone-metrics.yml index 5a17822..d1a081a 100644 --- a/.github/workflows/clone-metrics.yml +++ b/.github/workflows/clone-metrics.yml @@ -1,8 +1,8 @@ -name: Track Clone Metrics via GitHub App +name: Track Clone Metrics on: schedule: - - cron: '30 * * * *' # Run every hour at minute 30 + - cron: '0 8 * * *' # Run every day at 8am workflow_dispatch: jobs: diff --git a/.github/workflows/download-metrics.yml b/.github/workflows/download-metrics.yml index b554a00..e8ccdac 100644 --- a/.github/workflows/download-metrics.yml +++ b/.github/workflows/download-metrics.yml @@ -1,9 +1,11 @@ -name: Track Download Metrics via GitHub App +name: Track Download Metrics on: - schedule: - - cron: '30 * * * *' # Run every hour at minute 30 workflow_dispatch: + workflow_run: + workflows: ["Track View Metrics"] # exact name of PyPI workflow + types: + - completed jobs: download-stats: diff --git a/.github/workflows/publish_mcp.yml b/.github/workflows/publish_mcp.yml index 26c07d1..86afc72 100644 --- a/.github/workflows/publish_mcp.yml +++ b/.github/workflows/publish_mcp.yml @@ -3,21 +3,22 @@ name: Publish MCP Registry on: workflow_dispatch: workflow_run: - workflows: ["Publish PyPI"] # exact name of PyPI workflow - types: - - completed + workflows: ["Publish PyPI"] + types: [completed] + branches: [main] concurrency: group: publish-${{ github.ref }} cancel-in-progress: true jobs: - registry: + on-success: name: Publish to MCP Registry runs-on: ubuntu-latest + if: ${{ github.event.workflow_run.conclusion == 'success' }} permissions: contents: read - id-token: write # REQUIRED for MCP Registry GitHub OIDC login + id-token: write steps: - name: Checkout uses: actions/checkout@v4 @@ -27,33 +28,21 @@ jobs: set -e OS=$(uname -s | tr '[:upper:]' '[:lower:]') ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') - echo "Get the latest release version" LATEST_VERSION=$(curl -s https://api.github.com/repos/modelcontextprotocol/registry/releases/latest | jq -r '.tag_name') - echo "Installing MCP Publisher version: $LATEST_VERSION" - curl -L "https://github.com/modelcontextprotocol/registry/releases/download/${LATEST_VERSION}/mcp-publisher_${LATEST_VERSION#v}_${OS}_${ARCH}.tar.gz" \ - | tar xz mcp-publisher + curl -L "https://github.com/modelcontextprotocol/registry/releases/download/${LATEST_VERSION}/mcp-publisher_${LATEST_VERSION#v}_${OS}_${ARCH}.tar.gz" | tar xz mcp-publisher - - name: Login to MCP Registry (OIDC) - run: | - echo "Login to MCP Registry (OIDC)" - ./mcp-publisher login github-oidc + - name: Login to MCP Registry + run: ./mcp-publisher login github-oidc - - name: Publish server.json to MCP Registry + - name: Publish to MCP Registry run: | - echo "Publish server.json to MCP Registry" - # Try to publish, with fallback for duplicate version - if ./mcp-publisher publish; then - echo "Successfully published to MCP Registry" - else - PUBLISH_EXIT_CODE=$? - echo "Publish failed with exit code: $PUBLISH_EXIT_CODE" - - # Check if it's a duplicate version error - if [ $PUBLISH_EXIT_CODE -ne 0 ]; then - echo "Checking if version already exists in registry..." - - # Get current version from server.json - CURRENT_VERSION=$(jq -r '.version' server.json) - echo "Current version: $CURRENT_VERSION" - fi - fi + echo "PyPI workflow succeeded - Publishing to MCP Registry" + ./mcp-publisher publish + + on-failure: + name: Handle PyPI Failure + runs-on: ubuntu-latest + if: ${{ github.event.workflow_run.conclusion == 'failure' }} + steps: + - name: Log PyPI Failure + run: echo "PyPI workflow failed - MCP Registry publication skipped" diff --git a/pyproject.toml b/pyproject.toml index 8d05588..b6f300b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "ros-mcp" -version = "2.1.5" +version = "2.1.6" description = "Connect AI Language Models with Robots on ROS using MCP" readme = "README.md" requires-python = ">=3.10" diff --git a/server.json b/server.json index 4f0d28f..66370d2 100644 --- a/server.json +++ b/server.json @@ -6,13 +6,13 @@ "url": "https://github.com/robotmcp/ros-mcp-server", "source": "github" }, - "version": "2.1.5", + "version": "2.1.6", "packages": [ { "registryType": "pypi", "registryBaseUrl": "https://pypi.org", "identifier": "ros-mcp", - "version": "2.1.5", + "version": "2.1.6", "transport": { "type": "stdio", "command": "ros-mcp", diff --git a/uv.lock b/uv.lock index c222de7..a110c2a 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 2 +revision = 3 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.12' and sys_platform == 'darwin'", @@ -1213,7 +1213,7 @@ wheels = [ [[package]] name = "ros-mcp" -version = "2.1.4" +version = "2.1.6" source = { editable = "." } dependencies = [ { name = "fastmcp" }, From ac75c8c884c044f143c8e0f002662f22ad852444 Mon Sep 17 00:00:00 2001 From: Stefano Dalla Gasperina Date: Thu, 9 Oct 2025 00:07:39 -0500 Subject: [PATCH 22/24] Hotfix/workflows (#167) * Manual fixes to workflows * Changes to publish.yml * Removed branch restriction on publish mcp * Removed branch restriction on download metrics --------- Co-authored-by: Rohit John Varghese --- .github/workflows/clone-metrics.yml | 3 +- .github/workflows/download-metrics.yml | 3 +- .github/workflows/publish.yml | 89 ++++++++++++++++++++++++++ .github/workflows/publish_mcp.yml | 1 - .github/workflows/view-metrics.yml | 7 +- 5 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/clone-metrics.yml b/.github/workflows/clone-metrics.yml index d1a081a..6e82bac 100644 --- a/.github/workflows/clone-metrics.yml +++ b/.github/workflows/clone-metrics.yml @@ -1,9 +1,10 @@ name: Track Clone Metrics on: + workflow_dispatch: schedule: - cron: '0 8 * * *' # Run every day at 8am - workflow_dispatch: + jobs: clone-stats: diff --git a/.github/workflows/download-metrics.yml b/.github/workflows/download-metrics.yml index e8ccdac..ee473c3 100644 --- a/.github/workflows/download-metrics.yml +++ b/.github/workflows/download-metrics.yml @@ -4,8 +4,7 @@ on: workflow_dispatch: workflow_run: workflows: ["Track View Metrics"] # exact name of PyPI workflow - types: - - completed + types: [completed] jobs: download-stats: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..8eee8ee --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,89 @@ +name: Publish (PyPI + MCP Registry) + +on: + workflow_dispatch: + +concurrency: + group: publish-${{ github.ref }} + cancel-in-progress: true + +jobs: + pypi: + name: Publish to PyPI + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # REQUIRED for PyPI Trusted Publishing (OIDC) + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install uv + run: pipx install uv + + # --- Optional checks (keep for now; can be moved to PR CI later) --- + - name: Sync deps + run: uv sync + + - name: Ruff lint + run: uvx ruff check . + + - name: Ruff format check + run: uvx ruff format --check . + + - name: Run tests (if present) + run: | + if [ -d tests ]; then + uv run pytest -q + else + echo "No tests/ directory; skipping." + fi + + # --- Build artifacts for PyPI --- + - name: Build sdist & wheel + run: uv build + + # --- Publish using Trusted Publishing (no tokens) --- + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist + # For a dress rehearsal, you can set: + # repository-url: https://test.pypi.org/legacy/ + + registry: + name: Publish to MCP Registry + runs-on: ubuntu-latest + needs: pypi + permissions: + contents: read + id-token: write # REQUIRED for MCP Registry GitHub OIDC login + steps: + - name: Checkout + uses: actions/checkout@v4 + + # Small delay to allow PyPI metadata to propagate + - name: Wait briefly + run: sleep 20 + + - name: Install MCP Publisher + run: | + set -e + OS=$(uname -s | tr '[:upper:]' '[:lower:]') + ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') + echo "Get the latest release version" + LATEST_VERSION=$(curl -s https://api.github.com/repos/modelcontextprotocol/registry/releases/latest | jq -r '.tag_name') + echo "Installing MCP Publisher version: $LATEST_VERSION" + curl -L "https://github.com/modelcontextprotocol/registry/releases/download/${LATEST_VERSION}/mcp-publisher_${LATEST_VERSION#v}_${OS}_${ARCH}.tar.gz" \ + | tar xz mcp-publisher + + - name: Login to MCP Registry (OIDC) + run: ./mcp-publisher login github-oidc + + - name: Publish server.json to MCP Registry + run: ./mcp-publisher publish diff --git a/.github/workflows/publish_mcp.yml b/.github/workflows/publish_mcp.yml index 86afc72..0a398e3 100644 --- a/.github/workflows/publish_mcp.yml +++ b/.github/workflows/publish_mcp.yml @@ -5,7 +5,6 @@ on: workflow_run: workflows: ["Publish PyPI"] types: [completed] - branches: [main] concurrency: group: publish-${{ github.ref }} diff --git a/.github/workflows/view-metrics.yml b/.github/workflows/view-metrics.yml index 6759b1b..c0905ec 100644 --- a/.github/workflows/view-metrics.yml +++ b/.github/workflows/view-metrics.yml @@ -1,9 +1,10 @@ -name: Track View Metrics via GitHub App +name: Track View Metrics on: - schedule: - - cron: '30 * * * *' # Run every hour at minute 30 workflow_dispatch: + workflow_run: + workflows: ["Track Clone Metrics"] # exact name of PyPI workflow + types: [completed] jobs: view-stats: From 81ac1a40d3a30d414d83be1a7250b1a79d298133 Mon Sep 17 00:00:00 2001 From: Rohit John Varghese Date: Sat, 25 Oct 2025 22:56:16 -0500 Subject: [PATCH 23/24] Bump version to v2.1.7 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f8c9ca5..50eb259 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "ros-mcp" -version = "2.1.4" +version = "2.1.7" description = "Connect AI Language Models with Robots on ROS using MCP" readme = "README.md" requires-python = ">=3.10" From 537aff04b862483003183f8b9328fca509070a75 Mon Sep 17 00:00:00 2001 From: Rohit John Varghese Date: Sat, 25 Oct 2025 22:57:02 -0500 Subject: [PATCH 24/24] Update version to v2.1.7 in server.json and uv.lock --- server.json | 4 ++-- uv.lock | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server.json b/server.json index 59f0b47..0b5f9d6 100644 --- a/server.json +++ b/server.json @@ -2,12 +2,12 @@ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json", "name": "io.github.robotmcp/ros-mcp-server", "description": "Connect AI models like Claude & ChatGPT with ROS robots using MCP", - "version": "2.1.4", + "version": "2.1.7", "packages": [ { "registry_type": "pypi", "identifier": "ros-mcp", - "version": "2.1.4" + "version": "2.1.7" } ], "transport": { diff --git a/uv.lock b/uv.lock index c222de7..df56afe 100644 --- a/uv.lock +++ b/uv.lock @@ -1213,7 +1213,7 @@ wheels = [ [[package]] name = "ros-mcp" -version = "2.1.4" +version = "2.1.7" source = { editable = "." } dependencies = [ { name = "fastmcp" },