name: Docker Build & Push
on:
workflow_call:
inputs:
tag-name:
description: "The tag name to build (e.g., v1.0.0)"
required: true
type: string
is-dev-release:
description: "Whether this is a dev/pre-release"
required: false
type: boolean
default: false
workflow_dispatch:
inputs:
tag-name:
description: "The tag name to build (e.g., v1.0.0)"
required: true
type: string
is-dev-release:
description: "Whether this is a dev/pre-release"
required: false
type: boolean
default: false
# Refer: https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds#generating-artifact-attestations-for-your-builds
permissions:
contents: read
jobs:
docker:
name: Build & Push Docker Image
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0 # Fetch all history and tags
- name: Checkout specific tag
run: |
TAG_NAME="${{ inputs.tag-name }}"
echo "Checking out tag: $TAG_NAME"
git checkout $TAG_NAME
# Verify we're on the correct tag
CURRENT_TAG=$(git describe --exact-match --tags HEAD 2>/dev/null || echo "no-tag")
echo "Current tag after checkout: $CURRENT_TAG"
if [ "$CURRENT_TAG" != "$TAG_NAME" ]; then
echo "ERROR: Failed to checkout tag $TAG_NAME. Currently on: $CURRENT_TAG"
exit 1
fi
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "22"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract version and build metadata
id: meta
run: |
TAG_NAME="${{ inputs.tag-name }}"
PACKAGE_VERSION="${TAG_NAME#v}"
GIT_HASH=$(git rev-parse --short HEAD)
IS_DEV_RELEASE=${{ inputs.is-dev-release }}
echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> $GITHUB_ENV
echo "GIT_HASH=$GIT_HASH" >> $GITHUB_ENV
echo "IS_DEV_RELEASE=$IS_DEV_RELEASE" >> $GITHUB_ENV
echo "Package Version: $PACKAGE_VERSION"
echo "Git Hash: $GIT_HASH"
echo "Is Dev Release: $IS_DEV_RELEASE"
- name: Generate Docker tags and labels
id: docker-meta
uses: docker/metadata-action@v5
with:
images: chrisleekr/mcp-server-playground
tags: |
type=raw,value=${{ env.PACKAGE_VERSION }}
type=raw,value=latest,enable=${{ env.IS_DEV_RELEASE == 'false' }}
labels: |
org.opencontainers.image.version=${{ env.PACKAGE_VERSION }}
org.opencontainers.image.revision=${{ env.GIT_HASH }}
- name: Build and push Docker image - Dev/Alpha
if: env.IS_DEV_RELEASE == 'true'
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile
platforms: linux/amd64,linux/arm64
push: true
target: production
cache-from: type=registry,ref=chrisleekr/mcp-server-playground:cache
cache-to: type=registry,mode=max,ref=chrisleekr/mcp-server-playground:cache
build-args: |
PACKAGE_VERSION=${{ env.PACKAGE_VERSION }}
GIT_HASH=${{ env.GIT_HASH }}
NODE_ENV=production
tags: ${{ steps.docker-meta.outputs.tags }}
labels: ${{ steps.docker-meta.outputs.labels }}
- name: Build and push Docker image - Production
if: env.IS_DEV_RELEASE == 'false'
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile
platforms: linux/amd64,linux/arm64
push: true
target: production
cache-from: type=registry,ref=chrisleekr/mcp-server-playground:cache
cache-to: type=registry,mode=max,ref=chrisleekr/mcp-server-playground:cache
build-args: |
PACKAGE_VERSION=${{ env.PACKAGE_VERSION }}
GIT_HASH=${{ env.GIT_HASH }}
NODE_ENV=production
tags: ${{ steps.docker-meta.outputs.tags }}
labels: ${{ steps.docker-meta.outputs.labels }}
- name: Image digest
run: echo "Image pushed with digest ${{ steps.docker-meta.outputs.digest }}"