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
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"]