name: Docker Build + Push description: Build and push Docker images with buildx and layer caching for Gitea Actions author: eric inputs: dockerfile: description: Path to Dockerfile (relative to build_context) default: Dockerfile context: description: Build context path (relative to repo root) default: . image-name: description: Full image name (e.g. registry/image or image) required: true tags: description: Additional tags as CSV appended to defaults default: "" cache-from: description: Cache source (e.g. type=gha, or image:tag) default: "" cache-to: description: Cache destination for buildx (type=gha or type=local) default: type=local,dest=/tmp/buildx-cache,mode=max platforms: description: Target platforms as CSV (e.g. linux/amd64,linux/arm64) default: linux/amd64 push: description: Push images to registry after build default: "false" build-args: description: Build args as CSV KEY=VALUE default: "" outputs: image: description: Full image name with tag value: ${{ steps.meta.outputs.image }} tag: description: The primary tag used (date-SHA) value: ${{ steps.meta.outputs.tag }} digest: description: Image digest (only available after push) value: ${{ steps.push-digest.outputs.digest }} runs: using: composite env: DOCKER_HOST: tcp://docker.local:2375 DOCKER_BUILDKIT: "1" BUILDKIT_HOST: tcp://docker.local:2375 steps: - name: Set up QEMU for multi-platform builds shell: bash if: inputs.platforms != 'linux/amd64' run: | docker run --rm --privileged multiarch/qemu-user-static --reset -p yes 2>/dev/null || true - name: Set up Docker Buildx id: buildx shell: bash run: | mkdir -p $HOME/.docker/cli-plugins curl -fsSL https://github.com/docker/buildx/releases/download/v0.12.1/buildx-v0.12.1.linux-amd64 \ -o $HOME/.docker/cli-plugins/docker-buildx chmod +x $HOME/.docker/cli-plugins/docker-buildx docker buildx version # Create a builder instance (reuse if exists) docker buildx create \ --name gitea-builder \ --driver docker-container \ --driver-opt image=moby/buildkit:buildx-stable-1 \ --driver-opt network=host \ --use \ 2>/dev/null || docker buildx use gitea-builder docker buildx inspect --bootstrap - name: Compute metadata id: meta shell: bash run: | # Generate tags TAGS="latest" if [ -n "${{ inputs.tags }}" ]; then TAGS="$TAGS,${{ inputs.tags }}" fi SHORT_SHA="$(git rev-parse --short HEAD 2>/dev/null || echo 'local')" DATE_TAG="$(date +%Y-%m-%d)" TAG="$DATE_TAG-$SHORT_SHA" TAGS="$TAGS,$TAG" # Add git tag if this is a tag push if [ "${{ github.ref_type }}" = "tag" ] || [[ "${{ github.ref }}" == refs/tags/* ]]; then TAG_NAME="${1#refs/tags/}" TAGS="$TAGS,$TAG_NAME" fi echo "image=${{ inputs.image-name }}" >> $GITHUB_OUTPUT echo "tag=$TAG" >> $GITHUB_OUTPUT echo "tags=$TAGS" >> $GITHUB_OUTPUT - name: Build image id: build shell: bash env: DOCKER_BUILDKIT: "1" run: | set -x CACHE_FROM_FLAG="" if [ -n "${{ inputs.cache-from }}" ]; then CACHE_FROM_FLAG="--cache-from=${{ inputs.cache-from }}" fi BUILD_ARGS_FLAG="" if [ -n "${{ inputs.build-args }}" ]; then for arg in $(echo "${{ inputs.build-args }}" | tr ',' ' '); do BUILD_ARGS_FLAG="$BUILD_ARGS_FLAG --build-arg=$arg" done fi PLATFORM_FLAG="" if [ "${{ inputs.platforms }}" != "linux/amd64" ]; then PLATFORM_FLAG="--platform=${{ inputs.platforms }}" fi PUSH_FLAG="" if [ "${{ inputs.push }}" = "true" ]; then PUSH_FLAG="--push" fi docker buildx build \ $PLATFORM_FLAG \ --tag "${{ inputs.image-name }}:${{ steps.meta.outputs.tag }}" \ --tag "${{ inputs.image-name }}:latest" \ $(for t in $(echo ${{ steps.meta.outputs.tags }} | tr ',' ' '); do echo -n "--tag ${{ inputs.image-name }}:$t "; done) \ --file ${{ inputs.context }}/${{ inputs.dockerfile }} \ --cache-to=${{ inputs.cache-to }} \ $CACHE_FROM_FLAG \ $BUILD_ARGS_FLAG \ --progress=plain \ $PUSH_FLAG \ ${{ inputs.context }} - name: Get image digest id: push-digest shell: bash if: inputs.push == 'true' run: | DIGEST="$(docker inspect "${{ inputs.image-name }}:${{ steps.meta.outputs.tag }}" --format '{{.Digest}}' 2>/dev/null)" echo "digest=$DIGEST" >> $GITHUB_OUTPUT echo "digest_full=${{ inputs.image-name }}@$DIGEST" >> $GITHUB_OUTPUT