From fccb482c19a944f5048d4dbac42ff387fa91a7dc Mon Sep 17 00:00:00 2001 From: Matthew Helmke Date: Thu, 30 Apr 2026 07:31:08 -0500 Subject: [PATCH] Drop GitHub Releases from AI docs pipeline; redirect users to container/MCP Immutable releases (org ruleset) made the cleanup step fail on every run, and the high dispatch frequency was accumulating releases without bound. GCS and the container are already the live distribution layer, so GitHub Releases were a redundant channel causing errors with no path to fix. - compile-ai-docs-from-gcs.yaml: remove Create Release and Clean Up Old Releases steps; move Sign step before GCS upload; add .bundle files to GCS upload; drop contents:write permission; remove release-related egress endpoints; remove dead create_release dispatch input - developer-resources.md: remove GitHub Release table row; update intro and standalone script link to point to MCP docs - mcp-server-ai-docs.md: replace release curl commands with raw.githubusercontent.com for scripts + container extract for docs - ai-docs-security.md: replace direct-download verification block with container image verification Co-Authored-By: Claude Sonnet 4.6 --- .../workflows/compile-ai-docs-from-gcs.yaml | 94 ++++++------------- content/ai-docs-security.md | 18 +--- content/developer-resources.md | 12 +-- content/mcp-server-ai-docs.md | 14 +-- 4 files changed, 44 insertions(+), 94 deletions(-) diff --git a/.github/workflows/compile-ai-docs-from-gcs.yaml b/.github/workflows/compile-ai-docs-from-gcs.yaml index 268bffee38..b4a0535bd4 100644 --- a/.github/workflows/compile-ai-docs-from-gcs.yaml +++ b/.github/workflows/compile-ai-docs-from-gcs.yaml @@ -8,22 +8,13 @@ on: types: [ai-docs-source-updated] workflow_dispatch: - inputs: - create_release: - description: 'Create a GitHub release with the bundle' - required: false - default: 'false' - type: choice - options: - - 'true' - - 'false' concurrency: group: compile-ai-docs-${{ github.ref }} cancel-in-progress: false permissions: - contents: write # For creating/updating releases + contents: read id-token: write # For GCP workload identity federation packages: write # For pushing to GHCR # TODO: Split into separate compile (read-only) and publish (write) jobs @@ -56,7 +47,6 @@ jobs: objects.githubusercontent.com:443 pypi.org:443 raw.githubusercontent.com:443 - release-assets.githubusercontent.com:443 rekor.sigstore.dev:443 run.googleapis.com:443 us-central1-run.googleapis.com:443 @@ -64,7 +54,6 @@ jobs: storage.googleapis.com:443 timestamp.sigstore.dev:443 tuf-repo-cdn.sigstore.dev:443 - uploads.github.com:443 - name: Checkout edu repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -295,23 +284,45 @@ jobs: --role "roles/run.invoker" \ --project "$PROJECT_ID" || true + - name: Sign bundle files + if: github.ref == 'refs/heads/main' + run: | + cd static/downloads + cosign sign-blob chainguard-ai-docs.tar.gz \ + --yes \ + --bundle=chainguard-ai-docs.tar.gz.bundle + cosign sign-blob chainguard-ai-docs.md \ + --yes \ + --bundle=chainguard-ai-docs.md.bundle + echo "Bundle files signed" + - name: Upload bundle back to GCS for distribution env: COMMIT_SHA: ${{ github.sha }} EVENT_NAME: ${{ github.event_name }} run: | echo "Uploading compiled bundle to GCS..." - + # Upload the compiled bundle for easy distribution gcloud storage cp static/downloads/chainguard-ai-docs.tar.gz \ gs://academy-all-docs/compiled/chainguard-ai-docs.tar.gz \ --project=chainguard-academy - + # Upload checksums gcloud storage cp static/downloads/checksums.txt \ gs://academy-all-docs/compiled/checksums.txt \ --project=chainguard-academy - + + # Upload cosign bundle files for artifact verification (only present on main branch builds) + if [ -f "static/downloads/chainguard-ai-docs.tar.gz.bundle" ]; then + gcloud storage cp static/downloads/chainguard-ai-docs.tar.gz.bundle \ + gs://academy-all-docs/compiled/chainguard-ai-docs.tar.gz.bundle \ + --project=chainguard-academy + gcloud storage cp static/downloads/chainguard-ai-docs.md.bundle \ + gs://academy-all-docs/compiled/chainguard-ai-docs.md.bundle \ + --project=chainguard-academy + fi + # Create and upload compilation metadata python3 -c " import json, datetime, os @@ -324,58 +335,9 @@ jobs: with open('/tmp/compilation-metadata.json', 'w') as f: json.dump(meta, f, indent=2) " - + gcloud storage cp /tmp/compilation-metadata.json \ gs://academy-all-docs/compiled/metadata.json \ --project=chainguard-academy - - echo "✓ Bundle uploaded to GCS" - - - name: Sign bundle files - if: github.ref == 'refs/heads/main' - run: | - cd static/downloads - cosign sign-blob chainguard-ai-docs.tar.gz \ - --yes \ - --bundle=chainguard-ai-docs.tar.gz.bundle - cosign sign-blob chainguard-ai-docs.md \ - --yes \ - --bundle=chainguard-ai-docs.md.bundle - echo "Bundle files signed" - - name: Create GitHub Release - if: github.ref == 'refs/heads/main' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - TAG="ai-docs-$(date -u +%Y%m%d-%H%M%S)" - - gh release create "$TAG" \ - --title "AI Documentation Bundle $TAG" \ - --notes "Chainguard AI documentation bundle for use with AI coding assistants." \ - --latest \ - static/downloads/chainguard-ai-docs.tar.gz \ - static/downloads/chainguard-ai-docs.tar.gz.bundle \ - static/downloads/chainguard-ai-docs.md \ - static/downloads/chainguard-ai-docs.md.bundle \ - static/downloads/chainguard-ai-docs.zip \ - static/downloads/image-catalog.json \ - static/downloads/checksums.txt \ - scripts/mcp-server.py \ - scripts/mcp-requirements.txt - - echo "Release $TAG created" - - - name: Clean up old releases - if: github.ref == 'refs/heads/main' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # Keep only the 10 most recent dated releases; delete older ones - gh release list --limit 100 --json tagName,createdAt \ - | jq -r '[.[] | select(.tagName | test("^ai-docs-[0-9]{8}-[0-9]{6}$"))] | sort_by(.createdAt) | reverse | .[10:] | .[].tagName' \ - | while read -r tag; do - echo "Deleting old release: $tag" - gh release delete "$tag" --yes --cleanup-tag - done - echo "Release cleanup complete" \ No newline at end of file + echo "✓ Bundle uploaded to GCS" \ No newline at end of file diff --git a/content/ai-docs-security.md b/content/ai-docs-security.md index 4d7a27f384..658efc0535 100644 --- a/content/ai-docs-security.md +++ b/content/ai-docs-security.md @@ -86,22 +86,14 @@ Example patterns we redact: ## Verification Guide -### Direct Download Verification +### Container Image Verification -```bash -# 1. Download files -curl -LO https://github.com/chainguard-dev/edu/releases/latest/download/chainguard-ai-docs.tar.gz -curl -LO https://github.com/chainguard-dev/edu/releases/latest/download/chainguard-ai-docs.tar.gz.bundle +Verify the container image signature before pulling documentation: -# 2. Verify signature (using cosign v3 bundle format) -cosign verify-blob \ - --bundle chainguard-ai-docs.tar.gz.bundle \ +```bash +cosign verify ghcr.io/chainguard-dev/ai-docs:latest \ --certificate-identity-regexp ".*github.com/chainguard-dev/edu.*" \ - --certificate-oidc-issuer https://token.actions.githubusercontent.com \ - chainguard-ai-docs.tar.gz - -# 3. Extract contents -tar -xzf chainguard-ai-docs.tar.gz + --certificate-oidc-issuer https://token.actions.githubusercontent.com ``` ## Build Frequency diff --git a/content/developer-resources.md b/content/developer-resources.md index 6c48bbeb97..7dded6fdd1 100644 --- a/content/developer-resources.md +++ b/content/developer-resources.md @@ -13,7 +13,7 @@ toc: false ## AI-Ready Documentation Bundle -This page provides compiled Chainguard documentation optimized for use with AI coding assistants like Claude, ChatGPT, GitHub Copilot, and others. Choose between our cryptographically signed direct downloads or our secure container distribution. +This page provides compiled Chainguard documentation optimized for use with AI coding assistants like Claude, ChatGPT, GitHub Copilot, and others. Access it through our secure container image or as a standalone Python MCP server. ### What's Included @@ -40,12 +40,6 @@ Choose your preferred distribution method: For enhanced security and verification, we recommend using the Chainguard container image. It includes built-in verification, runs as non-root, and is built on our secure wolfi-base image. -### GitHub Release - -| Format | Description | Verification | -|--------|-------------|-------------| -| [Latest Release](https://github.com/chainguard-dev/edu/releases/latest) | Cryptographically signed documentation bundle | Includes Cosign signatures and certificates | - ### Container Distribution Pull the secure, Chainguard-based container with embedded documentation: @@ -119,7 +113,7 @@ Add to your `claude_desktop_config.json`: - Searchable and queryable documentation - Perfect for automated workflows - Works with Claude Desktop, Cursor, and other MCP-compatible tools -- Also available as a [standalone Python script](https://github.com/chainguard-dev/edu/releases/latest) (no Docker required) +- Also available as a [standalone Python script](/mcp-server-ai-docs/#standalone-installation-without-docker) (no Docker required) [**Full MCP Server Documentation →**](/mcp-server-ai-docs/) @@ -137,7 +131,7 @@ docker run --rm -v $(pwd):/output ghcr.io/chainguard-dev/ai-docs:latest extract

