Skip to content

Commit 3ee56eb

Browse files
authored
ci(release): setup docker multi-arch build (#49)
1 parent 4a5d19b commit 3ee56eb

File tree

11 files changed

+129
-53
lines changed

11 files changed

+129
-53
lines changed

.github/renovate.json5

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,11 @@
5858

5959
// Matchers
6060
fileMatch: [
61-
'src\\/build\\/get-papermc-server\\.sh$',
62-
'.github\\/semantic-release\\/release\\.sh$'
61+
'(^|\\/)docker-bake\\.hcl$'
6362
],
6463
matchStrings: [
6564
// cf. https://regex101.com/r/SLgTRk
66-
'# renovate: datasource=papermc\\s+MINECRAFT_VERSION=["\']?(?<currentValue>.+?)["\']?\\s'
65+
'# renovate: datasource=papermc\\s+variable "MINECRAFT_VERSION" {\\s+default = "(?<currentValue>.+?)"\\s+}'
6766
]
6867
}
6968
]

.github/semantic-release/release.sh

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,26 @@
22

33
set -Eeuo pipefail
44

5-
NEXT_RELEASE_VERSION=$1
6-
NEXT_RELEASE_CHANNEL=${2:-default}
5+
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P)
76

8-
# Extract <major>.<minor> part of the SemVer version
9-
NEXT_RELEASE_MAJOR_MINOR_VERSION="${NEXT_RELEASE_VERSION%".${NEXT_RELEASE_VERSION#*.*.}"}"
10-
# Extract <major> part of the SemVer version
11-
NEXT_RELEASE_MAJOR_VERSION="${NEXT_RELEASE_MAJOR_MINOR_VERSION%.*}"
7+
RELEASE_VERSION=$1
8+
RELEASE_CHANNEL=${2:-'default'}
129

13-
# renovate: datasource=papermc
14-
MINECRAFT_VERSION='1.21.4'
15-
16-
IMAGE_NAME=djaytan/papermc-server
17-
IMAGE_BUILD_CONTEXT_DIR="$ROOT_PROJECT_DIR/src"
18-
19-
docker info
20-
docker build --platform=linux/amd64,linux/arm64 --tag "$IMAGE_NAME" "$IMAGE_BUILD_CONTEXT_DIR"
21-
22-
# Docker tag format: <mc-version>-v<image-version>-<timestamp-YYYYMMDD>
23-
docker tag "$IMAGE_NAME" "$IMAGE_NAME:$MINECRAFT_VERSION"
24-
docker tag "$IMAGE_NAME" "$IMAGE_NAME:$MINECRAFT_VERSION-v$NEXT_RELEASE_VERSION"
25-
docker tag "$IMAGE_NAME" "$IMAGE_NAME:$MINECRAFT_VERSION-v$NEXT_RELEASE_MAJOR_MINOR_VERSION"
26-
docker tag "$IMAGE_NAME" "$IMAGE_NAME:$MINECRAFT_VERSION-v$NEXT_RELEASE_MAJOR_VERSION"
27-
docker tag "$IMAGE_NAME" "$IMAGE_NAME:$MINECRAFT_VERSION-v$NEXT_RELEASE_VERSION-$(date +%Y%m%d)"
10+
export REGISTRY='docker.io'
11+
export BUILD_CONTEXT="$SCRIPT_DIR"
12+
export IMAGE_VERSION="$RELEASE_VERSION"
2813

2914
# The default channel binds to the default Git branch (i.e. "main")
3015
# If we release from "main" branch -> we add the "latest" tag
31-
if [[ "$NEXT_RELEASE_CHANNEL" == 'default' ]]; then
32-
docker tag "$IMAGE_NAME" "$IMAGE_NAME:latest"
16+
IS_LATEST_RELEASE="$([ "$RELEASE_CHANNEL" == 'default' ] && echo 'true' || echo 'false')"
17+
export IS_LATEST_RELEASE
18+
19+
if [[ -z "$ROOT_PROJECT_DIR" ]]; then
20+
echo 'Error: environment variable "ROOT_PROJECT_DIR" is not set.'
21+
exit 1
3322
fi
3423

35-
docker push --all-tags "$IMAGE_NAME"
24+
cd "$ROOT_PROJECT_DIR/src"
25+
26+
docker buildx bake release --print
27+
docker buildx bake release --push

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ on:
1111

1212
permissions: {}
1313

14+
# TODO: rework CI - Use the test.sh script and rely on the generated tag
15+
# TODO: fail if container run fails
16+
# TODO: do we want to test multi-arch build?
17+
# TODO: what about cache?
1418
jobs:
1519
build-and-test:
1620
name: Build & Test
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
name: Release
22

3+
# TODO: frequent releases (once per week or at push time)
34
on:
45
workflow_dispatch:
56

@@ -43,6 +44,7 @@ jobs:
4344
production.cloudflare.docker.com:443
4445
archive.ubuntu.com:80
4546
security.ubuntu.com:80
47+
ports.ubuntu.com:80
4648
api.papermc.io:443
4749
api.nuget.org:443
4850
registry.npmjs.org:443
@@ -72,8 +74,10 @@ jobs:
7274

7375
# Setup of QEMU x Buildx
7476
# Required for multi-arch builds (typically for ARM architecture support)
77+
# TODO: rely on native ARM64 native node instead of QEMU: https://docs.docker.com/build/ci/github-actions/multi-platform/
7578
- name: Set up QEMU
7679
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
80+
7781
- name: Set up Docker Buildx
7882
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
7983

src/Dockerfile

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@
1616

1717
FROM docker.io/ubuntu:noble@sha256:72297848456d5d37d1262630108ab308d3e9ec7ed1c3286a32fe09856619a782 AS build
1818

19+
ARG MINECRAFT_VERSION
20+
21+
RUN if [[ -z "$MINECRAFT_VERSION" ]]; then \
22+
echo "Error: MINECRAFT_VERSION argument is not set." >&2; \
23+
exit 1; \
24+
fi
25+
26+
RUN echo "Building PaperMC server for Minecraft version: $MINECRAFT_VERSION"
27+
1928
WORKDIR /build
2029

2130
# Install required dependencies
@@ -27,7 +36,7 @@ RUN apt-get update && \
2736

2837
# Retrieve latest Paper server for the given version
2938
COPY --chmod=500 build/get-papermc-server.sh .
30-
RUN ./get-papermc-server.sh
39+
RUN ./get-papermc-server.sh "$MINECRAFT_VERSION"
3140

3241
FROM docker.io/eclipse-temurin:21-jre-noble@sha256:3ef64ec531571987f58ccc90bd3d7f92950539f1baa00a5c45b660d6faccf37d
3342

@@ -56,6 +65,7 @@ WORKDIR /home/papermc
5665
COPY --from=build --chown=papermc --chmod=500 /build/papermc-server-*.jar ./
5766

5867
# Copy license file
68+
# TODO: rely on named build context instead: https://docs.docker.com/build/concepts/context/#named-contexts
5969
ADD --chmod=444 https://raw.githubusercontent.com/Djaytan/docker-papermc-server/refs/heads/main/LICENSE.md .
6070

6171
# Copy the configuration files

src/build.sh

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/build/get-papermc-server.sh

100644100755
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
#!/usr/bin/env bash
22
# Reference: https://docs.papermc.io/misc/downloads-api
33

4-
# renovate: datasource=papermc
5-
MINECRAFT_VERSION='1.21.4'
4+
MINECRAFT_VERSION=$1
65

76
LATEST_BUILD=$(curl -sSf "https://api.papermc.io/v2/projects/paper/versions/${MINECRAFT_VERSION}/builds" | \
87
jq -r '.builds | map(select(.channel == "default") | .build) | .[-1]')

src/docker-bake.hcl

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# ========== VARIABLES ========== #
2+
3+
# General properties
4+
variable "REGISTRY" {
5+
default = ""
6+
}
7+
variable "IMAGE_NAME" {
8+
# TODO: make organization configurable
9+
default = "djaytan/papermc-server"
10+
}
11+
12+
# Tags properties
13+
variable "IS_LATEST_RELEASE" {
14+
default = false
15+
}
16+
# renovate: datasource=papermc
17+
variable "MINECRAFT_VERSION" {
18+
default = "1.21.4"
19+
}
20+
variable "IMAGE_VERSION" {
21+
default = "$IMAGE_VERSION"
22+
}
23+
24+
# ========== FUNCTIONS ========== #
25+
26+
function "tag" {
27+
params = [tag]
28+
result = "${notequal(REGISTRY, "") ? "${REGISTRY}/" : ""}${IMAGE_NAME}:${tag}"
29+
}
30+
31+
function "extractMajorFromSemVer" {
32+
params = [semver]
33+
result = split(".", semver)[0]
34+
}
35+
36+
function "extractMajorMinorFromSemVer" {
37+
params = [semver]
38+
result = "${split(".", semver)[0]}.${split(".", semver)[1]}"
39+
}
40+
41+
function "date" {
42+
params = []
43+
result = formatdate("YYYYMMDD", timestamp())
44+
}
45+
46+
# ========== TARGETS ========== #
47+
48+
target "dev" {
49+
description = "Builds the image for development purposes."
50+
args {
51+
MINECRAFT_VERSION = "${MINECRAFT_VERSION}"
52+
}
53+
tags = [
54+
tag("dev")
55+
]
56+
}
57+
58+
target "release" {
59+
description = "Builds the image for production purposes."
60+
args {
61+
MINECRAFT_VERSION = "${MINECRAFT_VERSION}"
62+
}
63+
platforms = ["linux/amd64", "linux/arm64"]
64+
pull = true
65+
no-cache = true
66+
# Docker tag format: <mc-version>-v<image-version>-<timestamp-YYYYMMDD>
67+
tags = [
68+
equal(IS_LATEST_RELEASE, true) ? tag("latest") : "", # Optional latest tag (empty string = no tag)
69+
tag("${MINECRAFT_VERSION}"),
70+
tag("${MINECRAFT_VERSION}-v${IMAGE_VERSION}"),
71+
tag("${MINECRAFT_VERSION}-v${IMAGE_VERSION}-${date()}"),
72+
tag("${MINECRAFT_VERSION}-v${extractMajorMinorFromSemVer(IMAGE_VERSION)}"),
73+
tag("${MINECRAFT_VERSION}-v${extractMajorFromSemVer(IMAGE_VERSION)}")
74+
]
75+
# TODO: annotations => https://github.com/opencontainers/image-spec/blob/main/annotations.md (or at Dockerfile level maybe?)
76+
# TODO: what about labels?
77+
}

src/run.sh

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/runtime/start.sh

100644100755
File mode changed.

0 commit comments

Comments
 (0)