From 601fbe7756e078aa309a84eca88e96e4f874d03d Mon Sep 17 00:00:00 2001 From: ezl-keygraph Date: Wed, 18 Mar 2026 22:15:59 +0530 Subject: [PATCH 1/3] feat: add beta release and rollback workflows with cosign signing (#247) --- .github/workflows/release-beta.yml | 197 ++++++++++++++++++++++++++++ .github/workflows/rollback-beta.yml | 71 ++++++++++ 2 files changed, 268 insertions(+) create mode 100644 .github/workflows/release-beta.yml create mode 100644 .github/workflows/rollback-beta.yml diff --git a/.github/workflows/release-beta.yml b/.github/workflows/release-beta.yml new file mode 100644 index 0000000..6a27694 --- /dev/null +++ b/.github/workflows/release-beta.yml @@ -0,0 +1,197 @@ +name: Release (Beta) + +on: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: release-beta + cancel-in-progress: false + +jobs: + preflight: + name: Preflight + runs-on: ubuntu-latest + outputs: + version: ${{ steps.version.outputs.version }} + + steps: + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: 24 + registry-url: https://registry.npmjs.org + + - name: Compute next beta version + id: version + shell: bash + run: | + set -euo pipefail + + LATEST=$(npm view "@keygraph/shannon" dist-tags.beta 2>/dev/null || echo "") + + if [[ -z "$LATEST" ]]; then + echo "version=1.0.0-beta.1" >> "$GITHUB_OUTPUT" + else + # Extract N from 1.0.0-beta.N and increment + N=$(echo "$LATEST" | grep -oE 'beta\.([0-9]+)' | grep -oE '[0-9]+') + NEXT=$((N + 1)) + echo "version=1.0.0-beta.$NEXT" >> "$GITHUB_OUTPUT" + fi + + - name: Print version + run: 'echo "Next beta version: ${{ steps.version.outputs.version }}"' + + build-docker: + name: Build Docker (${{ matrix.platform }}) + needs: preflight + permissions: + contents: read + strategy: + fail-fast: true + matrix: + include: + - platform: linux/amd64 + runner: ubuntu-latest + - platform: linux/arm64 + runner: ubuntu-24.04-arm + runs-on: ${{ matrix.runner }} + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Log in to Docker Hub + uses: docker/login-action@v4 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push by digest + id: build + uses: docker/build-push-action@v7 + with: + context: . + platforms: ${{ matrix.platform }} + provenance: mode=max + sbom: true + outputs: type=image,name=keygraph/shannon,push-by-digest=true,name-canonical=true,push=true + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v6 + with: + name: digests-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge-docker: + name: Push Docker manifests + needs: [preflight, build-docker] + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + outputs: + digest: ${{ steps.inspect.outputs.digest }} + + steps: + - name: Download digests + uses: actions/download-artifact@v6 + with: + path: /tmp/digests + pattern: digests-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Log in to Docker Hub + uses: docker/login-action@v4 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create \ + --tag "keygraph/shannon:${{ needs.preflight.outputs.version }}" \ + $(printf 'keygraph/shannon@sha256:%s ' *) + + - name: Inspect image + id: inspect + run: | + docker buildx imagetools inspect "keygraph/shannon:${{ needs.preflight.outputs.version }}" + DIGEST="sha256:$(docker buildx imagetools inspect --raw "keygraph/shannon:${{ needs.preflight.outputs.version }}" | sha256sum | cut -d' ' -f1)" + echo "digest=$DIGEST" >> "$GITHUB_OUTPUT" + + - name: Install cosign + uses: sigstore/cosign-installer@v4.1.0 + + - name: Sign Docker image + run: cosign sign --yes "keygraph/shannon@${{ steps.inspect.outputs.digest }}" + + - name: Verify Docker image signature + run: | + sleep 10 + cosign verify \ + --certificate-oidc-issuer https://token.actions.githubusercontent.com \ + --certificate-identity https://github.com/${{ github.repository }}/.github/workflows/release-beta.yml@${{ github.ref }} \ + "keygraph/shannon@${{ steps.inspect.outputs.digest }}" + + publish-npm: + name: Publish npm (beta) + needs: [preflight, merge-docker] + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + + - name: Configure npm registry + uses: actions/setup-node@v6 + with: + node-version: 24 + registry-url: https://registry.npmjs.org + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Set CLI package version + run: cd apps/cli && npm version "${{ needs.preflight.outputs.version }}" --no-git-tag-version --allow-same-version + + - name: Sync lockfile with bumped version + run: pnpm install --lockfile-only + + - name: Build CLI + run: pnpm --filter @keygraph/shannon run build + + - name: Publish npm package + working-directory: apps/cli + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: | + if npm view "@keygraph/shannon@${{ needs.preflight.outputs.version }}" version 2>/dev/null; then + echo "Version already published, skipping" + else + pnpm publish --access public --no-git-checks --tag beta + fi diff --git a/.github/workflows/rollback-beta.yml b/.github/workflows/rollback-beta.yml new file mode 100644 index 0000000..0014893 --- /dev/null +++ b/.github/workflows/rollback-beta.yml @@ -0,0 +1,71 @@ +name: Rollback (Beta) + +on: + workflow_dispatch: + inputs: + version: + description: "Beta version to roll back to (example: 1.0.0-beta.2)" + required: true + type: string + +permissions: + contents: read + +concurrency: + group: rollback-beta-${{ github.event.inputs.version }} + cancel-in-progress: false + +jobs: + rollback: + name: Roll back npm beta dist-tag + runs-on: ubuntu-latest + steps: + - name: Validate target version + id: target + shell: bash + env: + RAW_VERSION: ${{ inputs.version }} + run: | + set -euo pipefail + + VERSION="${RAW_VERSION#v}" + + if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+-beta\.[0-9]+$ ]]; then + echo "Version must be in format X.Y.Z-beta.N (e.g. 1.0.0-beta.2)" + exit 1 + fi + + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: 24 + registry-url: https://registry.npmjs.org + + - name: Verify npm package version exists + run: npm view "@keygraph/shannon@${{ steps.target.outputs.version }}" version + + - name: Show current npm dist-tags + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: npm dist-tag ls @keygraph/shannon + + - name: Move npm beta tag + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: npm dist-tag add "@keygraph/shannon@${{ steps.target.outputs.version }}" beta + + - name: Show final npm dist-tags + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: npm dist-tag ls @keygraph/shannon + + - name: Write summary + run: | + { + echo "## Rollback beta" + echo "" + echo "- Target version: \`${{ steps.target.outputs.version }}\`" + echo "- npm package: \`@keygraph/shannon\` (beta tag moved)" + } >> "$GITHUB_STEP_SUMMARY" From 3324c01b838908b9d55802f7d25acade95e9f4f2 Mon Sep 17 00:00:00 2001 From: ezl-keygraph Date: Thu, 19 Mar 2026 04:37:52 +0530 Subject: [PATCH 2/3] docs: update announcement banner to npx availability (#248) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 271d5ce..a843d5c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ >[!NOTE] -> **[📢 New: Claude models on AWS Bedrock and Google Vertex AI now supported. →](https://github.com/KeygraphHQ/shannon/discussions/categories/announcements)** +> **[📢 New: Shannon is now available via `npx @keygraph/shannon`. →](https://github.com/KeygraphHQ/shannon/discussions/categories/announcements)**
From 0d172f5e32ef39e8740798b8c1f85b75f0c16c48 Mon Sep 17 00:00:00 2001 From: ezl-keygraph Date: Thu, 19 Mar 2026 04:44:32 +0530 Subject: [PATCH 3/3] docs: update announcement banner URL to npx discussion (#250) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a843d5c..4e4adc7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ >[!NOTE] -> **[📢 New: Shannon is now available via `npx @keygraph/shannon`. →](https://github.com/KeygraphHQ/shannon/discussions/categories/announcements)** +> **[📢 New: Shannon is now available via `npx @keygraph/shannon`. →](https://github.com/KeygraphHQ/shannon/discussions/249)**