[feat]: Stateless playground #413
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |