Skip to content

CD: Build and Push DevContainer Image #11

CD: Build and Push DevContainer Image

CD: Build and Push DevContainer Image #11

Workflow file for this run

name: "CD: Build and Push DevContainer Image"
on:
push:
tags:
- "images/**"
workflow_dispatch:
inputs:
tag:
description: "Tag name (e.g., images/base/v1.0.0)"
required: true
type: string
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
name: ${{ steps.meta.outputs.name }}
tags: ${{ steps.meta.outputs.tags }}
image: ${{ steps.meta.outputs.image }}
steps:
- uses: actions/checkout@v4
- name: Extract image name and version from tag
id: meta
run: |
# images/base/v1.0.0 → name=base, version=1.0.0
TAG="${{ inputs.tag || github.ref_name }}"
NAME=$(echo "$TAG" | cut -d'/' -f2)
VERSION=$(echo "$TAG" | sed 's|.*/v||')
# Generate version tags: v2.0.0 → 2.0.0,2.0,2
MAJOR=$(echo "$VERSION" | cut -d'.' -f1)
MINOR=$(echo "$VERSION" | cut -d'.' -f2)
TAGS="${VERSION},${MAJOR}.${MINOR},${MAJOR}"
IMAGE="ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}-images/${NAME}"
echo "name=$NAME" >> "$GITHUB_OUTPUT"
echo "tags=$TAGS" >> "$GITHUB_OUTPUT"
echo "image=$IMAGE" >> "$GITHUB_OUTPUT"
- name: Validate image exists
run: |
if [ ! -d "images/${{ steps.meta.outputs.name }}" ]; then
echo "::error::Image '${{ steps.meta.outputs.name }}' not found"
exit 1
fi
build:
needs: prepare
strategy:
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
suffix: amd64
- platform: linux/arm64
runner: ubuntu-24.04-arm
suffix: arm64
runs-on: ${{ matrix.runner }}
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Install devcontainer CLI
run: npm install -g @devcontainers/cli
- name: Build and push
run: |
devcontainer build \
--workspace-folder images/${{ needs.prepare.outputs.name }} \
--image-name ${{ needs.prepare.outputs.image }}:${{ matrix.suffix }} \
--platform ${{ matrix.platform }} \
--push
manifest:
needs: [prepare, build]
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create and push multi-arch manifests
run: |
IMAGE="${{ needs.prepare.outputs.image }}"
TAGS="${{ needs.prepare.outputs.tags }}"
for TAG in latest $(echo "$TAGS" | tr ',' ' '); do
docker buildx imagetools create -t "${IMAGE}:${TAG}" \
"${IMAGE}:amd64" \
"${IMAGE}:arm64"
done