How to Set Up CI/CD for the Pumpkin-MC/Pumpkin Project: GitHub Actions and Docker Pipeline

The Pumpkin-MC/Pumpkin project automates its Rust Minecraft server builds using GitHub Actions for continuous integration and Docker for continuous delivery, enabling automated testing, linting, and containerized deployment.

Pumpkin is a Rust-based Minecraft server implementation that leverages a comprehensive CI/CD pipeline to ensure code quality and streamline releases. The project uses GitHub Actions to orchestrate the build process and Docker for packaging and deployment. This guide explains how to configure and understand the pipeline using the actual workflow definitions and deployment files from the repository.

Understanding the CI/CD Architecture

The continuous integration pipeline for Pumpkin is defined in .github/workflows/rust.yml. This workflow orchestrates multiple stages including code formatting checks, static analysis, test execution, binary compilation, and container image publishing. The pipeline triggers on every push and pull request targeting the master branch, running on the latest Ubuntu runner.

The workflow integrates with several key configuration files:

  • rust-toolchain.toml specifies the exact Rust version for reproducible builds
  • Dockerfile defines the multi-stage container build process
  • docker-compose.yml provides production deployment orchestration
  • flake.nix enables reproducible builds for Nix users

Configuring the GitHub Actions Workflow

The core CI logic resides in .github/workflows/rust.yml. While the file is located in the hidden .github directory, its structure follows standard Rust CI patterns with Pumpkin-specific deployment steps.

Workflow Triggers and Environment

The pipeline activates on Git events targeting the master branch:

name: Rust CI
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:
    runs-on: ubuntu-latest

Rust Toolchain Setup and Caching

The workflow installs the Rust toolchain specified in rust-toolchain.toml using rustup. To optimize build times, the configuration caches the Cargo registry and git dependencies:

      - name: Cache cargo registry
        uses: actions/cache@v3
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

This caching strategy stores ~/.cargo/registry and ~/.cargo/git between workflow runs, significantly reducing dependency resolution time for subsequent builds.

Code Quality Gates

The CI enforces strict code quality through automated formatting and linting checks. The workflow runs cargo fmt -- --check to verify code style compliance and executes cargo clippy -- -D warnings to catch potential bugs and enforce Rust best practices.

These checks prevent code that fails formatting or contains Clippy warnings from merging into the master branch, maintaining consistent code quality across the pumpkin-* crate workspace.

Testing and Release Builds

After passing quality gates, the workflow executes the full test suite:

      - name: Run tests
        run: cargo test --all-features

The tests cover world loading, packet handling, and plugin interfaces across all workspace crates. Following successful tests, the pipeline builds release binaries using cargo build --release for both the native target and x86_64-unknown-linux-musl (used by the Docker image).

Containerization and Deployment Strategy

Pumpkin uses a multi-stage Docker build to create minimal production images. The CI pipeline automatically builds and publishes these images to Docker Hub.

Building the Docker Image

The workflow constructs the container image using the repository's Dockerfile, which performs a multi-stage build copying the stripped binary into an Alpine Linux base image:

      - name: Build Docker image
        run: |
          docker build -t pumpkinmc/pumpkin:${{ github.sha }} .

This creates an image tagged with the Git commit SHA, ensuring traceability between code versions and deployed artifacts.

Configuring Docker Hub Authentication

To push images to Docker Hub, the workflow uses repository secrets configured in the GitHub settings:

      - name: Push Docker image
        if: github.ref == 'refs/heads/master'
        run: |
          echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u "${{ secrets.DOCKERHUB_USER }}" --password-stdin
          docker push pumpkinmc/pumpkin:${{ github.sha }}

The DOCKERHUB_USER and DOCKERHUB_TOKEN secrets are never exposed in the codebase and are only accessible to the CI environment during master branch builds.

Deploying with Docker Compose

The repository includes a docker-compose.yml file that simplifies production deployment. After the CI pipeline publishes a new image, deploy the server using:

docker compose up -d

This command pulls the latest image and starts the Pumpkin server with the correct volume mounts and port configurations defined in the compose file.

Nix Flake Integration

For users preferring reproducible builds without Docker, the flake.nix file provides a Nix-based development environment. Enter the development shell and run the server with:

nix develop
cargo run --release

This approach ensures the exact Rust toolchain and dependencies specified in the lock files are available without installing system-wide dependencies.

Local CI Testing and Validation

Before pushing changes, you can validate the CI steps locally to ensure builds will pass. Run the formatting check with cargo fmt -- --check, execute cargo clippy -- -D warnings for linting, and verify tests with cargo test --all-features.

For Docker validation, build the image locally using docker build -t pumpkin-local . and test the container startup to verify the multi-stage build process defined in the Dockerfile completes successfully.

Summary

  • The .github/workflows/rust.yml file defines the complete CI/CD pipeline, triggering on pushes and pull requests to the master branch.
  • rust-toolchain.toml pins the Rust version, while the workflow caches ~/.cargo/registry and ~/.cargo/git to accelerate builds.
  • The pipeline enforces code quality through cargo fmt and cargo clippy checks before executing cargo test --all-features.
  • Docker images are built using the multi-stage Dockerfile and pushed to Docker Hub using repository secrets (DOCKERHUB_TOKEN and DOCKERHUB_USER).
  • Production deployment is streamlined via docker-compose.yml, with an alternative flake.nix available for Nix-based workflows.

Frequently Asked Questions

What Rust version does the Pumpkin CI/CD pipeline use?

The pipeline uses the Rust version specified in rust-toolchain.toml, ensuring all CI builds and local development use identical compiler versions. The GitHub Actions workflow installs this specific toolchain via rustup at the start of each run.

How does the CI handle Cargo dependencies between workflow runs?

The workflow uses actions/cache@v3 to persist the ~/.cargo/registry and ~/.cargo/git directories between runs. This cache is keyed by the runner operating system and the hash of Cargo.lock, ensuring dependencies are only downloaded when the lock file changes.

Can I deploy the Pumpkin server without using Docker?

Yes, you can deploy using the flake.nix file for a reproducible Nix-based build, or manually compile the release binary with cargo build --release and run it directly. However, Docker is the primary deployment method supported by the automated CI/CD pipeline.

Where do I configure the Docker Hub credentials for automated image pushes?

Docker Hub authentication is configured in the GitHub repository settings under Secrets and variables > Actions. Add DOCKERHUB_USER for your Docker Hub username and DOCKERHUB_TOKEN for an access token. The workflow references these in the push step using ${{ secrets.DOCKERHUB_USER }} and ${{ secrets.DOCKERHUB_TOKEN }}.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →