Skip to content

[feat]: Stateless playground #413

[feat]: Stateless playground

[feat]: Stateless playground #413

name: "06 - railway preview: build images"
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
paths:
- 'api/**'
- 'web/**'
- 'services/**'
- 'sdk/**'
- 'hosting/railway/**'
- '.github/workflows/06-railway-preview-build.yml'
- '.github/workflows/07-railway-preview-deploy.yml'
workflow_dispatch:
inputs:
pr_number:
description: "PR number (for manual runs)"
required: false
type: string
permissions:
contents: read
packages: write
pull-requests: write
concurrency:
group: railway-preview-build-${{ github.event.pull_request.number || github.ref_name }}
cancel-in-progress: true
jobs:
prepare:
if: github.event_name == 'workflow_dispatch' || !github.event.pull_request.draft
runs-on: ubuntu-latest
outputs:
image_tag: ${{ steps.meta.outputs.image_tag }}
pr_number: ${{ steps.meta.outputs.pr_number }}
cache_scope: ${{ steps.meta.outputs.cache_scope }}
steps:
- uses: actions/checkout@v4
- name: Determine build metadata
id: meta
run: |
PR="${{ github.event.pull_request.number || inputs.pr_number }}"
SHA="$(git rev-parse --short HEAD)"
if [ -n "$PR" ]; then
TAG="pr-${PR}-${SHA}"
else
TAG="manual-${SHA}"
fi
if [ -n "$PR" ]; then
CACHE_SCOPE="pr-${PR}"
else
REF="$(printf "%s" "${GITHUB_REF_NAME}" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9._-' '-')"
REF="${REF#-}"
REF="${REF%-}"
CACHE_SCOPE="${REF:-manual}"
fi
CACHE_SCOPE="${CACHE_SCOPE:0:80}"
echo "image_tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "pr_number=${PR}" >> "$GITHUB_OUTPUT"
echo "cache_scope=${CACHE_SCOPE}" >> "$GITHUB_OUTPUT"
echo "Image tag: ${TAG}"
echo "Cache scope: ${CACHE_SCOPE}"
- name: Summary
run: |
TAG="${{ steps.meta.outputs.image_tag }}"
echo "### Railway Preview Images" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "| Image | Tag |" >> "$GITHUB_STEP_SUMMARY"
echo "|-------|-----|" >> "$GITHUB_STEP_SUMMARY"
echo "| agenta-api | \`${TAG}\` |" >> "$GITHUB_STEP_SUMMARY"
echo "| agenta-web | \`${TAG}\` |" >> "$GITHUB_STEP_SUMMARY"
echo "| agenta-services | \`${TAG}\` |" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "- Cache scope: \`${{ steps.meta.outputs.cache_scope }}\`" >> "$GITHUB_STEP_SUMMARY"
echo "- Shared cache: \`buildcache-shared\`" >> "$GITHUB_STEP_SUMMARY"
build-and-push:
needs: prepare
if: needs.prepare.outputs.image_tag != ''
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- image_name: agenta-api
context: api
dockerfile: api/oss/docker/Dockerfile.gh
needs_sdk: true
- image_name: agenta-web
context: web
dockerfile: web/oss/docker/Dockerfile.gh
needs_sdk: false
- image_name: agenta-services
context: services
dockerfile: services/oss/docker/Dockerfile.gh
needs_sdk: true
steps:
- uses: actions/checkout@v4
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Inject SDK into build context
if: matrix.needs_sdk
run: |
rm -rf "${{ matrix.context }}/sdk"
cp -R sdk "${{ matrix.context }}/sdk"
- name: Build and push image
uses: docker/build-push-action@v6
with:
context: ${{ matrix.context }}
file: ${{ matrix.dockerfile }}
push: true
tags: ghcr.io/agenta-ai/${{ matrix.image_name }}:${{ needs.prepare.outputs.image_tag }}
cache-from: |
type=registry,ref=ghcr.io/agenta-ai/${{ matrix.image_name }}:buildcache-shared
type=registry,ref=ghcr.io/agenta-ai/${{ matrix.image_name }}:buildcache-${{ needs.prepare.outputs.cache_scope }}
cache-to: |
type=registry,ref=ghcr.io/agenta-ai/${{ matrix.image_name }}:buildcache-shared,mode=max
type=registry,ref=ghcr.io/agenta-ai/${{ matrix.image_name }}:buildcache-${{ needs.prepare.outputs.cache_scope }},mode=max
- name: Verify SDK source path in image
if: matrix.image_name == 'agenta-api' || matrix.image_name == 'agenta-services'
run: |
IMAGE="ghcr.io/agenta-ai/${{ matrix.image_name }}:${{ needs.prepare.outputs.image_tag }}"
docker pull "$IMAGE"
sdk_path="$(docker run --rm --entrypoint python "$IMAGE" -c "import agenta; print(agenta.__file__)")"
echo "Resolved SDK path: $sdk_path"
case "$sdk_path" in
/app/sdk/*) ;;
*)
echo "Expected SDK to resolve from /app/sdk, got: $sdk_path"
exit 1
;;
esac
- name: Summary
run: |
echo "- Built \`${{ matrix.image_name }}:${{ needs.prepare.outputs.image_tag }}\`" >> "$GITHUB_STEP_SUMMARY"
deploy:
needs: [prepare, build-and-push]
if: needs.prepare.outputs.pr_number != '' && needs.build-and-push.result == 'success'
uses: ./.github/workflows/07-railway-preview-deploy.yml
with:
image_tag: ${{ needs.prepare.outputs.image_tag }}
pr_number: ${{ needs.prepare.outputs.pr_number }}
secrets: inherit