Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions .github/workflows/quma-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: Quma Image

on:
release:
types: [published]
pull_request:
paths:
- 'container/quma/**'
workflow_dispatch:
inputs:
version:
description: 'Release tag to build (e.g. v0.3.1)'
required: true

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}/quma

jobs:
build:
name: Build & Push
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4

- name: Log in to GHCR
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
type=semver,pattern={{version}},enable=${{ github.event_name == 'release' }}
type=sha,prefix=

- name: Resolve version
id: version
run: |
if [ "${{ github.event_name }}" = "release" ]; then
echo "tag=${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT"
else
echo "tag=${{ github.event.inputs.version }}" >> "$GITHUB_OUTPUT"
fi

- name: Build and push
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: container/quma
file: container/quma/Containerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
QUMA_VERSION=${{ steps.version.outputs.tag }}

build-check:
name: Build Check
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Build image
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: container/quma
file: container/quma/Containerfile
push: false
build-args: |
QUMA_VERSION=v0.3.1
32 changes: 32 additions & 0 deletions container/quma/Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Stage 1: Download pre-built binary from GitHub release
FROM registry.fedoraproject.org/fedora-minimal:latest AS download

ARG QUMA_VERSION
RUN test -n "$QUMA_VERSION" || { echo "ERROR: QUMA_VERSION build arg is required (e.g. v0.3.1)"; exit 1; }

RUN microdnf install -y --nodocs --setopt=install_weak_deps=False \
curl tar xz \
&& microdnf clean all

WORKDIR /download
RUN curl -fsSL -O "https://github.com/cebarks/quartermaster/releases/download/${QUMA_VERSION}/spt-quartermaster-x86_64-unknown-linux-gnu.tar.xz" \
-O "https://github.com/cebarks/quartermaster/releases/download/${QUMA_VERSION}/spt-quartermaster-x86_64-unknown-linux-gnu.tar.xz.sha256" \
&& sha256sum -c spt-quartermaster-x86_64-unknown-linux-gnu.tar.xz.sha256 \
&& tar xf spt-quartermaster-x86_64-unknown-linux-gnu.tar.xz --strip-components=1 \
&& chmod +x quma

# Stage 2: Minimal runtime
FROM registry.fedoraproject.org/fedora-minimal:latest

COPY --from=download /download/quma /usr/local/bin/quma

ENV QUMA_DIR=/opt/spt

VOLUME /opt/spt
EXPOSE 9190

LABEL quma.image-type="quma" \
org.opencontainers.image.title="quma" \
org.opencontainers.image.description="Quartermaster — mod manager for SPT/Fika dedicated servers"

ENTRYPOINT ["quma", "serve"]
7 changes: 7 additions & 0 deletions src/cli/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,13 @@ async fn detect_or_create_container(
dirs: &crate::dirs::QumaDirs,
container_name: &str,
) -> Result<String> {
// Name-first: if a configured container already exists, use it directly.
// Avoids ambiguity when quma itself runs in a container mounting the same dir.
if !container_name.is_empty() && mgr.inspect(container_name).await.is_ok() {
println!("Using configured container: {}", container_name);
return Ok(container_name.to_string());
}

let detected = mgr.detect_spt_containers(dirs).await?;

if detected.len() == 1 {
Expand Down
Loading