Skip to content

Commit 2a7c04a

Browse files
authored
Publish Docker images to Docker Hub and GHCR on tag (#51)
- Add multi-stage Dockerfile (rust:slim-bookworm -> debian:bookworm-slim) with g++/cmake for the bundled duckdb C++ build. - Add .dockerignore to keep the build context small. - Add docker.yml workflow: on tag push, builds multi-arch (amd64+arm64) and pushes to docker.io/<user>/sql-splitter and ghcr.io/<owner>/sql-splitter with semver-derived tags. PRs that touch build inputs get a build-only dry run; workflow_dispatch accepts a tag input for backfilling existing releases. Requires DOCKERHUB_USERNAME + DOCKERHUB_TOKEN secrets on the repo before the first publish.
1 parent 1308aa2 commit 2a7c04a

3 files changed

Lines changed: 147 additions & 0 deletions

File tree

.dockerignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.git
2+
.github
3+
target
4+
website
5+
docs
6+
docker
7+
tests/fixtures/generated
8+
tests/data/generated
9+
tests/realworld
10+
benches/data
11+
*.log
12+
*.tmp
13+
.DS_Store

.github/workflows/docker.yml

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
name: Docker
2+
3+
# Builds and publishes the sql-splitter image to Docker Hub and GHCR.
4+
#
5+
# Triggers:
6+
# - push to a version tag (v*): builds that tag
7+
# - workflow_dispatch with `tag` input: builds the given ref (used to backfill old releases)
8+
#
9+
# Required secrets:
10+
# - DOCKERHUB_USERNAME: Docker Hub account (e.g. helgesverre)
11+
# - DOCKERHUB_TOKEN: Docker Hub access token with read/write/delete on the repo
12+
#
13+
# GHCR uses the workflow's GITHUB_TOKEN -- no extra secret needed.
14+
15+
on:
16+
push:
17+
tags:
18+
- 'v*'
19+
pull_request:
20+
paths:
21+
- 'Dockerfile'
22+
- '.dockerignore'
23+
- '.github/workflows/docker.yml'
24+
- 'Cargo.toml'
25+
- 'Cargo.lock'
26+
workflow_dispatch:
27+
inputs:
28+
tag:
29+
description: 'Git tag to build (e.g. v1.13.5). Required for backfill runs.'
30+
required: true
31+
type: string
32+
33+
permissions:
34+
contents: read
35+
packages: write
36+
37+
jobs:
38+
build:
39+
runs-on: ubuntu-latest
40+
steps:
41+
- name: Resolve ref to build
42+
id: ref
43+
run: |
44+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
45+
echo "ref=${{ inputs.tag }}" >> "$GITHUB_OUTPUT"
46+
elif [ "${{ github.event_name }}" = "pull_request" ]; then
47+
# PR validation: build the PR head, don't push
48+
echo "ref=${{ github.event.pull_request.head.sha }}" >> "$GITHUB_OUTPUT"
49+
else
50+
echo "ref=${{ github.ref_name }}" >> "$GITHUB_OUTPUT"
51+
fi
52+
if [ "${{ github.event_name }}" = "pull_request" ]; then
53+
echo "push=false" >> "$GITHUB_OUTPUT"
54+
else
55+
echo "push=true" >> "$GITHUB_OUTPUT"
56+
fi
57+
58+
- uses: actions/checkout@v4
59+
with:
60+
ref: ${{ steps.ref.outputs.ref }}
61+
62+
- name: Set up QEMU
63+
uses: docker/setup-qemu-action@v3
64+
65+
- name: Set up Buildx
66+
uses: docker/setup-buildx-action@v3
67+
68+
- name: Log in to Docker Hub
69+
if: steps.ref.outputs.push == 'true'
70+
uses: docker/login-action@v3
71+
with:
72+
username: ${{ secrets.DOCKERHUB_USERNAME }}
73+
password: ${{ secrets.DOCKERHUB_TOKEN }}
74+
75+
- name: Log in to GHCR
76+
if: steps.ref.outputs.push == 'true'
77+
uses: docker/login-action@v3
78+
with:
79+
registry: ghcr.io
80+
username: ${{ github.actor }}
81+
password: ${{ secrets.GITHUB_TOKEN }}
82+
83+
- name: Compute image metadata
84+
id: meta
85+
if: steps.ref.outputs.push == 'true'
86+
uses: docker/metadata-action@v5
87+
with:
88+
images: |
89+
docker.io/${{ secrets.DOCKERHUB_USERNAME }}/sql-splitter
90+
ghcr.io/${{ github.repository_owner }}/sql-splitter
91+
# Strip any leading "v" so we get both `v1.13.5` and `1.13.5`, plus partial semver tags.
92+
# `latest` is applied automatically when the ref is the highest semver tag.
93+
tags: |
94+
type=semver,pattern={{version}},value=${{ steps.ref.outputs.ref }}
95+
type=semver,pattern={{major}}.{{minor}},value=${{ steps.ref.outputs.ref }}
96+
type=semver,pattern={{major}},value=${{ steps.ref.outputs.ref }}
97+
type=raw,value=${{ steps.ref.outputs.ref }}
98+
99+
- name: Build and push
100+
uses: docker/build-push-action@v6
101+
with:
102+
context: .
103+
# PR validation builds amd64 only to keep CI quick; tag/dispatch publishes multi-arch.
104+
platforms: ${{ steps.ref.outputs.push == 'true' && 'linux/amd64,linux/arm64' || 'linux/amd64' }}
105+
push: ${{ steps.ref.outputs.push == 'true' }}
106+
tags: ${{ steps.meta.outputs.tags }}
107+
labels: ${{ steps.meta.outputs.labels }}
108+
cache-from: type=gha
109+
cache-to: type=gha,mode=max

Dockerfile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# syntax=docker/dockerfile:1.7
2+
# Multi-stage build for sql-splitter.
3+
# Builder uses the latest stable Rust on Debian bookworm so glibc matches the runtime.
4+
# Build deps include g++/cmake/pkg-config because duckdb (bundled) compiles its C++ from source.
5+
6+
FROM rust:slim-bookworm AS builder
7+
WORKDIR /app
8+
RUN apt-get update \
9+
&& apt-get install -y --no-install-recommends \
10+
g++ \
11+
cmake \
12+
pkg-config \
13+
libssl-dev \
14+
ca-certificates \
15+
&& rm -rf /var/lib/apt/lists/*
16+
COPY . .
17+
RUN cargo build --release --locked --bin sql-splitter
18+
19+
FROM debian:bookworm-slim
20+
RUN apt-get update \
21+
&& apt-get install -y --no-install-recommends ca-certificates \
22+
&& rm -rf /var/lib/apt/lists/*
23+
COPY --from=builder /app/target/release/sql-splitter /usr/local/bin/sql-splitter
24+
WORKDIR /data
25+
ENTRYPOINT ["sql-splitter"]

0 commit comments

Comments
 (0)