Skip to content

feat: CI workflow to build an arbitrary Cassandra branch and publish image + tarball #729

Description

@rustyrazorblade

Scope

On-demand GitHub Actions workflow (in this repo) that builds a single arbitrary Apache Cassandra git ref and publishes both a Docker image (GHCR) and a consumable binary tarball from the same build.

In scope

  • workflow_dispatch trigger with a required ref input (branch / tag / SHA) and an optional repo input (default apache/cassandra, to support forks).
  • Build the ref using the upstream ant artifacts approach to produce a binary tarball.
  • Build a Docker image that is a drop-in replacement for the Docker Official cassandra image (docker.io/library/cassandra, e.g. cassandra:5): a small repo-owned Dockerfile in .github/cassandra-image/ that vendors the official docker-entrypoint.sh + filesystem layout and injects the branch-built tarball on an eclipse-temurin:<N>-jre base (Option A). Same docker-entrypoint.sh contract, CASSANDRA_* env vars, exposed ports (7000/7001/7199/9042/9160), and /var/lib/cassandra volume.
  • Publish the image to GHCR under this repo's namespace; tag = sanitized ref plus an immutable short-SHA tag (never latest).
  • Publish the binary tarball to a GitHub release so it is consumable via cassandra_versions.yaml + install_cassandra.sh.
  • Surface in the workflow run output: the pullable image reference, the tarball download URL, and the resolved Cassandra version + commit SHA.

Out of scope

  • The .deb package variant — that is sibling feat: GitHub Actions to publish arbitrary Cassandra branches as .deb packages #730.
  • Auto-wiring easy-db-lab to deploy the produced artifacts (editing cassandra_versions.yaml, AMI rebuild, a containerized-Cassandra cluster mode). Separate follow-up.
  • Multi-arch image builds — amd64 only (multi-arch is a one-line buildx toggle if arm64 is later needed).
  • Replacing or modifying the existing nightly tarball workflow.
  • Building from uncommitted / local working-tree changes; scheduled/cron or matrix builds.
  • Publishing to Docker Hub (GHCR only, per repo convention).

Acceptance criteria

  • WHEN triggered with a valid ref, THEN the workflow checks out that exact ref, builds it, and publishes both a GHCR image and a tarball.
  • WHEN the build completes, THEN the run output shows the pullable image reference, the tarball URL, and the resolved version + commit SHA.
  • WHEN two builds run from different refs, THEN their image tags and tarball artifacts differ (no silent overwrite).
  • WHEN the supplied ref does not exist in the source repo, THEN the workflow fails fast naming the bad ref and publishes nothing.
  • WHEN the Cassandra build itself fails, THEN nothing is published (no image, no tarball).
  • WHEN the workflow runs, THEN it authenticates to GHCR via this repo's GITHUB_TOKEN pattern, requiring no manual secrets at trigger time.
  • WHEN a ref contains tag-invalid characters (e.g. feature/foo), THEN the image tag is a sanitized, deterministic transform (consistent with publish-container.yml branch sanitization).
  • WHEN the produced image is substituted for cassandra:<n> in a docker-compose service (same CASSANDRA_* env vars, no other changes), THEN it starts and accepts CQL on 9042 — i.e. it honors the Docker Official cassandra image contract.
  • WHEN the published tarball URL is added to cassandra_versions.yaml and installed via install_cassandra.sh, THEN it unpacks and runs as a valid Cassandra install.

Notes / context

  • Image approach (owner decision): Option A — vendor the Docker Official cassandra image's docker-entrypoint.sh + layout into a small repo-owned Dockerfile under .github/cassandra-image/, and inject the branch-built tarball on an eclipse-temurin:<N>-jre base. The image is a drop-in for cassandra:<n>. (Considered and rejected: in-tree Cassandra Docker tooling — it is only a tarball build harness, ships no runnable server image, is absent on 4.0/4.1, and needs docker-in-docker; basing FROM cassandra:5 — brittle JRE/layout surgery.)
  • Locked design defaults: JDK auto-mapped from version (4.x→11, 5.0→17, trunk→17+) with an optional jdk override input; immutable sha-<short> image tag plus a moving friendly ref tag, never latest; one GitHub release per build (cassandra-<version>-<short-sha>), additive, manual pruning; re-run idempotent with no cleanup logic; amd64-only.
  • Prior art: .github/workflows/nightly-cassandra-build.yml (builds apache/cassandra refs with ant artifacts, publishes tarballs to a GitHub release) and .github/workflows/publish-container.yml (GHCR auth, tag sanitization, pull-and-run smoke test). .github/CLAUDE.md reserves latest for the main CLI image — do not reuse it here.
  • The vendored docker-entrypoint.sh is byte-identical across Cassandra 4.1/5.0 (verified); re-vendoring is a deliberate, reviewable PR if it ever changes upstream.
  • Lab tarball consumption today: packer/cassandra/cassandra_versions.yaml, packer/cassandra/install/install_cassandra.sh:158-200, and the use-cassandra command.
  • The build-cassandra CLI command builds the AMI, not a Docker image — do not conflate.
  • Sibling: feat: GitHub Actions to publish arbitrary Cassandra branches as .deb packages #730 (.deb variant) — keep separate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Priority 1 — highenhancementNew feature or requeststatus:in-reviewPR open; awaiting owner GitHub review

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions