Skip to content

Marketplace Deploy (JeremyDev87/codingbuddy) #42

Marketplace Deploy (JeremyDev87/codingbuddy)

Marketplace Deploy (JeremyDev87/codingbuddy) #42

Workflow file for this run

name: marketplace-deploy
on:
push:
branches:
- master
paths:
- '.claude-plugin/**'
- 'packages/claude-code-plugin/.claude-plugin/**'
- '.github/workflows/marketplace.yml'
- '.github/scripts/marketplace-utils.sh'
- '.github/templates/marketplace-index.html'
release:
types: [published]
workflow_dispatch:
# Workflow-level condition for defense-in-depth
# Prevents execution on forked repositories
run-name: Marketplace Deploy (${{ github.repository }})
permissions:
contents: read
pages: write
# Required for GitHub's OIDC-based Pages authentication
id-token: write
concurrency:
group: 'pages'
cancel-in-progress: false
# Shared environment variables to avoid hardcoded paths (DRY)
# Note: Repository name 'JeremyDev87/codingbuddy' is hardcoded in job conditions
# because GitHub Actions env vars are not available in job-level 'if' expressions
env:
MARKETPLACE_JSON: .claude-plugin/marketplace.json
SITE_DIR: _site
jobs:
validate:
# Primary repository restriction - prevents forks from deploying
if: github.repository == 'JeremyDev87/codingbuddy'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Validate marketplace.json
run: |
set -euo pipefail
echo "Validating marketplace.json..."
# Check if file exists
if [ ! -f "$MARKETPLACE_JSON" ]; then
echo "Error: $MARKETPLACE_JSON not found"
exit 1
fi
# Validate JSON syntax
if ! jq empty "$MARKETPLACE_JSON" 2>/dev/null; then
echo "Error: Invalid JSON syntax in $MARKETPLACE_JSON"
exit 1
fi
# Validate required fields
NAME=$(jq -r '.name' "$MARKETPLACE_JSON")
if [ "$NAME" == "null" ] || [ -z "$NAME" ]; then
echo "Error: 'name' field is required"
exit 1
fi
PLUGINS=$(jq -r '.plugins' "$MARKETPLACE_JSON")
if [ "$PLUGINS" == "null" ]; then
echo "Error: 'plugins' array is required"
exit 1
fi
# Source shared utility functions
source .github/scripts/marketplace-utils.sh
# Validate each plugin
PLUGIN_COUNT=$(get_plugin_count)
echo "Found $PLUGIN_COUNT plugin(s)"
for ((i=0; i<PLUGIN_COUNT; i++)); do
if ! validate_plugin "$i"; then
exit 1
fi
PLUGIN_NAME=$(get_plugin_name "$i")
echo "✓ Plugin '$PLUGIN_NAME' validated"
done
echo ""
echo "✅ Marketplace validation passed!"
build:
# Defense-in-depth: Additional repository check
if: github.repository == 'JeremyDev87/codingbuddy'
needs: validate
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Pages
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0
with:
enablement: true
- name: Prepare marketplace directory
run: |
set -euo pipefail
mkdir -p "$SITE_DIR/.claude-plugin"
# Copy marketplace.json
cp "$MARKETPLACE_JSON" "$SITE_DIR/.claude-plugin/"
# Source shared utility functions
source .github/scripts/marketplace-utils.sh
# Copy each plugin's .claude-plugin directory
PLUGIN_COUNT=$(get_plugin_count)
for ((i=0; i<PLUGIN_COUNT; i++)); do
PLUGIN_NAME=$(get_plugin_name "$i")
PLUGIN_SOURCE=$(get_plugin_source "$i")
# Create plugin directory structure
mkdir -p "$SITE_DIR/$PLUGIN_SOURCE/.claude-plugin"
# Copy plugin files
cp -r "$PLUGIN_SOURCE/.claude-plugin/"* "$SITE_DIR/$PLUGIN_SOURCE/.claude-plugin/"
echo "✓ Copied plugin '$PLUGIN_NAME' from '$PLUGIN_SOURCE'"
done
# Copy index.html for human visitors
cp .github/templates/marketplace-index.html "$SITE_DIR/index.html"
echo ""
echo "📦 Marketplace build complete!"
echo "Contents of $SITE_DIR:"
find "$SITE_DIR" -type f
- name: Upload artifact
uses: actions/upload-pages-artifact@0ca16172ca884f0a37117fed41734f29784cc980 # main (include-hidden-files support)
with:
path: '_site'
include-hidden-files: true
deploy:
# Defense-in-depth: Additional repository check
if: github.repository == 'JeremyDev87/codingbuddy'
needs: build
runs-on: ubuntu-latest
timeout-minutes: 10
outputs:
page_url: ${{ steps.deployment.outputs.page_url }}
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5
- name: Output deployment info
env:
PAGE_URL: ${{ steps.deployment.outputs.page_url }}
run: |
set -euo pipefail
echo "🎉 Marketplace deployed!"
echo ""
echo "Landing page URL: $PAGE_URL"
echo ""
echo "To use this marketplace:"
echo " claude marketplace add JeremyDev87/codingbuddy"
echo " claude plugin install codingbuddy@jeremydev87"
verify:
# Post-deploy verification — catches silent deployment failures
if: github.repository == 'JeremyDev87/codingbuddy'
needs: deploy
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Verify deployed URLs
env:
BASE_URL: ${{ needs.deploy.outputs.page_url }}
MARKETPLACE_JSON: .claude-plugin/marketplace.json
run: |
set -euo pipefail
# Ensure BASE_URL ends with /
BASE_URL="${BASE_URL%/}/"
echo "Waiting 30s for CDN propagation..."
sleep 30
# Source shared utility functions
source .github/scripts/marketplace-utils.sh
FAILED=0
verify_url() {
local url=$1
local description=$2
local status
status=$(curl -sI -o /dev/null -w '%{http_code}' --retry 3 --retry-delay 5 "$url")
if [ "$status" != "200" ]; then
echo "::error::$description returned HTTP $status (expected 200): $url"
FAILED=1
else
echo "✅ $description accessible (HTTP $status)"
fi
}
# Verify landing page
verify_url "${BASE_URL}" "Landing page"
# Verify marketplace.json
verify_url "${BASE_URL}.claude-plugin/marketplace.json" "marketplace.json"
# Verify each plugin's plugin.json
PLUGIN_COUNT=$(get_plugin_count)
echo "Verifying $PLUGIN_COUNT plugin(s)..."
for ((i=0; i<PLUGIN_COUNT; i++)); do
PLUGIN_NAME=$(get_plugin_name "$i")
PLUGIN_SOURCE=$(get_plugin_source "$i")
# Remove leading ./ from source path
PLUGIN_PATH="${PLUGIN_SOURCE#./}"
verify_url "${BASE_URL}${PLUGIN_PATH}/.claude-plugin/plugin.json" "Plugin '$PLUGIN_NAME' plugin.json"
done
if [ "$FAILED" -ne 0 ]; then
echo ""
echo "❌ URL verification failed!"
exit 1
fi
echo ""
echo "✅ All deployed URLs verified successfully!"