From 777eff032e8c609f7f5081500162bd9049c39be5 Mon Sep 17 00:00:00 2001 From: Jon Haddad Date: Sun, 16 Nov 2025 09:11:26 -0700 Subject: [PATCH] Add GitHub Actions CI and Docker container publishing - Configure Jib Gradle plugin 3.4.5 for Docker image builds - Add PR workflow for building on pull requests - Add main branch workflow for publishing to GitHub Container Registry - Configure multi-architecture support (amd64, arm64) - Use eclipse-temurin:17-jre-alpine as base image - Expose ports 8080 (REST API) and 5432 (PostgreSQL protocol) - Add Docker deployment documentation to README - Memory configuration via Docker flags, no hardcoded limits - Skip tests in CI (require running Cassandra instance) --- .github/workflows/main-ci.yml | 62 +++++++++++++++++++++++++++++++ .github/workflows/pr-ci.yml | 37 +++++++++++++++++++ README.md | 69 +++++++++++++++++++++++++++++++++++ build.gradle | 44 ++++++++++++++++++++++ 4 files changed, 212 insertions(+) create mode 100644 .github/workflows/main-ci.yml create mode 100644 .github/workflows/pr-ci.yml diff --git a/.github/workflows/main-ci.yml b/.github/workflows/main-ci.yml new file mode 100644 index 0000000..245376a --- /dev/null +++ b/.github/workflows/main-ci.yml @@ -0,0 +1,62 @@ +name: Main Branch CI + +on: + push: + branches: + - main + +permissions: + contents: read + packages: write + +jobs: + publish: + name: Publish Docker Image + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Set up Java 17 + uses: actions/setup-java@v5 + with: + distribution: 'temurin' + java-version: '17' + + - name: Cache Gradle packages + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build and push Docker image + env: + GITHUB_ACTOR: ${{ github.actor }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Build and push with Jib + ./gradlew jib --no-daemon \ + -Djib.to.tags=latest,${{ github.sha }} + + - name: Docker Image Summary + run: | + echo "### Docker Image Published" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Image:** ghcr.io/geico/cassandra-sql" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Tags:**" >> $GITHUB_STEP_SUMMARY + echo "- \`latest\`" >> $GITHUB_STEP_SUMMARY + echo "- \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Pull command:**" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY + echo "docker pull ghcr.io/geico/cassandra-sql:latest" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml new file mode 100644 index 0000000..514ec32 --- /dev/null +++ b/.github/workflows/pr-ci.yml @@ -0,0 +1,37 @@ +name: Pull Request CI + +on: + pull_request: + branches: + - main + +jobs: + build: + name: Build + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Set up Java 17 + uses: actions/setup-java@v5 + with: + distribution: "temurin" + java-version: "17" + + - name: Cache Gradle packages + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build + run: ./gradlew build -x test --no-daemon diff --git a/README.md b/README.md index 9a6ebac..105027b 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,75 @@ See [docs/DEMO_ECOMMERCE.md](docs/DEMO_ECOMMERCE.md) for detailed demo walkthrou --- +## Docker Deployment + +Docker images are automatically built and published to GitHub Container Registry on every merge to the `main` branch. + +### Pulling the Docker Image + +```bash +docker pull ghcr.io/geico/cassandra-sql:latest +``` + +### Running with Docker + +```bash +# Run the container +docker run -d \ + --name cassandra-sql \ + -p 8080:8080 \ + -p 5432:5432 \ + -e CASSANDRA_CONTACT_POINTS=host.docker.internal \ + ghcr.io/geico/cassandra-sql:latest +``` + +**Exposed Ports**: +- `8080`: REST API endpoint +- `5432`: PostgreSQL wire protocol server + +**Environment Variables**: +- `CASSANDRA_CONTACT_POINTS`: Cassandra server address (default: localhost) +- `CASSANDRA_PORT`: Cassandra port (default: 9042) +- `CASSANDRA_KEYSPACE`: Keyspace name (default: cassandra_sql) +- `POSTGRES_PORT`: PostgreSQL protocol port (default: 5432) + +**Memory Configuration**: + +Java 17 automatically detects container memory limits. Configure memory using Docker: + +```bash +# Limit container to 2GB +docker run --memory=2g ghcr.io/geico/cassandra-sql:latest + +# Or set JVM heap size directly +docker run -e JAVA_TOOL_OPTIONS="-Xmx2g" ghcr.io/geico/cassandra-sql:latest +``` + +### Connecting to the Docker Container + +Once running, you can connect using psql: + +```bash +psql -h localhost -p 5432 -d cassandra_sql +``` + +Or access the REST API: + +```bash +curl -X POST http://localhost:8080/api/sql/execute \ + -H "Content-Type: application/json" \ + -d '{"sql": "SELECT 1"}' +``` + +### Image Details + +- **Base Image**: eclipse-temurin:17-jre-alpine +- **Size**: ~150-200MB +- **Architecture**: amd64, arm64 +- **Registry**: GitHub Container Registry (ghcr.io) + +--- + ## SQL Feature Support See [docs/SQL_GRAMMAR.md](docs/SQL_GRAMMAR.md) for detailed implementation status. diff --git a/build.gradle b/build.gradle index 15c3c58..c4ce5af 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,7 @@ plugins { id 'java' id 'org.springframework.boot' version '3.1.5' id 'io.spring.dependency-management' version '1.1.3' + id 'com.google.cloud.tools.jib' version '3.4.5' } group = 'org.cassandrasql' @@ -195,3 +196,46 @@ task buildWithTests { } } +// Jib configuration for Docker container building +jib { + from { + image = 'eclipse-temurin:17-jre-alpine' + platforms { + platform { + architecture = 'amd64' + os = 'linux' + } + platform { + architecture = 'arm64' + os = 'linux' + } + } + } + + to { + image = 'ghcr.io/geico/cassandra-sql' + tags = [version, 'latest'] + auth { + username = System.getenv('GITHUB_ACTOR') ?: 'username' + password = System.getenv('GITHUB_TOKEN') ?: 'token' + } + } + + container { + jvmFlags = [ + '-XX:+UseG1GC', + '-XX:MaxGCPauseMillis=100' + ] + ports = ['8080', '5432'] + labels = [ + 'org.opencontainers.image.title': 'Cassandra SQL', + 'org.opencontainers.image.description': 'SQL layer for Apache Cassandra with PostgreSQL wire protocol support', + 'org.opencontainers.image.version': version, + 'org.opencontainers.image.source': 'https://github.com/geico/cassandra-sql', + 'org.opencontainers.image.licenses': 'Apache-2.0' + ] + creationTime = 'USE_CURRENT_TIMESTAMP' + format = 'OCI' + } +} +