Skip to content

use GET in healthcheck instead of HEAD (#1654) #1948

use GET in healthcheck instead of HEAD (#1654)

use GET in healthcheck instead of HEAD (#1654) #1948

name: Release Pipeline
# Triggers automatically on push to main when any version file changes
on:
push:
branches: ["main"]
# Prevent concurrent runs
concurrency:
group: release-pipeline
cancel-in-progress: false
jobs:
# Check if pipeline should be skipped based on first line of commit message
check-skip:
runs-on: ubuntu-latest
outputs:
should-skip: ${{ steps.check.outputs.should-skip }}
steps:
- name: Check if pipeline should be skipped
id: check
env:
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
run: |
FIRST_LINE=$(echo "$COMMIT_MESSAGE" | head -n 1)
if [[ "$FIRST_LINE" == *"--skip-pipeline"* ]]; then
echo "should-skip=true" >> $GITHUB_OUTPUT
else
echo "should-skip=false" >> $GITHUB_OUTPUT
fi
# Detect what needs to be released
detect-changes:
needs: [check-skip]
runs-on: ubuntu-latest
# Skip if first line of commit message contains --skip-pipeline
if: needs.check-skip.outputs.should-skip != 'true'
outputs:
core-needs-release: ${{ steps.detect.outputs.core-needs-release }}
framework-needs-release: ${{ steps.detect.outputs.framework-needs-release }}
plugins-need-release: ${{ steps.detect.outputs.plugins-need-release }}
bifrost-http-needs-release: ${{ steps.detect.outputs.bifrost-http-needs-release }}
docker-needs-release: ${{ steps.detect.outputs.docker-needs-release }}
changed-plugins: ${{ steps.detect.outputs.changed-plugins }}
core-version: ${{ steps.detect.outputs.core-version }}
framework-version: ${{ steps.detect.outputs.framework-version }}
transport-version: ${{ steps.detect.outputs.transport-version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Install jq
run: |
sudo apt-get update
sudo apt-get install -y jq
- name: Detect what needs release
id: detect
run: ./.github/workflows/scripts/detect-all-changes.sh "auto"
# Run all tests in parallel before any releases
test-core:
needs: [check-skip, detect-changes]
if: needs.check-skip.outputs.should-skip != 'true' && needs.detect-changes.outputs.core-needs-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.26"
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Run core tests
env:
MAXIM_API_KEY: ${{ secrets.MAXIM_API_KEY }}
MAXIM_LOGGER_ID: ${{ secrets.MAXIM_LOG_REPO_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_SESSION_TOKEN: ${{ secrets.AWS_SESSION_TOKEN }}
AWS_ARN: ${{ secrets.AWS_ARN }}
BEDROCK_API_KEY: ${{ secrets.BEDROCK_API_KEY }}
AZURE_ENDPOINT: ${{ secrets.AZURE_ENDPOINT }}
AZURE_API_KEY: ${{ secrets.AZURE_API_KEY }}
AZURE_API_VERSION: ${{ secrets.AZURE_API_VERSION }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
PARASAIL_API_KEY: ${{ secrets.PARASAIL_API_KEY }}
ELEVENLABS_API_KEY: ${{ secrets.ELEVENLABS_API_KEY }}
PERPLEXITY_API_KEY: ${{ secrets.PERPLEXITY_API_KEY }}
SGL_API_KEY: ${{ secrets.SGL_API_KEY }}
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
VERTEX_CREDENTIALS: ${{ secrets.VERTEX_CREDENTIALS }}
VERTEX_PROJECT_ID: ${{ secrets.VERTEX_PROJECT_ID }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
HUGGING_FACE_API_KEY: ${{ secrets.HUGGING_FACE_API_KEY }}
AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
AWS_BEDROCK_ROLE_ARN: ${{ secrets.AWS_BEDROCK_ROLE_ARN }}
run: ./.github/workflows/scripts/test-core.sh
test-framework:
needs: [check-skip, detect-changes]
if: needs.check-skip.outputs.should-skip != 'true' && needs.detect-changes.outputs.framework-needs-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.26"
- name: Set up Docker Compose
run: |
docker --version
if ! docker compose version >/dev/null 2>&1; then
echo "Installing Docker Compose..."
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
else
echo "Docker Compose plugin is available"
docker compose version
fi
- name: Run framework tests
env:
MAXIM_API_KEY: ${{ secrets.MAXIM_API_KEY }}
MAXIM_LOGGER_ID: ${{ secrets.MAXIM_LOG_REPO_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_SESSION_TOKEN: ${{ secrets.AWS_SESSION_TOKEN }}
AWS_ARN: ${{ secrets.AWS_ARN }}
BEDROCK_API_KEY: ${{ secrets.BEDROCK_API_KEY }}
AZURE_ENDPOINT: ${{ secrets.AZURE_ENDPOINT }}
AZURE_API_KEY: ${{ secrets.AZURE_API_KEY }}
AZURE_API_VERSION: ${{ secrets.AZURE_API_VERSION }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
PARASAIL_API_KEY: ${{ secrets.PARASAIL_API_KEY }}
ELEVENLABS_API_KEY: ${{ secrets.ELEVENLABS_API_KEY }}
PERPLEXITY_API_KEY: ${{ secrets.PERPLEXITY_API_KEY }}
SGL_API_KEY: ${{ secrets.SGL_API_KEY }}
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
VERTEX_CREDENTIALS: ${{ secrets.VERTEX_CREDENTIALS }}
VERTEX_PROJECT_ID: ${{ secrets.VERTEX_PROJECT_ID }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
HUGGING_FACE_API_KEY: ${{ secrets.HUGGING_FACE_API_KEY }}
run: ./.github/workflows/scripts/test-framework.sh
test-plugins:
needs: [check-skip, detect-changes]
if: needs.check-skip.outputs.should-skip != 'true' && needs.detect-changes.outputs.plugins-need-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Install jq
run: |
sudo apt-get update
sudo apt-get install -y jq
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.26"
- name: Set up Docker Compose
run: |
docker --version
if ! docker compose version >/dev/null 2>&1; then
echo "Installing Docker Compose..."
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
else
echo "Docker Compose plugin is available"
docker compose version
fi
- name: Run plugin tests
env:
MAXIM_API_KEY: ${{ secrets.MAXIM_API_KEY }}
MAXIM_LOGGER_ID: ${{ secrets.MAXIM_LOG_REPO_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_SESSION_TOKEN: ${{ secrets.AWS_SESSION_TOKEN }}
AWS_ARN: ${{ secrets.AWS_ARN }}
BEDROCK_API_KEY: ${{ secrets.BEDROCK_API_KEY }}
AZURE_ENDPOINT: ${{ secrets.AZURE_ENDPOINT }}
AZURE_API_KEY: ${{ secrets.AZURE_API_KEY }}
AZURE_API_VERSION: ${{ secrets.AZURE_API_VERSION }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
PARASAIL_API_KEY: ${{ secrets.PARASAIL_API_KEY }}
ELEVENLABS_API_KEY: ${{ secrets.ELEVENLABS_API_KEY }}
PERPLEXITY_API_KEY: ${{ secrets.PERPLEXITY_API_KEY }}
SGL_API_KEY: ${{ secrets.SGL_API_KEY }}
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
VERTEX_CREDENTIALS: ${{ secrets.VERTEX_CREDENTIALS }}
VERTEX_PROJECT_ID: ${{ secrets.VERTEX_PROJECT_ID }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
HUGGING_FACE_API_KEY: ${{ secrets.HUGGING_FACE_API_KEY }}
run: ./.github/workflows/scripts/test-all-plugins.sh
test-bifrost-http:
needs: [check-skip, detect-changes]
if: needs.check-skip.outputs.should-skip != 'true' && needs.detect-changes.outputs.bifrost-http-needs-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.26"
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Set up Docker Compose
run: |
docker --version
if ! docker compose version >/dev/null 2>&1; then
echo "Installing Docker Compose..."
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
else
echo "Docker Compose plugin is available"
docker compose version
fi
- name: Run bifrost-http tests
env:
MAXIM_API_KEY: ${{ secrets.MAXIM_API_KEY }}
MAXIM_LOGGER_ID: ${{ secrets.MAXIM_LOG_REPO_ID }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: ./.github/workflows/scripts/test-bifrost-http.sh
# Migration tests - validates database migrations from previous versions
test-migrations:
needs: [check-skip, detect-changes]
if: needs.check-skip.outputs.should-skip != 'true' && needs.detect-changes.outputs.bifrost-http-needs-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.26"
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Set up Docker Compose
run: |
docker --version
if ! docker compose version >/dev/null 2>&1; then
echo "Installing Docker Compose..."
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
else
echo "Docker Compose plugin is available"
docker compose version
fi
- name: Run migration tests
run: |
chmod +x ./.github/workflows/scripts/run-migration-tests.sh
./.github/workflows/scripts/run-migration-tests.sh postgres
# E2E UI tests - validates UI with Playwright
test-e2e-ui:
needs: [check-skip, detect-changes]
if: needs.check-skip.outputs.should-skip != 'true' && needs.detect-changes.outputs.bifrost-http-needs-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.26"
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Set up Docker Compose
run: |
docker --version
if ! docker compose version >/dev/null 2>&1; then
echo "Installing Docker Compose..."
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
else
echo "Docker Compose plugin is available"
docker compose version
fi
- name: Run E2E UI tests
env:
MCP_SSE_HEADERS: ${{ secrets.MCP_SSE_HEADERS }}
run: ./.github/workflows/scripts/test-e2e-ui.sh
- name: Upload Playwright artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: |
tests/e2e/test-results/
tests/e2e/playwright-report/
retention-days: 30
core-release:
needs:
[
check-skip,
detect-changes,
test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
]
if: "always() && needs.check-skip.outputs.should-skip != 'true' && needs.detect-changes.outputs.core-needs-release == 'true' && needs.test-core.result == 'success' && (needs.test-framework.result == 'success' || needs.test-framework.result == 'skipped') && (needs.test-plugins.result == 'success' || needs.test-plugins.result == 'skipped') && (needs.test-bifrost-http.result == 'success' || needs.test-bifrost-http.result == 'skipped') && (needs.test-migrations.result == 'success' || needs.test-migrations.result == 'skipped')"
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
success: ${{ steps.release.outputs.success }}
version: ${{ needs.detect-changes.outputs.core-version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
token: ${{ secrets.GH_TOKEN }}
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.26"
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Configure Git
run: |
git config user.name "GitHub Actions Bot"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Release core
id: release
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
MAXIM_API_KEY: ${{ secrets.MAXIM_API_KEY }}
MAXIM_LOGGER_ID: ${{ secrets.MAXIM_LOG_REPO_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_SESSION_TOKEN: ${{ secrets.AWS_SESSION_TOKEN }}
AWS_ARN: ${{ secrets.AWS_ARN }}
BEDROCK_API_KEY: ${{ secrets.BEDROCK_API_KEY }}
AZURE_ENDPOINT: ${{ secrets.AZURE_ENDPOINT }}
AZURE_API_KEY: ${{ secrets.AZURE_API_KEY }}
AZURE_API_VERSION: ${{ secrets.AZURE_API_VERSION }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
PARASAIL_API_KEY: ${{ secrets.PARASAIL_API_KEY }}
ELEVENLABS_API_KEY: ${{ secrets.ELEVENLABS_API_KEY }}
PERPLEXITY_API_KEY: ${{ secrets.PERPLEXITY_API_KEY }}
SGL_API_KEY: ${{ secrets.SGL_API_KEY }}
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
VERTEX_CREDENTIALS: ${{ secrets.VERTEX_CREDENTIALS }}
VERTEX_PROJECT_ID: ${{ secrets.VERTEX_PROJECT_ID }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
HUGGING_FACE_API_KEY: ${{ secrets.HUGGING_FACE_API_KEY }}
AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
AWS_BEDROCK_ROLE_ARN: ${{ secrets.AWS_BEDROCK_ROLE_ARN }}
REPLICATE_API_KEY: ${{ secrets.REPLICATE_API_KEY }}
REPLICATE_OWNER: ${{ secrets.REPLICATE_OWNER }}
run: ./.github/workflows/scripts/release-core.sh "${{ needs.detect-changes.outputs.core-version }}"
framework-release:
needs:
[
check-skip,
detect-changes,
test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
core-release,
]
if: "always() && needs.check-skip.outputs.should-skip != 'true' && needs.detect-changes.outputs.framework-needs-release == 'true' && (needs.test-core.result == 'success' || needs.test-core.result == 'skipped') && needs.test-framework.result == 'success' && (needs.test-plugins.result == 'success' || needs.test-plugins.result == 'skipped') && (needs.test-bifrost-http.result == 'success' || needs.test-bifrost-http.result == 'skipped') && (needs.test-migrations.result == 'success' || needs.test-migrations.result == 'skipped') && (needs.detect-changes.outputs.core-needs-release == 'false' || needs.core-release.result == 'success' || needs.core-release.result == 'skipped')"
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
success: ${{ steps.release.outputs.success }}
version: ${{ needs.detect-changes.outputs.framework-version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
token: ${{ secrets.GH_TOKEN }}
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.26"
- name: Configure Git
run: |
git config user.name "GitHub Actions Bot"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Set up Docker Compose
run: |
# Verify Docker is available
docker --version
# Install Docker Compose if not available as plugin
if ! docker compose version >/dev/null 2>&1; then
echo "Installing Docker Compose..."
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
else
echo "Docker Compose plugin is available"
docker compose version
fi
- name: Release framework
id: release
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
MAXIM_API_KEY: ${{ secrets.MAXIM_API_KEY }}
MAXIM_LOGGER_ID: ${{ secrets.MAXIM_LOG_REPO_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_SESSION_TOKEN: ${{ secrets.AWS_SESSION_TOKEN }}
AWS_ARN: ${{ secrets.AWS_ARN }}
BEDROCK_API_KEY: ${{ secrets.BEDROCK_API_KEY }}
AZURE_ENDPOINT: ${{ secrets.AZURE_ENDPOINT }}
AZURE_API_KEY: ${{ secrets.AZURE_API_KEY }}
AZURE_API_VERSION: ${{ secrets.AZURE_API_VERSION }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
PARASAIL_API_KEY: ${{ secrets.PARASAIL_API_KEY }}
ELEVENLABS_API_KEY: ${{ secrets.ELEVENLABS_API_KEY }}
PERPLEXITY_API_KEY: ${{ secrets.PERPLEXITY_API_KEY }}
SGL_API_KEY: ${{ secrets.SGL_API_KEY }}
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
VERTEX_CREDENTIALS: ${{ secrets.VERTEX_CREDENTIALS }}
VERTEX_PROJECT_ID: ${{ secrets.VERTEX_PROJECT_ID }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
HUGGING_FACE_API_KEY: ${{ secrets.HUGGING_FACE_API_KEY }}
REPLICATE_API_KEY: ${{ secrets.REPLICATE_API_KEY }}
REPLICATE_OWNER: ${{ secrets.REPLICATE_OWNER }}
run: ./.github/workflows/scripts/release-framework.sh "${{ needs.detect-changes.outputs.framework-version }}"
plugins-release:
needs:
[
check-skip,
detect-changes,
test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
core-release,
framework-release,
]
if: "always() && needs.check-skip.outputs.should-skip != 'true' && needs.detect-changes.outputs.plugins-need-release == 'true' && (needs.test-core.result == 'success' || needs.test-core.result == 'skipped') && (needs.test-framework.result == 'success' || needs.test-framework.result == 'skipped') && needs.test-plugins.result == 'success' && (needs.test-bifrost-http.result == 'success' || needs.test-bifrost-http.result == 'skipped') && (needs.test-migrations.result == 'success' || needs.test-migrations.result == 'skipped') && (needs.detect-changes.outputs.core-needs-release == 'false' || needs.core-release.result == 'success' || needs.core-release.result == 'skipped') && (needs.detect-changes.outputs.framework-needs-release == 'false' || needs.framework-release.result == 'success' || needs.framework-release.result == 'skipped')"
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
success: ${{ steps.release.outputs.success }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
token: ${{ secrets.GH_TOKEN }}
- name: Install jq
run: |
sudo apt-get update
sudo apt-get install -y jq
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.26"
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Configure Git
run: |
git config user.name "GitHub Actions Bot"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Set up Docker Compose
run: |
# Verify Docker is available
docker --version
# Install Docker Compose if not available as plugin
if ! docker compose version >/dev/null 2>&1; then
echo "Installing Docker Compose..."
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
else
echo "Docker Compose plugin is available"
docker compose version
fi
- name: Release all changed plugins
id: release
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
MAXIM_API_KEY: ${{ secrets.MAXIM_API_KEY }}
MAXIM_LOGGER_ID: ${{ secrets.MAXIM_LOG_REPO_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_SESSION_TOKEN: ${{ secrets.AWS_SESSION_TOKEN }}
AWS_ARN: ${{ secrets.AWS_ARN }}
BEDROCK_API_KEY: ${{ secrets.BEDROCK_API_KEY }}
AZURE_ENDPOINT: ${{ secrets.AZURE_ENDPOINT }}
AZURE_API_KEY: ${{ secrets.AZURE_API_KEY }}
AZURE_API_VERSION: ${{ secrets.AZURE_API_VERSION }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
PARASAIL_API_KEY: ${{ secrets.PARASAIL_API_KEY }}
ELEVENLABS_API_KEY: ${{ secrets.ELEVENLABS_API_KEY }}
PERPLEXITY_API_KEY: ${{ secrets.PERPLEXITY_API_KEY }}
SGL_API_KEY: ${{ secrets.SGL_API_KEY }}
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
VERTEX_CREDENTIALS: ${{ secrets.VERTEX_CREDENTIALS }}
VERTEX_PROJECT_ID: ${{ secrets.VERTEX_PROJECT_ID }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
HUGGING_FACE_API_KEY: ${{ secrets.HUGGING_FACE_API_KEY }}
REPLICATE_API_KEY: ${{ secrets.REPLICATE_API_KEY }}
REPLICATE_OWNER: ${{ secrets.REPLICATE_OWNER }}
run: ./.github/workflows/scripts/release-all-plugins.sh '${{ needs.detect-changes.outputs.changed-plugins }}'
bifrost-http-release:
needs:
[
check-skip,
detect-changes,
test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
core-release,
framework-release,
plugins-release,
]
if: "always() && needs.check-skip.outputs.should-skip != 'true' && needs.detect-changes.outputs.bifrost-http-needs-release == 'true' && (needs.test-core.result == 'success' || needs.test-core.result == 'skipped') && (needs.test-framework.result == 'success' || needs.test-framework.result == 'skipped') && (needs.test-plugins.result == 'success' || needs.test-plugins.result == 'skipped') && needs.test-bifrost-http.result == 'success' && needs.test-migrations.result == 'success' && (needs.detect-changes.outputs.core-needs-release == 'false' || needs.core-release.result == 'success' || needs.core-release.result == 'skipped') && (needs.detect-changes.outputs.framework-needs-release == 'false' || needs.framework-release.result == 'success' || needs.framework-release.result == 'skipped') && (needs.detect-changes.outputs.plugins-need-release == 'false' || needs.plugins-release.result == 'success' || needs.plugins-release.result == 'skipped')"
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
success: ${{ steps.release.outputs.success }}
version: ${{ needs.detect-changes.outputs.transport-version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
token: ${{ secrets.GH_TOKEN }}
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.26"
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Configure Git
run: |
git config user.name "GitHub Actions Bot"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Set up Docker Compose
run: |
# Verify Docker is available
docker --version
# Install Docker Compose if not available as plugin
if ! docker compose version >/dev/null 2>&1; then
echo "Installing Docker Compose..."
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
else
echo "Docker Compose plugin is available"
docker compose version
fi
- name: Release bifrost-http
id: release
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
MAXIM_API_KEY: ${{ secrets.MAXIM_API_KEY }}
MAXIM_LOGGER_ID: ${{ secrets.MAXIM_LOG_REPO_ID }}
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
R2_BUCKET: ${{ secrets.R2_BUCKET }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_SESSION_TOKEN: ${{ secrets.AWS_SESSION_TOKEN }}
AWS_ARN: ${{ secrets.AWS_ARN }}
BEDROCK_API_KEY: ${{ secrets.BEDROCK_API_KEY }}
AZURE_ENDPOINT: ${{ secrets.AZURE_ENDPOINT }}
AZURE_API_KEY: ${{ secrets.AZURE_API_KEY }}
AZURE_API_VERSION: ${{ secrets.AZURE_API_VERSION }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
PARASAIL_API_KEY: ${{ secrets.PARASAIL_API_KEY }}
ELEVENLABS_API_KEY: ${{ secrets.ELEVENLABS_API_KEY }}
PERPLEXITY_API_KEY: ${{ secrets.PERPLEXITY_API_KEY }}
SGL_API_KEY: ${{ secrets.SGL_API_KEY }}
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
VERTEX_CREDENTIALS: ${{ secrets.VERTEX_CREDENTIALS }}
VERTEX_PROJECT_ID: ${{ secrets.VERTEX_PROJECT_ID }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
HUGGING_FACE_API_KEY: ${{ secrets.HUGGING_FACE_API_KEY }}
REPLICATE_API_KEY: ${{ secrets.REPLICATE_API_KEY }}
REPLICATE_OWNER: ${{ secrets.REPLICATE_OWNER }}
run: ./.github/workflows/scripts/release-bifrost-http.sh "${{ needs.detect-changes.outputs.transport-version }}"
# Docker build amd64
docker-build-amd64:
needs:
[
check-skip,
detect-changes,
test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
core-release,
framework-release,
plugins-release,
bifrost-http-release,
]
if: "always() && needs.check-skip.outputs.should-skip != 'true' && needs.detect-changes.outputs.docker-needs-release == 'true' && (needs.test-core.result == 'success' || needs.test-core.result == 'skipped') && (needs.test-framework.result == 'success' || needs.test-framework.result == 'skipped') && (needs.test-plugins.result == 'success' || needs.test-plugins.result == 'skipped') && (needs.test-bifrost-http.result == 'success' || needs.test-bifrost-http.result == 'skipped') && (needs.test-migrations.result == 'success' || needs.test-migrations.result == 'skipped') && (needs.detect-changes.outputs.core-needs-release == 'false' || needs.core-release.result == 'success' || needs.core-release.result == 'skipped') && (needs.detect-changes.outputs.framework-needs-release == 'false' || needs.framework-release.result == 'success' || needs.framework-release.result == 'skipped') && (needs.detect-changes.outputs.plugins-need-release == 'false' || needs.plugins-release.result == 'success' || needs.plugins-release.result == 'skipped') && (needs.detect-changes.outputs.bifrost-http-needs-release == 'false' || needs.bifrost-http-release.result == 'success' || needs.bifrost-http-release.result == 'skipped')"
runs-on: ubuntu-latest
permissions:
contents: write
env:
REGISTRY: docker.io
ACCOUNT: maximhq
IMAGE_NAME: bifrost
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Verify bifrost-http release
id: verify
continue-on-error: true
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
./.github/workflows/scripts/verify-bifrost-http-release.sh "${{ needs.detect-changes.outputs.transport-version }}" "${{ needs.detect-changes.outputs.bifrost-http-needs-release }}"
echo "verified=true" >> $GITHUB_OUTPUT
- name: Setup Docker Buidx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Determine Docker tags
id: tags
run: |
git pull origin ${{ github.ref_name }}
VERSION="${{ needs.detect-changes.outputs.transport-version }}"
BASE_TAG="${{ env.REGISTRY }}/${{ env.ACCOUNT }}/${{ env.IMAGE_NAME }}:v${VERSION}-amd64"
echo "tags=${BASE_TAG}" >> $GITHUB_OUTPUT
- name: Build and push AMD64 Docker image
uses: docker/build-push-action@v5
with:
context: .
build-args: |
VERSION=${{ needs.detect-changes.outputs.transport-version }}
file: ./transports/Dockerfile
push: true
tags: ${{ steps.tags.outputs.tags }}
platforms: linux/amd64
# Docker build arm64
docker-build-arm64:
needs:
[
check-skip,
detect-changes,
test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
core-release,
framework-release,
plugins-release,
bifrost-http-release,
]
if: "always() && needs.check-skip.outputs.should-skip != 'true' && needs.detect-changes.outputs.docker-needs-release == 'true' && (needs.test-core.result == 'success' || needs.test-core.result == 'skipped') && (needs.test-framework.result == 'success' || needs.test-framework.result == 'skipped') && (needs.test-plugins.result == 'success' || needs.test-plugins.result == 'skipped') && (needs.test-bifrost-http.result == 'success' || needs.test-bifrost-http.result == 'skipped') && (needs.test-migrations.result == 'success' || needs.test-migrations.result == 'skipped') && (needs.detect-changes.outputs.core-needs-release == 'false' || needs.core-release.result == 'success' || needs.core-release.result == 'skipped') && (needs.detect-changes.outputs.framework-needs-release == 'false' || needs.framework-release.result == 'success' || needs.framework-release.result == 'skipped') && (needs.detect-changes.outputs.plugins-need-release == 'false' || needs.plugins-release.result == 'success' || needs.plugins-release.result == 'skipped') && (needs.detect-changes.outputs.bifrost-http-needs-release == 'false' || needs.bifrost-http-release.result == 'success' || needs.bifrost-http-release.result == 'skipped')"
runs-on: ubuntu-24.04-arm
permissions:
contents: write
env:
REGISTRY: docker.io
ACCOUNT: maximhq
IMAGE_NAME: bifrost
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Verify bifrost-http release
id: verify
continue-on-error: true
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
./.github/workflows/scripts/verify-bifrost-http-release.sh "${{ needs.detect-changes.outputs.transport-version }}" "${{ needs.detect-changes.outputs.bifrost-http-needs-release }}"
echo "verified=true" >> $GITHUB_OUTPUT
- name: Setup Docker Buidx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Determine Docker tags
id: tags
run: |
git pull origin ${{ github.ref_name }}
VERSION="${{ needs.detect-changes.outputs.transport-version }}"
BASE_TAG="${{ env.REGISTRY }}/${{ env.ACCOUNT }}/${{ env.IMAGE_NAME }}:v${VERSION}-arm64"
echo "tags=${BASE_TAG}" >> $GITHUB_OUTPUT
- name: Build and push ARM64 Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./transports/Dockerfile
push: true
build-args: |
VERSION=${{ needs.detect-changes.outputs.transport-version }}
tags: ${{ steps.tags.outputs.tags }}
platforms: linux/arm64
# Docker manifest
docker-manifest:
needs: [check-skip, detect-changes, docker-build-amd64, docker-build-arm64]
if: "always() && needs.check-skip.outputs.should-skip != 'true' && needs.docker-build-amd64.result == 'success' && needs.docker-build-arm64.result == 'success'"
runs-on: ubuntu-latest
env:
REGISTRY: docker.io
ACCOUNT: maximhq
IMAGE_NAME: bifrost
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Create and push multi-arch manifest
run: |
./.github/workflows/scripts/create-docker-manifest.sh "${{ needs.detect-changes.outputs.transport-version }}"
# Push Mintlify changelog
push-mintlify-changelog:
needs:
[
check-skip,
detect-changes,
test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
core-release,
framework-release,
plugins-release,
bifrost-http-release,
]
if: "always() && needs.check-skip.outputs.should-skip != 'true' && (needs.test-core.result == 'success' || needs.test-core.result == 'skipped') && (needs.test-framework.result == 'success' || needs.test-framework.result == 'skipped') && (needs.test-plugins.result == 'success' || needs.test-plugins.result == 'skipped') && (needs.test-bifrost-http.result == 'success' || needs.test-bifrost-http.result == 'skipped') && (needs.test-migrations.result == 'success' || needs.test-migrations.result == 'skipped') && (needs.detect-changes.outputs.core-needs-release == 'false' || needs.core-release.result == 'success' || needs.core-release.result == 'skipped') && (needs.detect-changes.outputs.framework-needs-release == 'false' || needs.framework-release.result == 'success' || needs.framework-release.result == 'skipped') && (needs.detect-changes.outputs.plugins-need-release == 'false' || needs.plugins-release.result == 'success' || needs.plugins-release.result == 'skipped') && (needs.detect-changes.outputs.bifrost-http-needs-release == 'false' || needs.bifrost-http-release.result == 'success' || needs.bifrost-http-release.result == 'skipped')"
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
token: ${{ secrets.GH_TOKEN }}
- name: Push Mintlify changelog
run: |
./.github/workflows/scripts/push-mintlify-changelog.sh "${{ needs.detect-changes.outputs.transport-version }}"
# Notification
notify:
needs:
[
check-skip,
detect-changes,
test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
core-release,
framework-release,
plugins-release,
bifrost-http-release,
docker-manifest,
]
if: "always() && needs.check-skip.outputs.should-skip != 'true'"
runs-on: ubuntu-latest
steps:
- name: Install jq
run: |
sudo apt-get update
sudo apt-get install -y jq
- name: Discord Notification
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
run: |
# Build status summary
CORE_STATUS="⏭️ Skipped"
FRAMEWORK_STATUS="⏭️ Skipped"
PLUGINS_STATUS="⏭️ Skipped"
BIFROST_STATUS="⏭️ Skipped"
if [ "${{ needs.core-release.result }}" = "success" ]; then
CORE_STATUS="✅ Released v${{ needs.detect-changes.outputs.core-version }}"
elif [ "${{ needs.core-release.result }}" = "failure" ]; then
CORE_STATUS="❌ Failed"
fi
if [ "${{ needs.framework-release.result }}" = "success" ]; then
FRAMEWORK_STATUS="✅ Released v${{ needs.detect-changes.outputs.framework-version }}"
elif [ "${{ needs.framework-release.result }}" = "failure" ]; then
FRAMEWORK_STATUS="❌ Failed"
fi
if [ "${{ needs.plugins-release.result }}" = "success" ]; then
PLUGINS_STATUS="✅ Released plugins"
elif [ "${{ needs.plugins-release.result }}" = "failure" ]; then
PLUGINS_STATUS="❌ Failed"
fi
if [ "${{ needs.bifrost-http-release.result }}" = "success" ]; then
BIFROST_STATUS="✅ Released v${{ needs.detect-changes.outputs.transport-version }}"
elif [ "${{ needs.bifrost-http-release.result }}" = "failure" ]; then
BIFROST_STATUS="❌ Failed"
fi
# Build the message with proper formatting
MESSAGE=$(printf "🚀 **Release Pipeline Complete**\n\n**Components:**\n• Core: %s\n• Framework: %s\n• Plugins: %s\n• Bifrost HTTP: %s\n\n**Details:**\n• Branch: \`${{ github.ref_name }}\`\n• Commit: \`%.8s\`\n• Author: %s\n\n[View Workflow Run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})" "$CORE_STATUS" "$FRAMEWORK_STATUS" "$PLUGINS_STATUS" "$BIFROST_STATUS" "${{ github.sha }}" "${{ github.actor }}")
payload="$(jq -n --arg content "$MESSAGE" '{content:$content}')"
curl -sS -H "Content-Type: application/json" -d "$payload" "$DISCORD_WEBHOOK"