Repository navigation
Merge pull request #3 from bespokelabsai/feature/preset-images #1
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: Build and push preset images | |
| # Two modes of operation: | |
| # | |
| # * Push to main -> build+push :main (mutable dev tag). Library code | |
| # never references :main; it exists for manual testing. | |
| # | |
| # * workflow_dispatch -> build+push a pinned, immutable tag (e.g. :v1) | |
| # matching PRESET_IMAGE_TAG in src/bespokelabs/sandbox/presets.py. | |
| # This is how you cut a new image release: bump the constant in | |
| # Python, then run this workflow with the same tag value. | |
| # | |
| # :sha-<short> is always emitted for audit/rollback. | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - "images/**" | |
| workflow_dispatch: | |
| inputs: | |
| image: | |
| description: "Specific image to build (e.g. claude-sdk), or 'all'" | |
| required: false | |
| default: "all" | |
| tag: | |
| description: "Pinned tag to publish (e.g. v1). Must match PRESET_IMAGE_TAG." | |
| required: true | |
| default: "v1" | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_PREFIX: ghcr.io/bespokelabsai/sandbox | |
| jobs: | |
| detect-changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| images: ${{ steps.set-matrix.outputs.images }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 2 | |
| - id: set-matrix | |
| run: | | |
| if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | |
| INPUT="${{ github.event.inputs.image }}" | |
| if [[ "$INPUT" == "all" || -z "$INPUT" ]]; then | |
| IMAGES=$(ls -d images/*/ | xargs -I{} basename {} | jq -R -s -c 'split("\n") | map(select(. != ""))') | |
| else | |
| IMAGES=$(echo "[\"$INPUT\"]") | |
| fi | |
| else | |
| # On push, only build images whose Dockerfile changed | |
| CHANGED=$(git diff --name-only HEAD~1 HEAD -- images/ | cut -d/ -f2 | sort -u | jq -R -s -c 'split("\n") | map(select(. != ""))') | |
| if [[ "$CHANGED" == "[]" || "$CHANGED" == '[""]' ]]; then | |
| IMAGES="[]" | |
| else | |
| IMAGES="$CHANGED" | |
| fi | |
| fi | |
| echo "images=$IMAGES" >> "$GITHUB_OUTPUT" | |
| build: | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.images != '[]' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| image: ${{ fromJson(needs.detect-changes.outputs.images) }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: docker/setup-buildx-action@v3 | |
| - uses: docker/metadata-action@v5 | |
| id: meta | |
| with: | |
| images: ${{ env.IMAGE_PREFIX }}/${{ matrix.image }} | |
| # On workflow_dispatch -> the pinned tag input (e.g. :v1). | |
| # On push to main -> :main (dev tag, never referenced by library). | |
| # Always emit :sha-<short> for auditability. | |
| tags: | | |
| type=raw,value=${{ github.event.inputs.tag }},enable=${{ github.event_name == 'workflow_dispatch' }} | |
| type=raw,value=main,enable=${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} | |
| type=sha,prefix=sha- | |
| - uses: docker/build-push-action@v5 | |
| with: | |
| context: images/${{ matrix.image }} | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max |