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
80 changes: 34 additions & 46 deletions .github/actions/build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,7 @@ inputs:
type: string
required: false
upstream-ref:
description: "Upstream ref to build"
type: string
required: true
cache-scope:
description: "GHA cache scope for layer caching (empty to disable)"
type: string
required: false
cache-fallback-scope:
description: "Additional GHA cache scope to read from as fallback"
description: "Optional upstream ref override (e.g. 0.34.1); if omitted, the latest upstream release tag is used"
type: string
required: false

Expand All @@ -46,7 +38,7 @@ outputs:
description: "Built image digest"
value: ${{ steps.build.outputs.digest }}
crawl-tag:
description: "Upstream version without v prefix (e.g. 0.34.0)"
description: "Upstream version tag (e.g. 0.34.1)"
value: ${{ steps.compute.outputs.crawl-tag }}
metadata:
description: "Built image metadata"
Expand All @@ -55,6 +47,22 @@ outputs:
runs:
using: composite
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0

- name: Build image
id: build
uses: docker/build-push-action@eb6512707bea5740b2608f2a43ece7bc543cb75b # v7.0.0
with:
context: .
push: false
load: true
build-args: |
CRAWL_TAG=${{ inputs.upstream-ref }}
tags: local/build:${{ github.run_id }}
cache-from: type=gha,scope=${{ inputs.upstream-ref || 'latest' }}
cache-to: type=gha,mode=max,scope=${{ inputs.upstream-ref || 'latest' }}

- name: Compute tags and refs
id: compute
shell: bash -euo pipefail {0}
Expand All @@ -63,16 +71,16 @@ runs:
LABEL: ${{ inputs.label }}
REPOS: ${{ inputs.repos }}
REPOSITORY_NAME: ${{ github.repository }}
CACHE_SCOPE: ${{ inputs.cache-scope }}
CACHE_FALLBACK_SCOPE: ${{ inputs.cache-fallback-scope }}
IMAGE_ID: ${{ steps.build.outputs.imageid }}
run: |
if [[ -z "${UPSTREAM_REF:-}" ]]; then
UPSTREAM_REF=$(docker run --rm --entrypoint cat "${IMAGE_ID}" /app/crawl-tag)
fi

tags=()
base_tag="${UPSTREAM_REF}${LABEL:+-$LABEL}"
tags+=("${base_tag}")

run_tag="${base_tag}-${GITHUB_RUN_ID}.${GITHUB_RUN_ATTEMPT}"
tags+=("${run_tag}")

