Skip to content

✨ feat(kasmvnc): add KasmVNC-based GUI studio environments #15

✨ feat(kasmvnc): add KasmVNC-based GUI studio environments

✨ feat(kasmvnc): add KasmVNC-based GUI studio environments #15

Workflow file for this run

name: Build and Push Docker Images
on:
release:
types: [published]
push:
branches:
- master
paths:
- '**/Dockerfile'
pull_request:
paths:
- '**/Dockerfile'
workflow_dispatch:
inputs:
tag:
description: 'Tag to use for the images (e.g., v1.0.0). Defaults to "latest"'
required: false
type: string
default: 'latest'
# renovate: datasource=docker depName=public.cr.seqera.io/platform/connect-client
connect_client_version:
description: 'Version of connect-client to use (e.g., 0.9)'
required: false
type: string
default: '0.9'
env:
REGISTRY: ghcr.io
# Use provided connect-client version or default to 0.9
CONNECT_CLIENT_VERSION: ${{ inputs.connect_client_version || '0.9' }}
jobs:
setup:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Define container matrix
id: set-matrix
run: |
echo 'matrix={"container":[{"name":"ttyd","path":"./ttyd"},{"name":"streamlit","path":"./streamlit"},{"name":"cellxgene","path":"./cellxgene"},{"name":"shiny","path":"./shiny-simple-example"},{"name":"marimo","path":"./marimo"}]}' >> "$GITHUB_OUTPUT"
build-and-push:
runs-on: ubuntu-latest
needs: setup
permissions:
contents: read
packages: write
strategy:
matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GHCR_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Determine image tag
id: image-tag
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "tag=pr-${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT"
echo "is_pr=true" >> "$GITHUB_OUTPUT"
elif [[ "${{ github.event_name }}" == "release" ]]; then
echo "tag=${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT"
echo "is_pr=false" >> "$GITHUB_OUTPUT"
elif [[ -n "${{ inputs.tag }}" && "${{ inputs.tag }}" != "latest" ]]; then
echo "tag=${{ inputs.tag }}" >> "$GITHUB_OUTPUT"
echo "is_pr=false" >> "$GITHUB_OUTPUT"
else
echo "tag=latest" >> "$GITHUB_OUTPUT"
echo "is_pr=false" >> "$GITHUB_OUTPUT"
fi
- name: Build and push ${{ matrix.container.name }}
uses: docker/build-push-action@v5
with:
context: ${{ matrix.container.path }}
push: true
platforms: linux/amd64
build-args: |
CONNECT_CLIENT_VERSION=${{ env.CONNECT_CLIENT_VERSION }}
tags: |
${{ env.REGISTRY }}/${{ github.repository }}/${{ matrix.container.name }}:${{ steps.image-tag.outputs.tag }}
${{ steps.image-tag.outputs.is_pr == 'false' && format('{0}/{1}/{2}:latest', env.REGISTRY, github.repository, matrix.container.name) || '' }}
labels: |
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.description=Custom Studios Example Container for ${{ matrix.container.name }}
org.opencontainers.image.licenses=MIT
org.opencontainers.image.version=${{ steps.image-tag.outputs.tag }}
cache-from: type=gha,scope=${{ matrix.container.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.container.name }}
cleanup-pr-images:
runs-on: ubuntu-latest
needs: [setup, build-and-push]
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
permissions:
packages: write
strategy:
matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
steps:
- name: Extract PR number from merge commit
id: extract-pr
env:
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
run: |
# Extract PR number from merge commit message (format: "Merge pull request #123 from...")
PR_NUMBER=$(echo "$COMMIT_MESSAGE" | grep -oP 'Merge pull request #\K[0-9]+' || echo "")
if [[ -z "$PR_NUMBER" ]]; then
echo "No PR number found in commit message, skipping cleanup"
echo "found=false" >> "$GITHUB_OUTPUT"
else
echo "Found PR number: $PR_NUMBER"
echo "found=true" >> "$GITHUB_OUTPUT"
echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
fi
- name: Delete PR image for ${{ matrix.container.name }}
if: steps.extract-pr.outputs.found == 'true'
env:
GH_TOKEN: ${{ secrets.GHCR_TOKEN }}
PR_NUMBER: ${{ steps.extract-pr.outputs.number }}
CONTAINER_NAME: ${{ matrix.container.name }}
run: |
PACKAGE_NAME="custom-studios-examples/${CONTAINER_NAME}"
TAG="pr-${PR_NUMBER}"
echo "Checking for $PACKAGE_NAME:$TAG..."
# Get all versions of the package
VERSIONS=$(gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/orgs/seqeralabs/packages/container/${PACKAGE_NAME}/versions" \
--paginate 2>/dev/null || echo "[]")
# Find the version ID for our PR tag
VERSION_ID=$(echo "$VERSIONS" | jq -r ".[] | select(.metadata.container.tags[] == \"$TAG\") | .id" 2>/dev/null || echo "")
if [[ -n "$VERSION_ID" ]]; then
echo "Deleting $PACKAGE_NAME:$TAG (version ID: $VERSION_ID)..."
gh api \
--method DELETE \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/orgs/seqeralabs/packages/container/${PACKAGE_NAME}/versions/${VERSION_ID}" \
&& echo "Successfully deleted $PACKAGE_NAME:$TAG" \
|| echo "Failed to delete $PACKAGE_NAME:$TAG (may not exist)"
else
echo "No image found for $PACKAGE_NAME:$TAG, skipping"
fi