1313 paths :
1414 - ' tools/studio-bridge/docker/**'
1515 - ' .github/workflows/studio-linux-docker-build.yml'
16+ pull_request :
17+ paths :
18+ - ' tools/studio-bridge/docker/**'
19+ - ' .github/workflows/studio-linux-docker-build.yml'
1620
1721env :
1822 REGISTRY : ghcr.io
2428 outputs :
2529 version : ${{ steps.resolve.outputs.version }}
2630 short : ${{ steps.resolve.outputs.short }}
31+ is_canary : ${{ steps.resolve.outputs.is_canary }}
32+ canary_tag : ${{ steps.resolve.outputs.canary_tag }}
2733 steps :
2834 - name : Resolve Studio version
2935 id : resolve
3743 echo "short=${VERSION:0:12}" >> "$GITHUB_OUTPUT"
3844 echo "Resolved Studio version: $VERSION"
3945
46+ # Canary builds for PRs and non-main branches
47+ # For pull_request events, head_ref is the source branch; for push, ref_name is the branch
48+ BRANCH="${{ github.head_ref || github.ref_name }}"
49+ if [ "$BRANCH" != "main" ]; then
50+ # Sanitize branch name for Docker tag (replace / with -)
51+ CANARY_TAG="canary-${BRANCH//\//-}"
52+ echo "is_canary=true" >> "$GITHUB_OUTPUT"
53+ echo "canary_tag=$CANARY_TAG" >> "$GITHUB_OUTPUT"
54+ echo "Canary build: $CANARY_TAG"
55+ else
56+ echo "is_canary=false" >> "$GITHUB_OUTPUT"
57+ echo "canary_tag=" >> "$GITHUB_OUTPUT"
58+ fi
59+
4060 check-existing :
4161 needs : resolve-version
4262 runs-on : ubuntu-latest
4666 - name : Check if image already exists
4767 id : check
4868 run : |
69+ # Always rebuild canary images
70+ if [ "${{ needs.resolve-version.outputs.is_canary }}" = "true" ]; then
71+ echo "exists=false" >> "$GITHUB_OUTPUT"
72+ echo "Canary build — always rebuild"
73+ exit 0
74+ fi
75+
4976 if docker manifest inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.resolve-version.outputs.version }} > /dev/null 2>&1; then
5077 echo "exists=true" >> "$GITHUB_OUTPUT"
5178 echo "Image already exists for version ${{ needs.resolve-version.outputs.version }}, skipping build"
@@ -77,6 +104,23 @@ jobs:
77104 username : ${{ github.actor }}
78105 password : ${{ secrets.GITHUB_TOKEN }}
79106
107+ - name : Compute image tags
108+ id : tags
109+ run : |
110+ if [ "${{ needs.resolve-version.outputs.is_canary }}" = "true" ]; then
111+ # Canary: only the canary tag, never :latest
112+ TAGS="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.resolve-version.outputs.canary_tag }}"
113+ else
114+ # Production: latest + version tags
115+ TAGS="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
116+ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.resolve-version.outputs.version }}
117+ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.resolve-version.outputs.short }}"
118+ fi
119+ # Use EOF delimiter for multiline
120+ echo "tags<<ENDOFTAGS" >> "$GITHUB_OUTPUT"
121+ echo "$TAGS" >> "$GITHUB_OUTPUT"
122+ echo "ENDOFTAGS" >> "$GITHUB_OUTPUT"
123+
80124 - name : Build and push image
81125 uses : docker/build-push-action@v6
82126 with :
@@ -85,10 +129,7 @@ jobs:
85129 build-args : |
86130 STUDIO_VERSION=${{ needs.resolve-version.outputs.version }}
87131 push : true
88- tags : |
89- ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
90- ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.resolve-version.outputs.version }}
91- ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.resolve-version.outputs.short }}
132+ tags : ${{ steps.tags.outputs.tags }}
92133 cache-from : type=gha
93134 cache-to : type=gha,mode=max
94135
0 commit comments