Files
bifrost/.github/workflows/release-pipeline.yml
Beyhan Oğur 880f412e2c first commit
2026-04-26 21:52:23 +03:00

1822 lines
77 KiB
YAML

name: Release Pipeline
# Triggers automatically on push to main when any version file changes
on:
push:
branches: ["main"]
workflow_dispatch:
inputs:
skip_tests:
description: 'Skip all tests and jump directly to release (admin only)'
required: false
type: boolean
default: false
# Prevent concurrent runs
concurrency:
group: release-pipeline
cancel-in-progress: false
permissions:
contents: read
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 }}
skip-tests: ${{ steps.skip_tests.outputs.skip-tests }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >+
api.github.com:443
- 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-ci"* ]]; then
echo "should-skip=true" >> $GITHUB_OUTPUT
else
echo "should-skip=false" >> $GITHUB_OUTPUT
fi
- name: Validate admin permission for skip_tests
id: skip_tests
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ inputs.skip_tests }}" == "true" ]]; then
PERMISSION=$(gh api repos/${{ github.repository }}/collaborators/${{ github.actor }}/permission --jq '.permission')
if [[ "$PERMISSION" != "admin" ]]; then
echo "::error::Only repository admins can use skip_tests=true. ${{ github.actor }} has permission: $PERMISSION"
exit 1
fi
echo "Admin verified: ${{ github.actor }} ($PERMISSION)"
echo "skip-tests=true" >> $GITHUB_OUTPUT
else
echo "skip-tests=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-ci
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: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
_http._tcp.azure.archive.ubuntu.com:443
_https._tcp.esm.ubuntu.com:443
_https._tcp.motd.ubuntu.com:443
_https._tcp.packages.microsoft.com:443
api.github.com:443
azure.archive.ubuntu.com:80
dl.google.com:443
esm.ubuntu.com:443
github.com:443
packages.microsoft.com:443
proxy.golang.org:443
registry.hub.docker.com:443
release-assets.githubusercontent.com:443
storage.googleapis.com:443
sum.golang.org:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
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@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- name: Detect what needs release
id: detect
run: ./.github/workflows/scripts/detect-all-changes.sh "auto"
- name: Validate Helm templates
run: |
chmod +x .github/workflows/scripts/validate-helm-templates.sh
.github/workflows/scripts/validate-helm-templates.sh
- name: Validate Helm config fields
run: |
chmod +x .github/workflows/scripts/validate-helm-config-fields.sh
.github/workflows/scripts/validate-helm-config-fields.sh
- name: Validate Go ↔ config.schema.json ↔ helm-chart sync (schemasync)
run: |
chmod +x .github/workflows/scripts/validate-schema-sync.sh
.github/workflows/scripts/validate-schema-sync.sh
# Run all tests in parallel before any releases
test-core:
needs: [check-skip, detect-changes]
if: needs.check-skip.outputs.should-skip != 'true' && needs.check-skip.outputs.skip-tests != 'true' && needs.detect-changes.outputs.core-needs-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
api.anthropic.com:443
api.cerebras.ai:443
api.cohere.ai:443
api.elevenlabs.io:443
api.fireworks.ai:443
api.github.com:443
api.groq.com:443
api.mistral.ai:443
api.openai.com:443
api.parasail.io:443
api.perplexity.ai:443
bedrock-runtime.us-east-1.amazonaws.com:443
bedrock.us-east-1.amazonaws.com:443
bifrost-batch-api-file-upload-testing.s3.us-east-1.amazonaws.com:443
fal.media:443
generativelanguage.googleapis.com:443
github.com:443
huggingface.co:443
login.microsoftonline.com:443
maxim-o1.openai.azure.com:443
nodejs.org:443
openrouter.ai:443
proxy.golang.org:443
registry.npmjs.org:443
release-assets.githubusercontent.com:443
router.huggingface.co:443
storage.googleapis.com:443
sum.golang.org:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "25"
- 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 }}
FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_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 }}
BIFROST_ENCRYPTION_KEY: ${{ secrets.BIFROST_ENCRYPTION_KEY }}
run: ./.github/workflows/scripts/test-core.sh
# Approval gate for flaky test-core failures
# If test-core fails (often due to flaky provider API calls), this job waits for manual approval
# to continue the release pipeline without requiring a full re-run
approve-flaky-test-core:
needs: [check-skip, detect-changes, test-core]
if: |
always() &&
needs.check-skip.outputs.should-skip != 'true' &&
needs.check-skip.outputs.skip-tests != 'true' &&
needs.detect-changes.outputs.core-needs-release == 'true' &&
needs.test-core.result == 'failure'
runs-on: ubuntu-latest
environment:
name: flaky-test-override
url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
outputs:
approved: ${{ steps.approve.outputs.approved }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >+
- name: Display failed test info
run: |
echo "::warning::test-core failed. Review the logs to determine if this is a flaky test."
echo "If this is a known flaky test (e.g., provider API timeout), approve to continue."
echo "If this is a real failure, reject and fix the issue."
- name: Mark as approved
id: approve
run: echo "approved=true" >> $GITHUB_OUTPUT
test-framework:
needs: [check-skip, detect-changes]
if: needs.check-skip.outputs.should-skip != 'true' && needs.check-skip.outputs.skip-tests != 'true' && needs.detect-changes.outputs.framework-needs-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
_grpc_config.cluster.qdrant.io:443
_grpc_config.localhost:443
api.github.com:443
auth.docker.io:443
cluster.qdrant.io:443
cluster.weaviate.network:443
codecov.io:443
dl-cdn.alpinelinux.org:443
ghcr.io:443
github.com:443
pkg-containers.githubusercontent.com:443
production.cloudflare.docker.com:443
proxy.golang.org:443
registry-1.docker.io:443
release-assets.githubusercontent.com:443
storage.googleapis.com:443
sum.golang.org:443
telemetry.qdrant.io:443
uploader.codecov.io:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- 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 }}
FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_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 }}
BIFROST_ENCRYPTION_KEY: ${{ secrets.BIFROST_ENCRYPTION_KEY }}
run: ./.github/workflows/scripts/test-framework.sh
test-plugins:
needs: [check-skip, detect-changes]
if: needs.check-skip.outputs.should-skip != 'true' && needs.check-skip.outputs.skip-tests != 'true' && needs.detect-changes.outputs.plugins-need-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
_grpc_config.localhost:443
_http._tcp.azure.archive.ubuntu.com:443
_https._tcp.esm.ubuntu.com:443
_https._tcp.motd.ubuntu.com:443
_https._tcp.packages.microsoft.com:443
api.github.com:443
api.openai.com:443
auth.docker.io:443
azure.archive.ubuntu.com:80
codecov.io:443
dl-cdn.alpinelinux.org:443
esm.ubuntu.com:443
getbifrost.ai:443
ghcr.io:443
github.com:443
packages.microsoft.com:443
pkg-containers.githubusercontent.com:443
production.cloudflare.docker.com:443
proxy.golang.org:443
registry-1.docker.io:443
release-assets.githubusercontent.com:443
storage.googleapis.com:443
sum.golang.org:443
telemetry.qdrant.io:443
uploader.codecov.io:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
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@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- 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 }}
FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_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 }}
BIFROST_ENCRYPTION_KEY: ${{ secrets.BIFROST_ENCRYPTION_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.check-skip.outputs.skip-tests != 'true' && needs.detect-changes.outputs.bifrost-http-needs-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
172.38.0.12:8080
172.38.0.12:8301
172.38.0.2:5432
api.github.com:443
auth.docker.io:443
codecov.io:443
cr.weaviate.io:443
example.com:443
file.example.com:443
fonts.googleapis.com:443
fonts.gstatic.com:443
getbifrost.ai:443
github.com:443
nodejs.org:443
production.cloudflare.docker.com:443
proxy.golang.org:443
registry-1.docker.io:443
registry.npmjs.org:443
release-assets.githubusercontent.com:443
storage.googleapis.com:443
sum.golang.org:443
telemetry.qdrant.io:443
uploader.codecov.io:443
www.getbifrost.ai:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "25"
- 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 }}
BIFROST_ENCRYPTION_KEY: ${{ secrets.BIFROST_ENCRYPTION_KEY }}
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.check-skip.outputs.skip-tests != 'true' && needs.detect-changes.outputs.bifrost-http-needs-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
172.38.0.2:5432
api.anthropic.com:443
api.github.com:443
api.openai.com:443
auth.docker.io:443
downloads.getmaxim.ai:443
getbifrost.ai:443
github.com:443
nodejs.org:443
production.cloudflare.docker.com:443
proxy.golang.org:443
registry-1.docker.io:443
registry.npmjs.org:443
release-assets.githubusercontent.com:443
storage.googleapis.com:443
sum.golang.org:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "25"
- 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.check-skip.outputs.skip-tests != 'true' && needs.detect-changes.outputs.bifrost-http-needs-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
172.38.0.12:8301
172.38.0.2:5432
_http._tcp.azure.archive.ubuntu.com:443
_https._tcp.esm.ubuntu.com:443
_https._tcp.motd.ubuntu.com:443
_https._tcp.packages.microsoft.com:443
api.github.com:443
api.openai.com:443
auth.docker.io:443
azure.archive.ubuntu.com:80
cdn.jsdelivr.net:443
cdn.playwright.dev:443
cr.weaviate.io:443
d3gk2c5xim1je2.cloudfront.net:443
d4tuoctqmanu0.cloudfront.net:443
docs.getbifrost.ai:443
esm.ubuntu.com:443
fonts.googleapis.com:443
fonts.gstatic.com:443
getbifrost.ai:443
github.com:443
mintcdn.com:443
nodejs.org:443
packages.microsoft.com:443
playwright.download.prss.microsoft.com:443
production.cloudflare.docker.com:443
proxy.golang.org:443
registry-1.docker.io:443
registry.npmjs.org:443
release-assets.githubusercontent.com:443
static.cloudflareinsights.com:443
storage.googleapis.com:443
sum.golang.org:443
telemetry.qdrant.io:443
ts-mcp-sse-proxy.fly.dev:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "25"
- 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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: playwright-report
path: |
tests/e2e/test-results/
tests/e2e/playwright-report/
retention-days: 30
# Docker image test - amd64
test-docker-image-amd64:
needs: [check-skip, detect-changes]
if: needs.check-skip.outputs.should-skip != 'true' && needs.check-skip.outputs.skip-tests != 'true' && needs.detect-changes.outputs.docker-needs-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
api.anthropic.com:443
api.cerebras.ai:443
api.cohere.ai:443
api.elevenlabs.io:443
api.github.com:443
api.groq.com:443
api.mistral.ai:443
api.openai.com:443
api.parasail.io:443
api.replicate.com:443
auth.docker.io:443
bedrock.us-east-1.amazonaws.com:443
dl-cdn.alpinelinux.org:443
fonts.googleapis.com:443
fonts.gstatic.com:443
generativelanguage.googleapis.com:443
getbifrost.ai:443
ghcr.io:443
github.com:443
huggingface.co:443
maxim-o1.openai.azure.com:443
nodejs.org:443
openrouter.ai:443
pkg-containers.githubusercontent.com:443
production.cloudflare.docker.com:443
proxy.golang.org:443
registry-1.docker.io:443
registry.npmjs.org:443
release-assets.githubusercontent.com:443
storage.googleapis.com:443
sum.golang.org:443
telemetry.qdrant.io:443
www.getbifrost.ai:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "25"
- name: Install Newman
run: npm install -g newman newman-reporter-html
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Test Docker image (amd64)
env:
CI: "1"
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
VERTEX_PROJECT_ID: ${{ secrets.VERTEX_PROJECT_ID }}
VERTEX_CREDENTIALS: ${{ secrets.VERTEX_CREDENTIALS }}
GOOGLE_LOCATION: ${{ secrets.GOOGLE_LOCATION }}
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
PERPLEXITY_API_KEY: ${{ secrets.PERPLEXITY_API_KEY }}
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
PARASAIL_API_KEY: ${{ secrets.PARASAIL_API_KEY }}
ELEVENLABS_API_KEY: ${{ secrets.ELEVENLABS_API_KEY }}
FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_API_KEY }}
HUGGING_FACE_API_KEY: ${{ secrets.HUGGING_FACE_API_KEY }}
XAI_API_KEY: ${{ secrets.XAI_API_KEY }}
REPLICATE_API_KEY: ${{ secrets.REPLICATE_API_KEY }}
AZURE_API_KEY: ${{ secrets.AZURE_API_KEY }}
AZURE_ENDPOINT: ${{ secrets.AZURE_ENDPOINT }}
AZURE_API_VERSION: ${{ secrets.AZURE_API_VERSION }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ARN: ${{ secrets.AWS_ARN }}
run: |
chmod +x ./.github/workflows/scripts/test-docker-image.sh
./.github/workflows/scripts/test-docker-image.sh linux/amd64
- name: Upload Newman reports
if: ${{ !cancelled() }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: newman-reports-amd64
path: tests/e2e/api/newman-reports/
retention-days: 30
# Docker image test - arm64
test-docker-image-arm64:
needs: [check-skip, detect-changes]
if: needs.check-skip.outputs.should-skip != 'true' && needs.check-skip.outputs.skip-tests != 'true' && needs.detect-changes.outputs.docker-needs-release == 'true'
runs-on: ubuntu-24.04-arm
permissions:
contents: read
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
api.anthropic.com:443
api.cerebras.ai:443
api.cohere.ai:443
api.elevenlabs.io:443
api.github.com:443
api.groq.com:443
api.mistral.ai:443
api.openai.com:443
api.parasail.io:443
api.replicate.com:443
auth.docker.io:443
bedrock.us-east-1.amazonaws.com:443
dl-cdn.alpinelinux.org:443
fonts.googleapis.com:443
fonts.gstatic.com:443
generativelanguage.googleapis.com:443
getbifrost.ai:443
ghcr.io:443
github.com:443
huggingface.co:443
maxim-o1.openai.azure.com:443
nodejs.org:443
openrouter.ai:443
pkg-containers.githubusercontent.com:443
production.cloudflare.docker.com:443
proxy.golang.org:443
registry-1.docker.io:443
registry.npmjs.org:443
release-assets.githubusercontent.com:443
storage.googleapis.com:443
sum.golang.org:443
telemetry.qdrant.io:443
www.getbifrost.ai:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "25"
- name: Install Newman
run: npm install -g newman newman-reporter-html
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Test Docker image (arm64)
env:
CI: "1"
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
VERTEX_PROJECT_ID: ${{ secrets.VERTEX_PROJECT_ID }}
VERTEX_CREDENTIALS: ${{ secrets.VERTEX_CREDENTIALS }}
GOOGLE_LOCATION: ${{ secrets.GOOGLE_LOCATION }}
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
PERPLEXITY_API_KEY: ${{ secrets.PERPLEXITY_API_KEY }}
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
PARASAIL_API_KEY: ${{ secrets.PARASAIL_API_KEY }}
ELEVENLABS_API_KEY: ${{ secrets.ELEVENLABS_API_KEY }}
FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_API_KEY }}
HUGGING_FACE_API_KEY: ${{ secrets.HUGGING_FACE_API_KEY }}
XAI_API_KEY: ${{ secrets.XAI_API_KEY }}
REPLICATE_API_KEY: ${{ secrets.REPLICATE_API_KEY }}
AZURE_API_KEY: ${{ secrets.AZURE_API_KEY }}
AZURE_ENDPOINT: ${{ secrets.AZURE_ENDPOINT }}
AZURE_API_VERSION: ${{ secrets.AZURE_API_VERSION }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ARN: ${{ secrets.AWS_ARN }}
run: |
chmod +x ./.github/workflows/scripts/test-docker-image.sh
./.github/workflows/scripts/test-docker-image.sh linux/arm64
- name: Upload Newman reports
if: ${{ !cancelled() }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: newman-reports-arm64
path: tests/e2e/api/newman-reports/
retention-days: 30
core-release:
needs:
[
check-skip,
detect-changes,
test-core,
approve-flaky-test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
test-docker-image-amd64,
test-docker-image-arm64,
]
if: "always() && needs.check-skip.outputs.should-skip != 'true' && needs.detect-changes.outputs.core-needs-release == 'true' && (needs.test-core.result == 'success' || needs.test-core.result == 'skipped' || (needs.test-core.result == 'failure' && needs.approve-flaky-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') && (needs.test-docker-image-amd64.result == 'success' || needs.test-docker-image-amd64.result == 'skipped') && (needs.test-docker-image-arm64.result == 'success' || needs.test-docker-image-arm64.result == 'skipped')"
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
success: ${{ steps.release.outputs.success }}
version: ${{ needs.detect-changes.outputs.core-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
api.github.com:443
github.com:443
nodejs.org:443
release-assets.githubusercontent.com:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
token: ${{ secrets.GH_TOKEN }}
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "25"
- 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 }}
FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_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 }}
RUNWAY_API_KEY : ${{ secrets.RUNWAY_API_KEY }}
run: ./.github/workflows/scripts/release-core.sh "${{ needs.detect-changes.outputs.core-version }}"
framework-release:
needs:
[
check-skip,
detect-changes,
test-core,
approve-flaky-test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
test-docker-image-amd64,
test-docker-image-arm64,
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-core.result == 'failure' && needs.approve-flaky-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') && (needs.test-docker-image-amd64.result == 'success' || needs.test-docker-image-amd64.result == 'skipped') && (needs.test-docker-image-arm64.result == 'success' || needs.test-docker-image-arm64.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: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
api.github.com:443
github.com:443
proxy.golang.org:443
release-assets.githubusercontent.com:443
storage.googleapis.com:443
sum.golang.org:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
token: ${{ secrets.GH_TOKEN }}
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- 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 }}
FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_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 }}
RUNWAY_API_KEY : ${{ secrets.RUNWAY_API_KEY }}
run: ./.github/workflows/scripts/release-framework.sh "${{ needs.detect-changes.outputs.framework-version }}"
plugins-release:
needs:
[
check-skip,
detect-changes,
test-core,
approve-flaky-test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
test-docker-image-amd64,
test-docker-image-arm64,
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-core.result == 'failure' && needs.approve-flaky-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') && (needs.test-docker-image-amd64.result == 'success' || needs.test-docker-image-amd64.result == 'skipped') && (needs.test-docker-image-arm64.result == 'success' || needs.test-docker-image-arm64.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: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
_http._tcp.azure.archive.ubuntu.com:443
_https._tcp.esm.ubuntu.com:443
_https._tcp.motd.ubuntu.com:443
_https._tcp.packages.microsoft.com:443
api.github.com:443
azure.archive.ubuntu.com:80
esm.ubuntu.com:443
github.com:443
nodejs.org:443
packages.microsoft.com:443
proxy.golang.org:443
release-assets.githubusercontent.com:443
storage.googleapis.com:443
sum.golang.org:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
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@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "25"
- 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 }}
FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_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 }}
RUNWAY_API_KEY : ${{ secrets.RUNWAY_API_KEY }}
run: ./.github/workflows/scripts/release-all-plugins.sh '${{ needs.detect-changes.outputs.changed-plugins }}'
# Prep: update dependencies, validate build, commit/push
bifrost-http-prep:
needs:
[
check-skip,
detect-changes,
test-core,
approve-flaky-test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
test-docker-image-amd64,
test-docker-image-arm64,
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-core.result == 'failure' && needs.approve-flaky-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') && (needs.test-docker-image-amd64.result == 'success' || needs.test-docker-image-amd64.result == 'skipped') && (needs.test-docker-image-arm64.result == 'success' || needs.test-docker-image-arm64.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')"
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
success: ${{ steps.prep.outputs.success }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
api.github.com:443
fonts.googleapis.com:443
fonts.gstatic.com:443
github.com:443
nodejs.org:443
proxy.golang.org:443
registry.npmjs.org:443
release-assets.githubusercontent.com:443
storage.googleapis.com:443
sum.golang.org:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
token: ${{ secrets.GH_TOKEN }}
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "25"
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Prep bifrost-http release
id: prep
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: ./.github/workflows/scripts/release-bifrost-http-prep.sh "${{ needs.detect-changes.outputs.transport-version }}"
# Build darwin, windows, linux/amd64 binaries and upload to R2
build-binaries-x86:
needs: [bifrost-http-prep, detect-changes]
if: "always() && needs.bifrost-http-prep.result == 'success' && needs.bifrost-http-prep.outputs.success == 'true'"
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
7defe2860d5ee49a1e667e1eeea34b25.r2.cloudflarestorage.com:443
_http._tcp.azure.archive.ubuntu.com:443
_https._tcp.esm.ubuntu.com:443
_https._tcp.motd.ubuntu.com:443
_https._tcp.packages.microsoft.com:443
api.github.com:443
azure.archive.ubuntu.com:80
esm.ubuntu.com:443
files.pythonhosted.org:443
fonts.googleapis.com:443
fonts.gstatic.com:443
github.com:443
nodejs.org:443
packages.microsoft.com:443
proxy.golang.org:443
pypi.org:443
registry.npmjs.org:443
release-assets.githubusercontent.com:443
storage.googleapis.com:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
token: ${{ secrets.GH_TOKEN }}
- name: Pull latest changes
run: git pull origin ${{ github.ref_name }}
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "25"
- name: Build UI
run: make build-ui
- name: Install cross-compilation toolchains
run: bash ./.github/workflows/scripts/install-cross-compilers.sh
- name: Build executables
run: bash ./.github/workflows/scripts/build-executables.sh "${{ needs.detect-changes.outputs.transport-version }}" "darwin/amd64 darwin/arm64 linux/amd64 windows/amd64"
- name: Configure R2
env:
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
run: bash ./.github/workflows/scripts/configure-r2.sh
- name: Upload to R2
env:
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
R2_BUCKET: ${{ secrets.R2_BUCKET }}
SKIP_LATEST_UPLOAD: "true"
run: bash ./.github/workflows/scripts/upload-to-r2.sh "transports/v${{ needs.detect-changes.outputs.transport-version }}"
# Build linux/arm64 natively on ARM runner and upload to R2
build-binaries-arm64:
needs: [bifrost-http-prep, detect-changes]
if: "always() && needs.bifrost-http-prep.result == 'success' && needs.bifrost-http-prep.outputs.success == 'true'"
runs-on: ubuntu-24.04-arm
permissions:
contents: read
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
7defe2860d5ee49a1e667e1eeea34b25.r2.cloudflarestorage.com:443
api.github.com:443
files.pythonhosted.org:443
fonts.googleapis.com:443
fonts.gstatic.com:443
github.com:443
nodejs.org:443
proxy.golang.org:443
pypi.org:443
registry.npmjs.org:443
release-assets.githubusercontent.com:443
storage.googleapis.com:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
token: ${{ secrets.GH_TOKEN }}
- name: Pull latest changes
run: git pull origin ${{ github.ref_name }}
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: "1.26.2"
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "25"
- name: Build UI
run: make build-ui
- name: Build linux/arm64 binary
run: bash ./.github/workflows/scripts/build-executables.sh "${{ needs.detect-changes.outputs.transport-version }}" "linux/arm64"
- name: Configure R2
env:
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
run: bash ./.github/workflows/scripts/configure-r2.sh
- name: Upload to R2
env:
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
R2_BUCKET: ${{ secrets.R2_BUCKET }}
SKIP_LATEST_UPLOAD: "true"
run: bash ./.github/workflows/scripts/upload-to-r2.sh "transports/v${{ needs.detect-changes.outputs.transport-version }}"
# Finalize: changelog, tagging, GitHub release, R2 latest copy
bifrost-http-release:
needs: [build-binaries-x86, build-binaries-arm64, detect-changes, bifrost-http-prep]
if: "always() && needs.build-binaries-x86.result == 'success' && needs.build-binaries-arm64.result == 'success'"
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
success: ${{ steps.release.outputs.success }}
version: ${{ needs.detect-changes.outputs.transport-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
7defe2860d5ee49a1e667e1eeea34b25.r2.cloudflarestorage.com:443
api.github.com:443
files.pythonhosted.org:443
github.com:443
pypi.org:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
token: ${{ secrets.GH_TOKEN }}
- name: Pull latest changes
run: git pull origin ${{ github.ref_name }}
- name: Configure R2
env:
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
run: bash ./.github/workflows/scripts/configure-r2.sh
- name: Finalize bifrost-http release
id: release
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
R2_BUCKET: ${{ secrets.R2_BUCKET }}
run: ./.github/workflows/scripts/release-bifrost-http-finalize.sh "${{ needs.detect-changes.outputs.transport-version }}"
# Docker build amd64
docker-build-amd64:
needs:
[
check-skip,
detect-changes,
test-core,
approve-flaky-test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
test-docker-image-amd64,
test-docker-image-arm64,
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-core.result == 'failure' && needs.approve-flaky-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') && (needs.test-docker-image-amd64.result == 'success' || needs.test-docker-image-amd64.result == 'skipped') && (needs.test-docker-image-arm64.result == 'success' || needs.test-docker-image-arm64.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: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
auth.docker.io:443
dl-cdn.alpinelinux.org:443
fonts.googleapis.com:443
fonts.gstatic.com:443
github.com:443
production.cloudflare.docker.com:443
proxy.golang.org:443
registry-1.docker.io:443
registry.npmjs.org:443
storage.googleapis.com:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
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@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Log in to Docker Hub
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
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@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
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,
approve-flaky-test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
test-docker-image-amd64,
test-docker-image-arm64,
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-core.result == 'failure' && needs.approve-flaky-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') && (needs.test-docker-image-amd64.result == 'success' || needs.test-docker-image-amd64.result == 'skipped') && (needs.test-docker-image-arm64.result == 'success' || needs.test-docker-image-arm64.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: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
auth.docker.io:443
dl-cdn.alpinelinux.org:443
fonts.googleapis.com:443
fonts.gstatic.com:443
github.com:443
production.cloudflare.docker.com:443
proxy.golang.org:443
registry-1.docker.io:443
registry.npmjs.org:443
storage.googleapis.com:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
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@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Log in to Docker Hub
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
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@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
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: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
auth.docker.io:443
github.com:443
production.cloudflare.docker.com:443
registry-1.docker.io:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Log in to Docker Hub
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
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,
approve-flaky-test-core,
test-framework,
test-plugins,
test-bifrost-http,
test-migrations,
test-docker-image-amd64,
test-docker-image-arm64,
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-core.result == 'failure' && needs.approve-flaky-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') && (needs.test-docker-image-amd64.result == 'success' || needs.test-docker-image-amd64.result == 'skipped') && (needs.test-docker-image-arm64.result == 'success' || needs.test-docker-image-arm64.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: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
github.com:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
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,
test-docker-image-amd64,
test-docker-image-arm64,
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: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
_http._tcp.azure.archive.ubuntu.com:443
_https._tcp.esm.ubuntu.com:443
_https._tcp.motd.ubuntu.com:443
_https._tcp.packages.microsoft.com:443
azure.archive.ubuntu.com:80
discord.com:443
dl.google.com:443
esm.ubuntu.com:443
packages.microsoft.com:443
- 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"