diff --git a/.gitea/actions/docker-build/action.yml b/.gitea/actions/docker-build/action.yml new file mode 100644 index 0000000..4e8c7e7 --- /dev/null +++ b/.gitea/actions/docker-build/action.yml @@ -0,0 +1,154 @@ +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 diff --git a/README.md b/README.md index b29e25a..870f032 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,56 @@ # actions-docker -Reusable Docker build+push action for Gitea Actions with buildx and layer caching \ No newline at end of file +Reusable Gitea Actions for Docker build + push workflows. + +## actions/docker-build + +Composite action that builds and optionally pushes Docker images with `docker buildx`. + +### Usage + +```yaml +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: https://gitea.com/actions/checkout@v4 + + - name: Build and push + uses: https://git.ericxliu.me/eric/actions-docker/.gitea/actions/docker-build@main + with: + image-name: registry.example.com/myimage + dockerfile: Dockerfile + context: . + push: true + cache-from: type=local,src=/tmp/buildx-cache + cache-to: type=local,dest=/tmp/buildx-cache,mode=max +``` + +### Inputs + +| Input | Required | Default | Description | +|-------|----------|---------|-------------| +| `dockerfile` | No | `Dockerfile` | Path to Dockerfile relative to `context` | +| `context` | No | `.` | Build context path | +| `image-name` | **Yes** | — | Full image name (registry/image) | +| `tags` | No | (none) | Extra tags as CSV | +| `platforms` | No | `linux/amd64` | Platforms as CSV | +| `push` | No | `false` | Push images after build | +| `cache-from` | No | — | Cache source | +| `cache-to` | No | `type=local,dest=/tmp/buildx-cache,mode=max` | Cache destination | +| `build-args` | No | — | Build args as CSV `KEY=VALUE,KEY2=VALUE2` | + +### Outputs + +| Output | Description | +|--------|-------------| +| `image` | Full image name | +| `tag` | Primary tag (date-SHA) | +| `digest` | Image digest after push | + +### Features + +- **Multi-platform** builds via QEMU (if platforms != linux/amd64) +- **Layer caching** via local buildx cache +- **Git metadata** — auto-adds `date-SHA` tag + git tag if on a tag ref +- **`DOCKER_HOST`** — auto-configured for Gitea Actions (`tcp://docker.local:2375`)