Add CI workflow and Docker image build
Automated testing on push/PR and container image publishing
to ghcr.io on main. Multi-stage Dockerfile keeps the production
image free of build tooling and development gems.

Assisted-by: Claude Opus 4.6 via Claude Code
change opsptuwmyyvukuszkkvpvmxwnyqrnlkx
commit 3d3e0eac9113886bd397f629d6e94e02b7115634
author Alpha Chen <alpha@kejadlen.dev>
date
parent ryprnutl
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..2c242a8
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,7 @@
+.git
+.github
+.claude
+.direnv
+.envrc
+db/*.db
+test
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..94e3194
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,50 @@
+name: CI
+
+on:
+  push:
+    branches: [main]
+  pull_request:
+    branches: [main]
+
+permissions:
+  contents: read
+  packages: write
+
+jobs:
+  test:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: ruby/setup-ruby@v1
+        with:
+          ruby-version-file: .ruby-version
+          bundler-cache: true
+      - run: bundle exec rake test
+
+  build:
+    needs: test
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: docker/setup-buildx-action@v3
+      - uses: docker/login-action@v3
+        if: github.ref == 'refs/heads/main' && github.event_name == 'push'
+        with:
+          registry: ghcr.io
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+      - uses: docker/metadata-action@v5
+        id: meta
+        with:
+          images: ghcr.io/${{ github.repository }}
+          tags: |
+            type=raw,value={{date 'YYYYMMDD'}}
+            type=sha,format=short
+      - uses: docker/build-push-action@v6
+        with:
+          context: .
+          push: ${{ github.ref == 'refs/heads/main' && github.event_name == 'push' }}
+          tags: ${{ steps.meta.outputs.tags }}
+          labels: ${{ steps.meta.outputs.labels }}
+          cache-from: type=gha
+          cache-to: type=gha,mode=max
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..0e4f958
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,21 @@
+FROM ruby:4.0-slim AS build
+
+RUN apt-get update && apt-get install -y build-essential && rm -rf /var/lib/apt/lists/*
+
+WORKDIR /app
+
+COPY Gemfile Gemfile.lock ./
+RUN bundle config set without development && bundle install
+
+COPY . .
+
+FROM ruby:4.0-slim
+
+WORKDIR /app
+
+COPY --from=build /usr/local/bundle /usr/local/bundle
+COPY --from=build /app /app
+
+EXPOSE 9292
+
+CMD ["bundle", "exec", "rackup", "-o", "0.0.0.0"]