Available Security Features

    -
  • Signed releases with Sigstore/Cosign
  • +
  • Container image signed with Sigstore/Cosign
  • Container distribution via GitHub Container Registry
  • Automated updates via GitHub Actions
  • Security scanning with gitleaks
  • diff --git a/content/mcp-server-ai-docs.md b/content/mcp-server-ai-docs.md index 3ea96b983c..2ab6988998 100644 --- a/content/mcp-server-ai-docs.md +++ b/content/mcp-server-ai-docs.md @@ -242,14 +242,16 @@ latest, latest-dev, 3.13, 3.13-dev, ... ## Standalone Installation (without Docker) -The MCP server is also available as a standalone Python script from the [latest GitHub release](https://github.com/chainguard-dev/edu/releases/latest): +The MCP server script and its dependencies are available directly from the repository. The documentation files are distributed via the container image. ```bash -# Download the MCP server, requirements, docs, and catalog -curl -LO https://github.com/chainguard-dev/edu/releases/latest/download/mcp-server.py -curl -LO https://github.com/chainguard-dev/edu/releases/latest/download/mcp-requirements.txt -curl -LO https://github.com/chainguard-dev/edu/releases/latest/download/chainguard-ai-docs.md -curl -LO https://github.com/chainguard-dev/edu/releases/latest/download/image-catalog.json +# Download the MCP server script and requirements +curl -LO https://raw.githubusercontent.com/chainguard-dev/edu/main/scripts/mcp-server.py +curl -LO https://raw.githubusercontent.com/chainguard-dev/edu/main/scripts/mcp-requirements.txt + +# Extract the documentation bundle from the container image +docker run --rm -v $(pwd):/output ghcr.io/chainguard-dev/ai-docs:latest extract /output +# Writes chainguard-ai-docs.md and image-catalog.json to the current directory # Install dependencies pip install -r mcp-requirements.txt