mapfile -t repo_list < <(
printf '%s' "${REPOS:-}" \
| sed 's/\\r//g' \
Expand All @@ -95,42 +103,22 @@ runs:

primary_ref="${refs[0]}"

crawl_tag="${UPSTREAM_REF#v}"

cache_from=""
cache_to=""
if [[ -n "${CACHE_SCOPE:-}" ]]; then
cache_from="type=gha,scope=${CACHE_SCOPE}"
cache_to="type=gha,mode=max,scope=${CACHE_SCOPE}"
fi
if [[ -n "${CACHE_FALLBACK_SCOPE:-}" ]]; then
NL=$'\n'
cache_from="${cache_from:+${cache_from}${NL}}type=gha,scope=${CACHE_FALLBACK_SCOPE}"
fi

{
printf 'crawl-tag=%s\n' "${crawl_tag}"
printf 'crawl-tag=%s\n' "${UPSTREAM_REF}"
printf 'tags<<EOF\n%s\nEOF\n' "$(printf '%s\n' "${tags[@]}")"
printf 'refs<<EOF\n%s\nEOF\n' "$(printf '%s\n' "${refs[@]}")"
printf 'repos<<EOF\n%s\nEOF\n' "$(printf '%s\n' "${repo_list[@]}")"
printf 'primary-tag=%s\n' "${base_tag}"
printf 'primary-ref=%s\n' "${primary_ref}"
printf 'cache-from<<EOF\n%s\nEOF\n' "${cache_from}"
printf 'cache-to=%s\n' "${cache_to}"
} >> "$GITHUB_OUTPUT"

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0

- name: Build image
id: build
uses: docker/build-push-action@eb6512707bea5740b2608f2a43ece7bc543cb75b # v7.0.0
with:
context: .
push: false
load: true
build-args: |
CRAWL_TAG=${{ steps.compute.outputs.crawl-tag }}
tags: ${{ steps.compute.outputs.refs }}
cache-from: ${{ steps.compute.outputs.cache-from }}
cache-to: ${{ steps.compute.outputs.cache-to }}
- name: Apply final image tags
shell: bash -euo pipefail {0}
env:
IMAGE_ID: ${{ steps.build.outputs.imageid }}
REFS: ${{ steps.compute.outputs.refs }}
run: |
while IFS= read -r ref; do
[[ -z "${ref}" ]] && continue
docker tag "${IMAGE_ID}" "${ref}"
done <<< "${REFS}"
8 changes: 4 additions & 4 deletions .github/actions/test/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ inputs:
runs:
using: composite
steps:
- name: Test CRAWL_TAG environment variable
- name: Test bundled crawl-tag file marker
shell: bash -euo pipefail {0}
env:
IMAGE_REF: ${{ inputs.image-ref }}
CRAWL_TAG: ${{ inputs.crawl-tag }}
run: |
echo "Testing CRAWL_TAG environment variable..."
output="$(docker run --rm --entrypoint printenv ${IMAGE_REF} CRAWL_TAG)"
echo "Testing crawl-tag file marker..."
output="$(docker run --rm --entrypoint cat "${IMAGE_REF}" /app/crawl-tag)"
if [[ "${output}" != "${CRAWL_TAG}" ]]; then
echo "❌ CRAWL_TAG mismatch: expected '${CRAWL_TAG}', got '${output}'"
exit 1
Expand All @@ -33,7 +33,7 @@ runs:
CRAWL_TAG: ${{ inputs.crawl-tag }}
run: |
echo "Testing crawl binary version..."
output="$(docker run --rm --entrypoint ./crawl ${IMAGE_REF} -version)"
output="$(docker run --rm --entrypoint ./crawl "${IMAGE_REF}" -version)"
if ! grep -qF "${CRAWL_TAG}" <<< "${output}"; then
echo "❌ Unexpected crawl version:"
echo "${output}"
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/build-and-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ jobs:
permissions:
contents: read
packages: write
env:
CRAWL_TAG: "0.34.0"
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand All @@ -30,8 +28,7 @@ jobs:
ghcr.io/treyturner/dcss
docker.io/treyturner/dcss
forgejo.treyturner.info/treyturner/dcss
upstream-ref: v${{ inputs.upstream-ref && inputs.upstream-ref || env.CRAWL_TAG }}
cache-scope: main
upstream-ref: ${{ inputs.upstream-ref }}

- name: Test
uses: ./.github/actions/test
Expand Down
5 changes: 0 additions & 5 deletions .github/workflows/build-and-test-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
env:
CRAWL_TAG: "0.34.0"
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand All @@ -20,9 +18,6 @@ jobs:
uses: ./.github/actions/build
with:
label: ${{ format('pr{0}', github.event.pull_request.number) }}
upstream-ref: v${{ env.CRAWL_TAG }}
cache-scope: ${{ github.head_ref }}
cache-fallback-scope: main

- name: Test
uses: ./.github/actions/test
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/promote-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
workflow_dispatch:
inputs:
release-version:
description: "Targeted release version tag (e.g. 'v0.34.0')"
description: "Targeted release version tag (e.g. '0.34.1')"
type: string
required: true
promote-latest:
Expand All @@ -29,8 +29,8 @@ jobs:
RELEASE_VERSION: ${{ inputs.release-version }}
PROMOTE_LATEST: ${{ inputs.promote-latest }}
run: |
if ! [[ "$RELEASE_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::RELEASE_VERSION must match v<digit>.<digit>.<digit> (e.g. v0.34.0)"
if ! [[ "$RELEASE_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::RELEASE_VERSION must match <digit>.<digit>.<digit> (e.g. 0.34.1)"
exit 1
fi
source_tag="${RELEASE_VERSION}-dev"
Expand Down
22 changes: 14 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1.7

ARG CRAWL_TAG=0.34.0
ARG CRAWL_TAG

###########
# BUILDER #
Expand All @@ -14,20 +14,29 @@ ARG CRAWL_TAG \
RUN --mount=type=cache,target=/var/cache/apk \
--mount=type=cache,target=/root/.cache/pip \
apk add \
curl \
g++ \
gcc \
git \
jq \
libpng-dev \
make \
ncurses-dev \
perl \
&& pip install pyyaml

RUN mkdir /build \
RUN set -eux \
&& if [ -z "${CRAWL_TAG:-}" ]; then \
CRAWL_TAG=$(curl -fsSL \
"https://api.github.com/repos/crawl/crawl/releases/latest" \
| jq -r '.tag_name'); \
fi \
&& printf '%s' "${CRAWL_TAG}" > /tmp/crawl-tag \
&& mkdir /build \
&& git clone ${CRAWL_REPO} --depth 1 /build/crawl \
&& cd /build/crawl \
&& git fetch origin tag ${CRAWL_TAG} --no-tags \
&& git checkout tags/${CRAWL_TAG} -b ${CRAWL_TAG} \
&& git fetch origin tag "${CRAWL_TAG}" --no-tags \
&& git checkout tags/"${CRAWL_TAG}" -b "${CRAWL_TAG}" \
&& git submodule update --init

RUN cd /build/crawl/crawl-ref/source \
Expand All @@ -44,8 +53,7 @@ RUN --mount=type=cache,target=/root/.cache/pip \

FROM python:3.13-alpine AS runtime

ARG CRAWL_TAG

COPY --from=builder /tmp/crawl-tag /app/crawl-tag
COPY --from=builder /build/crawl/crawl-ref/source/ /app/source/
COPY --from=builder /build/crawl/crawl-ref/settings/ /app/settings/
COPY --from=builder /build/crawl/crawl-ref/docs/ /app/docs/
Expand All @@ -61,8 +69,6 @@ RUN pip install --no-cache-dir --no-deps /wheels/*.whl \

COPY --chmod=+x entrypoint.sh /app/entrypoint.sh

ENV CRAWL_TAG=${CRAWL_TAG}

VOLUME ["/data"]

ENTRYPOINT ["/app/entrypoint.sh"]
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Packages the open source turn-based CRPG [Dungeon Crawl Stone Soup](https://craw

Images are published to Docker Hub, GitHub Container Registry, and Forgejo:

- `docker.io/treyturner/dcss`
- `ghcr.io/treyturner/dcss`
- `forgejo.treyturner.info/treyturner/dcss`
- `docker.io/treyturner/dcss`

## Quick Start

Expand All @@ -22,12 +22,10 @@ Every push to `main` builds and publishes a **dev** image. When ready, a dev ima

| Tag | Description |
| --- | --- |
| `v<version>-dev` | Development build from `main` (e.g. `v0.34.0-dev`) |
| `v<version>` | Stable release promoted from the corresponding dev tag (e.g. `v0.34.0`) |
| `<version>-dev` | Development build from `main` (e.g. `0.34.1-dev`) |
| `<version>` | Stable release promoted from the corresponding dev tag (e.g. `0.34.1`) |
| `latest` | Points to the most recent stable release |

Each CI run also produces a unique tag for traceability: `v<version>-dev-<run_id>.<attempt>`.

## Configuration

Runtime configuration is handled through environment variables. At container startup, the entrypoint generates the server's `config.yml` and `games.d/base.yaml` from these values.
Expand Down Expand Up @@ -173,10 +171,10 @@ docker run -d \
To build the image locally:

```sh
docker build --build-arg CRAWL_TAG=0.34.0 -t dcss .
docker build --build-arg CRAWL_TAG=0.34.1 -t dcss .
```

| Build Argument | Default | Description |
| --- | --- | --- |
| `CRAWL_REPO` | `https://github.com/crawl/crawl` | Git repository to clone |
| `CRAWL_TAG` | `0.34.0` | Version tag to build; appears in the lobby UI |
| `CRAWL_TAG` | _(latest upstream)_ | Version tag to build; appears in the lobby UI |
1 change: 1 addition & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ set -e
############

DCSS_DATA="${DCSS_DATA:-/data}"
CRAWL_TAG="${CRAWL_TAG:-$(cat /app/crawl-tag)}"

## Server
DCSS_BIND_PORT="${DCSS_BIND_PORT:-8080}"
Expand Down