diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index e2cf9334a..6189fe6f7 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -20,7 +20,7 @@ on: workflow_dispatch: inputs: process: - description: 'Process to build (pgvector | node-sqitch | postgis)' + description: 'Process to build (pgvector | node-sqitch | postgis | pgvector-postgis | launchql)' type: choice required: true options: @@ -28,6 +28,7 @@ on: - node-sqitch - postgis - pgvector-postgis + - launchql default: pgvector version: description: 'Specific version to build (must exist in version.yaml)' @@ -95,3 +96,55 @@ jobs: REPO_NAME=$REPO \ PLATFORMS="$PLATFORMS" \ build-push-process + + build-launchql: + if: github.event_name != 'pull_request' || !github.event.pull_request.draft + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + + defaults: + run: + working-directory: docker + + env: + REPO: ghcr.io/${{ github.repository_owner }} + PLATFORMS: linux/amd64,linux/arm64 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GHCR + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build LaunchQL (no push) + if: github.event_name == 'pull_request' + run: | + make \ + PROCESS=launchql \ + REPO_NAME=$REPO \ + PLATFORMS="$PLATFORMS" \ + build-process + + - name: Build and push LaunchQL (all versions) + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + run: | + make \ + PROCESS=launchql \ + REPO_NAME=$REPO \ + PLATFORMS="$PLATFORMS" \ + build-push-process diff --git a/docker/Makefile b/docker/Makefile index 5964b5090..4e251f212 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -8,7 +8,7 @@ PLATFORMS?=linux/arm64 PROCESS?=pgvector # Convenience: list of known processes -PROCESSES:=pgvector node-sqitch postgis pgvector-postgis +PROCESSES:=pgvector node-sqitch postgis pgvector-postgis launchql CONTAINER_NAME?=$(PROCESS) @@ -54,12 +54,20 @@ build-process-version: @test -n "$(BASE)" || { echo "Error: BASE is required"; exit 1; } @test -n "$(VERSION)" || { echo "Error: VERSION is required"; exit 1; } @echo " -> $(BASE):$(VERSION) => $(REPO_NAME)/$(PROCESS):$(VERSION) (build)" - @docker buildx build \ + @DOCKERFILE_PATH="$(PROCESS)/Dockerfile"; \ + CONTEXT=$$( \ + if [ "$(PROCESS)" = "launchql" ]; then \ + echo ".."; \ + else \ + echo "$(PROCESS)"; \ + fi ); \ + docker buildx build \ --platform $(PLATFORMS) \ --build-arg BASE=$(BASE) \ --build-arg BASE_VERSION=$(VERSION) \ + --file $$DOCKERFILE_PATH \ -t $(REPO_NAME)/$(PROCESS):$(VERSION) \ - $(PROCESS) + $$CONTEXT # Build+push only a specific VERSION for $(PROCESS). Intended for internal use by build-push-process. # Usage (internal): $(MAKE) BASE= VERSION= build-push-process-version @@ -67,13 +75,21 @@ build-push-process-version: @test -n "$(BASE)" || { echo "Error: BASE is required"; exit 1; } @test -n "$(VERSION)" || { echo "Error: VERSION is required"; exit 1; } @echo " -> $(BASE):$(VERSION) => $(REPO_NAME)/$(PROCESS):$(VERSION) (push)" - @docker buildx build \ + @DOCKERFILE_PATH="$(PROCESS)/Dockerfile"; \ + CONTEXT=$$( \ + if [ "$(PROCESS)" = "launchql" ]; then \ + echo ".."; \ + else \ + echo "$(PROCESS)"; \ + fi ); \ + docker buildx build \ --platform $(PLATFORMS) \ --build-arg BASE=$(BASE) \ --build-arg BASE_VERSION=$(VERSION) \ + --file $$DOCKERFILE_PATH \ -t $(REPO_NAME)/$(PROCESS):$(VERSION) \ --push \ - $(PROCESS) + $$CONTEXT # Aliases all: build-all @@ -91,3 +107,6 @@ postgis: pgvector-postgis: $(MAKE) PROCESS=pgvector-postgis build-process + +launchql: + $(MAKE) PROCESS=launchql build-process diff --git a/docker/launchql/Dockerfile b/docker/launchql/Dockerfile new file mode 100644 index 000000000..f45fce538 --- /dev/null +++ b/docker/launchql/Dockerfile @@ -0,0 +1,56 @@ +ARG BASE=node +ARG BASE_VERSION=20-bookworm +FROM ${BASE}:${BASE_VERSION} AS build + +LABEL org.opencontainers.image.source="https://github.com/launchql/launchql" +ARG BASE +ARG BASE_VERSION +ENV BASE_VERSION=${BASE_VERSION} + +WORKDIR /app + +# System deps for building native modules and tools used by the monorepo +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates curl git python3 make g++; \ + update-ca-certificates || true; \ + corepack enable; \ + corepack prepare yarn@1.22.22 --activate; \ + rm -rf /var/lib/apt/lists/* + +# Copy full repo (build context must be repo root when building this image) +COPY . . + +# Install and build all workspaces +RUN set -eux; \ + yarn install --frozen-lockfile; \ + yarn build + +################################################################################ +FROM ${BASE}:${BASE_VERSION} AS launchql + +LABEL org.opencontainers.image.source="https://github.com/launchql/launchql" +WORKDIR /app + +# Runtime deps (psql optional but handy for debugging) +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends ca-certificates postgresql-client; \ + update-ca-certificates || true; \ + corepack enable; \ + corepack prepare yarn@1.22.22 --activate; \ + rm -rf /var/lib/apt/lists/* + +# Copy built repo from builder +COPY --from=build /app /app + +# Lightweight shims to expose CLI on PATH +RUN set -eux; \ + install -d /usr/local/bin; \ + printf '#!/usr/bin/env bash\nnode /app/packages/cli/dist/index.js "$@"\n' > /usr/local/bin/lql; \ + printf '#!/usr/bin/env bash\nnode /app/packages/cli/dist/index.js "$@"\n' > /usr/local/bin/launchql; \ + chmod +x /usr/local/bin/lql /usr/local/bin/launchql + +ENTRYPOINT ["/usr/local/bin/lql"] +CMD ["--help"] diff --git a/docker/launchql/version.yaml b/docker/launchql/version.yaml new file mode 100644 index 000000000..ed9cabf40 --- /dev/null +++ b/docker/launchql/version.yaml @@ -0,0 +1,4 @@ +base: node +versions: + - 20-bookworm +