From 05368d9b1a029d6704e7834c3297e0fb7ba72940 Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Tue, 31 Mar 2026 15:46:34 -0700 Subject: [PATCH 1/2] [Infra] Add cosign verification section to release notes Prepend Docker image signature verification instructions to auto-generated release notes, using the cosign public key committed to the repo. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/create-release.yml | 34 +++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 377c6342c0d..2572408ac62 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -44,8 +44,32 @@ jobs: script: | const tag = process.env.TAG; const commitHash = process.env.COMMIT_HASH; + + const cosignSection = [ + `## Verify Docker Image Signature`, + ``, + `All LiteLLM Docker images are signed with [cosign](https://docs.sigstore.dev/cosign/overview/). To verify the integrity of an image before deploying:`, + ``, + '```bash', + `cosign verify \\`, + ` --key https://raw.githubusercontent.com/BerriAI/litellm/main/cosign.pub \\`, + ` ghcr.io/berriai/litellm:${tag}`, + '```', + ``, + `Expected output:`, + ``, + '```', + `The following checks were performed on each of these signatures:`, + ` - The cosign claims were validated`, + ` - The signatures were verified against the specified public key`, + '```', + ``, + `---`, + ``, + ].join('\n'); + try { - await github.rest.repos.createRelease({ + const response = await github.rest.repos.createRelease({ draft: false, generate_release_notes: true, target_commitish: commitHash, @@ -55,6 +79,14 @@ jobs: repo: context.repo.repo, tag_name: tag, }); + + const updatedBody = cosignSection + response.data.body; + await github.rest.repos.updateRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + release_id: response.data.id, + body: updatedBody, + }); } catch (error) { core.setFailed(error.message); } From 8071691ffcf24782a266db9bbcafbb3ce1927142 Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Tue, 31 Mar 2026 16:26:20 -0700 Subject: [PATCH 2/2] [Fix] Address review feedback on release workflow - Use nullish coalescing for potentially null response body - Create release as draft first, then publish atomically to avoid partial-release state - Pin cosign.pub URL to release tag instead of main branch Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/create-release.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 2572408ac62..2ae01823a96 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -52,7 +52,7 @@ jobs: ``, '```bash', `cosign verify \\`, - ` --key https://raw.githubusercontent.com/BerriAI/litellm/main/cosign.pub \\`, + ` --key https://raw.githubusercontent.com/BerriAI/litellm/${tag}/cosign.pub \\`, ` ghcr.io/berriai/litellm:${tag}`, '```', ``, @@ -70,7 +70,7 @@ jobs: try { const response = await github.rest.repos.createRelease({ - draft: false, + draft: true, generate_release_notes: true, target_commitish: commitHash, name: tag, @@ -80,12 +80,13 @@ jobs: tag_name: tag, }); - const updatedBody = cosignSection + response.data.body; + const updatedBody = cosignSection + (response.data.body ?? ''); await github.rest.repos.updateRelease({ owner: context.repo.owner, repo: context.repo.repo, release_id: response.data.id, body: updatedBody, + draft: false, }); } catch (error) { core.setFailed(error.message);