diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml index b8d8eed..f8de6aa 100644 --- a/.github/actions/build/action.yml +++ b/.github/actions/build/action.yml @@ -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 @@ -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" @@ -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} @@ -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' \ @@ -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<> "$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}" diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml index 02ba53f..e9846cb 100644 --- a/.github/actions/test/action.yml +++ b/.github/actions/test/action.yml @@ -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 @@ -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}" diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index a48aec3..4323c9e 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -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 @@ -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 diff --git a/.github/workflows/build-and-test-pr.yml b/.github/workflows/build-and-test-pr.yml index 16ce980..438f46c 100644 --- a/.github/workflows/build-and-test-pr.yml +++ b/.github/workflows/build-and-test-pr.yml @@ -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 @@ -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 diff --git a/.github/workflows/promote-tag.yml b/.github/workflows/promote-tag.yml index 21b885e..fa49a86 100644 --- a/.github/workflows/promote-tag.yml +++ b/.github/workflows/promote-tag.yml @@ -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: @@ -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.. (e.g. v0.34.0)" + if ! [[ "$RELEASE_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::RELEASE_VERSION must match .. (e.g. 0.34.1)" exit 1 fi source_tag="${RELEASE_VERSION}-dev" diff --git a/Dockerfile b/Dockerfile index 141f822..530ac5c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1.7 -ARG CRAWL_TAG=0.34.0 +ARG CRAWL_TAG ########### # BUILDER # @@ -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 \ @@ -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/ @@ -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"] diff --git a/README.md b/README.md index b0a6cfb..ea1443d 100644 --- a/README.md +++ b/README.md @@ -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 @@ -22,12 +22,10 @@ Every push to `main` builds and publishes a **dev** image. When ready, a dev ima | Tag | Description | | --- | --- | -| `v-dev` | Development build from `main` (e.g. `v0.34.0-dev`) | -| `v` | Stable release promoted from the corresponding dev tag (e.g. `v0.34.0`) | +| `-dev` | Development build from `main` (e.g. `0.34.1-dev`) | +| `` | 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-dev-.`. - ## 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. @@ -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 | diff --git a/entrypoint.sh b/entrypoint.sh index 7f68c73..5f00966 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -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}"