Merge pull request #24 from broadinstitute/fix-delete-event-builds #37
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: Docker Build | |
| on: | |
| push: | |
| branches: ['**'] | |
| tags: ['**'] | |
| pull_request: | |
| branches: [main] | |
| merge_group: | |
| delete: # Trigger cleanup when branches are deleted | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| jobs: | |
| build-amd64: | |
| if: github.event_name != 'delete' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| outputs: | |
| digest: ${{ steps.build.outputs.digest }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Container Registry | |
| if: github.event_name == 'push' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Generate tag suffix | |
| id: tag | |
| run: | | |
| # Sanitize ref_name: replace / with - for valid Docker tags | |
| echo "suffix=$(echo '${{ github.ref_name }}' | tr '/' '-')" >> $GITHUB_OUTPUT | |
| - name: Build and push (amd64) | |
| id: build | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| platforms: linux/amd64 | |
| push: ${{ github.event_name == 'push' }} | |
| tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.suffix }}-amd64 | |
| cache-from: | | |
| type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-amd64 | |
| type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main-amd64 | |
| cache-to: ${{ github.event_name == 'push' && format('type=registry,ref={0}/{1}:buildcache-amd64,mode=max', env.REGISTRY, env.IMAGE_NAME) || '' }} | |
| build-arm64: | |
| if: github.event_name != 'delete' | |
| runs-on: ubuntu-24.04-arm | |
| permissions: | |
| contents: read | |
| packages: write | |
| outputs: | |
| digest: ${{ steps.build.outputs.digest }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Container Registry | |
| if: github.event_name == 'push' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Generate tag suffix | |
| id: tag | |
| run: | | |
| # Sanitize ref_name: replace / with - for valid Docker tags | |
| echo "suffix=$(echo '${{ github.ref_name }}' | tr '/' '-')" >> $GITHUB_OUTPUT | |
| - name: Build and push (arm64) | |
| id: build | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| platforms: linux/arm64 | |
| push: ${{ github.event_name == 'push' }} | |
| tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.suffix }}-arm64 | |
| cache-from: | | |
| type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-arm64 | |
| type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main-arm64 | |
| cache-to: ${{ github.event_name == 'push' && format('type=registry,ref={0}/{1}:buildcache-arm64,mode=max', env.REGISTRY, env.IMAGE_NAME) || '' }} | |
| create-manifest: | |
| if: github.event_name == 'push' | |
| needs: [build-amd64, build-arm64] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Generate tag suffix | |
| id: tag | |
| run: | | |
| # Sanitize ref_name: replace / with - for valid Docker tags | |
| echo "suffix=$(echo '${{ github.ref_name }}' | tr '/' '-')" >> $GITHUB_OUTPUT | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=tag | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Create and push manifest | |
| env: | |
| TAGS: ${{ steps.meta.outputs.tags }} | |
| SUFFIX: ${{ steps.tag.outputs.suffix }} | |
| run: | | |
| # Iterate over multi-line tags properly | |
| echo "$TAGS" | while IFS= read -r tag; do | |
| [ -z "$tag" ] && continue | |
| echo "Creating manifest for: $tag" | |
| docker buildx imagetools create \ | |
| --annotation "index:org.opencontainers.image.description=ML-guided qPCR primer design with off-target minimization" \ | |
| --annotation "index:org.opencontainers.image.source=https://github.com/broadinstitute/qprimer_designer" \ | |
| --annotation "index:org.opencontainers.image.licenses=MIT" \ | |
| -t "$tag" \ | |
| "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${SUFFIX}-amd64" \ | |
| "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${SUFFIX}-arm64" | |
| done | |
| cleanup-untagged: | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| needs: [create-manifest] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| packages: write | |
| steps: | |
| - uses: actions/delete-package-versions@v5 | |
| with: | |
| package-name: qprimer_designer | |
| package-type: container | |
| min-versions-to-keep: 5 | |
| delete-only-untagged-versions: true | |
| cleanup-branch-images: | |
| if: github.event_name == 'delete' && github.event.ref_type == 'branch' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| packages: write | |
| steps: | |
| - name: Delete branch images from ghcr.io | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| # Sanitize branch name (same logic as build jobs) | |
| SUFFIX=$(echo '${{ github.event.ref }}' | tr '/' '-') | |
| for arch in amd64 arm64; do | |
| TAG="${SUFFIX}-${arch}" | |
| echo "Looking for tag: $TAG" | |
| # Get version ID for this tag | |
| VERSION_ID=$(gh api \ | |
| "orgs/${{ github.repository_owner }}/packages/container/qprimer_designer/versions" \ | |
| --jq ".[] | select(.metadata.container.tags | contains([\"$TAG\"])) | .id" \ | |
| 2>/dev/null || true) | |
| if [ -n "$VERSION_ID" ]; then | |
| gh api --method DELETE \ | |
| "orgs/${{ github.repository_owner }}/packages/container/qprimer_designer/versions/$VERSION_ID" | |
| echo "Deleted version $VERSION_ID (tag: $TAG)" | |
| else | |
| echo "Tag $TAG not found, skipping" | |
| fi | |
| done |