Repository navigation
Validate Release Secrets #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Validate Release Secrets | |
| on: | |
| workflow_dispatch: | |
| jobs: | |
| validate-npm: | |
| name: "npm: trusted publishing" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check package linkage | |
| run: | | |
| FAILED=false | |
| for pkg in @debugmcp/shared @debugmcp/adapter-mock @debugmcp/adapter-python @debugmcp/mcp-debugger; do | |
| REPO=$(npm view "$pkg" repository.url 2>/dev/null || echo "") | |
| if echo "$REPO" | grep -q "debugmcp/mcp-debugger"; then | |
| echo "✅ $pkg linked to debugmcp/mcp-debugger" | |
| elif [[ -z "$REPO" ]]; then | |
| echo "⚠️ $pkg not found on npm (OK if first publish)" | |
| else | |
| echo "❌ $pkg repository: $REPO — expected debugmcp/mcp-debugger" | |
| FAILED=true | |
| fi | |
| done | |
| if [[ "$FAILED" == "true" ]]; then exit 1; fi | |
| validate-docker: | |
| name: "Docker Hub: credentials" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Test login | |
| env: | |
| DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} | |
| DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} | |
| run: | | |
| if echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin 2>&1; then | |
| echo "✅ Docker Hub credentials are valid" | |
| docker logout > /dev/null 2>&1 | |
| else | |
| echo "❌ Docker Hub credentials are invalid" | |
| echo " Fix: update DOCKER_USERNAME/DOCKER_PASSWORD secrets" | |
| exit 1 | |
| fi | |
| validate-pypi: | |
| name: "PyPI: token" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Test token | |
| env: | |
| PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} | |
| run: | | |
| # Use the PyPI JSON API with token auth to check validity | |
| # Requesting our own project metadata — 200 = good auth, 401/403 = bad token | |
| HTTP_CODE=$(curl -s -o /tmp/pypi_response -w "%{http_code}" \ | |
| -H "Authorization: token $PYPI_TOKEN" \ | |
| "https://pypi.org/pypi/debug-mcp-server-launcher/json" 2>/dev/null) || true | |
| case "$HTTP_CODE" in | |
| 200) | |
| echo "✅ PYPI_TOKEN is valid" | |
| ;; | |
| 401|403) | |
| echo "❌ PYPI_TOKEN is expired or revoked (HTTP $HTTP_CODE)" | |
| echo " Fix: regenerate at pypi.org → Account Settings → API tokens" | |
| exit 1 | |
| ;; | |
| 404) | |
| echo "⚠️ Package not found on PyPI (HTTP 404) — token may still be valid" | |
| echo " (404 can mean the package hasn't been published yet)" | |
| ;; | |
| *) | |
| # Fallback: try twine with a real sdist from our project | |
| pip install twine build > /dev/null 2>&1 | |
| mkdir -p /tmp/pypi-test && cd /tmp/pypi-test | |
| echo '[project]' > pyproject.toml | |
| echo 'name = "_validate-token-test"' >> pyproject.toml | |
| echo 'version = "0.0.0"' >> pyproject.toml | |
| python -m build --sdist > /dev/null 2>&1 | |
| TWINE_OUT=$(python -m twine upload --skip-existing \ | |
| --repository-url https://upload.pypi.org/legacy/ \ | |
| -u __token__ -p "$PYPI_TOKEN" \ | |
| dist/*.tar.gz 2>&1) || true | |
| if echo "$TWINE_OUT" | grep -qiE "401|403|unauthorized|forbidden"; then | |
| echo "❌ PYPI_TOKEN is expired or revoked" | |
| echo " $TWINE_OUT" | |
| exit 1 | |
| else | |
| echo "✅ PYPI_TOKEN appears valid" | |
| echo " (twine output: $TWINE_OUT)" | |
| fi | |
| ;; | |
| esac |