Skip to content

Build and push custom Docker images #44

Build and push custom Docker images

Build and push custom Docker images #44

name: Build and push custom Docker images
on:
workflow_dispatch:
inputs:
repository-owner:
description: The owner of the VMaNGOS code repository to use
default: vmangos
required: true
type: string
repository-name:
description: The name of the VMaNGOS code repository to use
default: core
required: true
type: string
revision:
description: The VMaNGOS code repository revision to use
default: development
required: true
type: string
client-version:
description: The client version for which to build VMaNGOS
default: 5875
required: true
type: number
world-db-repository-owner:
description: The owner of the VMaNGOS world database repository to use
default: brotalnia
required: true
type: string
world-db-repository-name:
description: The name of the VMaNGOS world database repository to use
default: database
required: true
type: string
world-db-dump-name:
description: The name of the VMaNGOS world database dump to use
default: world_full_14_june_2021
required: true
type: string
patches-repository-url:
description: (Optional) A URL to a repository that contains patches to apply to the VMaNGOS code (patches have to end in `.patch` and be located in the root of the repository)
required: false
type: string
custom-name:
description: (Optional) A custom name to use as part of the image tags (when provided, this overrides the default `{ owner }-{ repository }-{ revision }` naming scheme)
required: false
type: string
build-aarch64-images:
description: Build `aarch64` images (if unchecked, only `x86_64` images will be built)
default: true
type: boolean
env:
REGISTRY: ghcr.io
IMAGE_NAME_SERVER: ${{ github.repository_owner }}/vmangos-server-custom
IMAGE_NAME_DATABASE: ${{ github.repository_owner }}/vmangos-database-custom
OCI_ANNOTATION_AUTHORS: ${{ vars.OCI_ANNOTATION_AUTHORS || github.repository_owner }}
OCI_ANNOTATION_URL: https://github.com/${{ github.repository }}
OCI_ANNOTATION_DOCUMENTATION: https://github.com/${{ github.repository }}/blob/master/README.md
OCI_ANNOTATION_SOURCE: https://github.com/${{ github.repository }}
OCI_ANNOTATION_VENDOR: ${{ vars.OCI_ANNOTATION_VENDOR || github.repository_owner }}
OCI_ANNOTATION_LICENSES: GPL-2.0
OCI_ANNOTATION_SERVER_TITLE: vmangos-deploy - Custom VMaNGOS server image
OCI_ANNOTATION_SERVER_DESCRIPTION: VMaNGOS is a server emulator supporting versions 1.6.1 to 1.12.1.
OCI_ANNOTATION_SERVER_BASE_NAME: ubuntu:24.04
OCI_ANNOTATION_DATABASE_TITLE: vmangos-deploy - Custom VMaNGOS database image
OCI_ANNOTATION_DATABASE_DESCRIPTION: Database for the VMaNGOS server emulator.
OCI_ANNOTATION_DATABASE_BASE_NAME: mariadb:11.4
jobs:
setup:
name: Setup
runs-on: ubuntu-24.04
steps:
# If the original MariaDB entrypoint script changes, we can't guarantee
# that our custom version (which relies on functions defined in the
# original) will still work, so we fail the workflow run at this point.
- name: Check if MariaDB entrypoint script has been updated
id: mariadb-entrypoint-check
run: |
known_entrypoint=https://raw.githubusercontent.com/MariaDB/mariadb-docker/64252135052f269ed2bb57134ad73537e93b7ab6/11.4/docker-entrypoint.sh
latest_entrypoint=https://raw.githubusercontent.com/MariaDB/mariadb-docker/master/11.4/docker-entrypoint.sh
curl -o known-entrypoint.sh $known_entrypoint
curl -o latest-entrypoint.sh $latest_entrypoint
diff known-entrypoint.sh latest-entrypoint.sh
build-and-push-server-images:
name: Build and push server images
needs: setup
runs-on: ubuntu-24.04
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up QEMU
if: ${{ inputs.build-aarch64-images == 'true' }}
uses: docker/setup-qemu-action@v3
# Work around QEMU 7.x compilation issues by explicitly using 8.x,
# which is not yet the default for the action.
# See https://github.com/tonistiigi/binfmt/issues/215
with:
image: tonistiigi/binfmt:qemu-v8.1.5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Generate tags
uses: actions/github-script@v7
id: generate-tags
env:
IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_SERVER }}
REPOSITORY_OWNER: ${{ inputs.repository-owner }}
REPOSITORY_NAME: ${{ inputs.repository-name }}
REVISION: ${{ inputs.revision }}
CLIENT_VERSION: ${{ inputs.client-version }}
CUSTOM_NAME: ${{ inputs.custom-name }}
with:
result-encoding: string
script: |
const tags = []
if (process.env.CUSTOM_NAME.trim() !== '') {
tags.push(`${process.env.IMAGE}:${process.env.CUSTOM_NAME}-${process.env.CLIENT_VERSION}`)
return tags.join(',')
}
tags.push(`${process.env.IMAGE}:${process.env.REPOSITORY_OWNER}-${process.env.REPOSITORY_NAME}-${process.env.REVISION}-${process.env.CLIENT_VERSION}`)
return tags.join(',')
# See https://github.com/opencontainers/image-spec/blob/main/annotations.md
- name: Generate OCI annotations
uses: actions/github-script@v7
id: generate-annotations
env:
IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_SERVER }}
REPOSITORY_OWNER: ${{ inputs.repository-owner }}
REPOSITORY_NAME: ${{ inputs.repository-name }}
REVISION: ${{ inputs.revision }}
CLIENT_VERSION: ${{ inputs.client-version }}
CUSTOM_NAME: ${{ inputs.custom-name }}
BUILD_AARCH64_IMAGES: ${{ inputs.build-aarch64-images }}
with:
result-encoding: string
script: |
const refName = process.env.CUSTOM_NAME.trim() !== ''
? `${process.env.IMAGE}:${process.env.CUSTOM_NAME}-${process.env.CLIENT_VERSION}`
: `${process.env.IMAGE}:${process.env.REPOSITORY_OWNER}-${process.env.REPOSITORY_NAME}-${process.env.REVISION}-${process.env.CLIENT_VERSION}`
const annotations = [
{ key: 'created', value: new Date().toISOString() },
{ key: 'authors', envKey: 'OCI_ANNOTATION_AUTHORS' },
{ key: 'url', envKey: 'OCI_ANNOTATION_URL' },
{ key: 'documentation', envKey: 'OCI_ANNOTATION_DOCUMENTATION' },
{ key: 'source', envKey: 'OCI_ANNOTATION_SOURCE' },
{ key: 'vendor', envKey: 'OCI_ANNOTATION_VENDOR' },
{ key: 'licenses', envKey: 'OCI_ANNOTATION_LICENSES' },
{ key: 'ref.name', value: refName },
{ key: 'title', envKey: 'OCI_ANNOTATION_SERVER_TITLE' },
{ key: 'description', envKey: 'OCI_ANNOTATION_SERVER_DESCRIPTION' },
{ key: 'base.name', envKey: 'OCI_ANNOTATION_SERVER_BASE_NAME' },
].map(({ key, value, envKey }) => {
const resolvedValue = value ?? process.env[envKey] ?? ''
const prefixes = ['manifest:']
if (process.env.BUILD_AARCH64_IMAGES === 'true') prefixes.push('index:')
return prefixes.map(prefix => `${prefix}org.opencontainers.image.${key}=${resolvedValue}`)
})
.flat()
.join('\n')
return annotations
- name: Build and push images
uses: docker/build-push-action@v6
with:
context: .
platforms: ${{ inputs.build-aarch64-images == 'true' && 'linux/amd64, linux/arm64' || 'linux/amd64' }}
file: ./docker/server/Dockerfile
push: true
provenance: false
build-args: |
VMANGOS_REPOSITORY_OWNER=${{ inputs.repository-owner }}
VMANGOS_REPOSITORY_NAME=${{ inputs.repository-name }}
VMANGOS_REVISION=${{ inputs.revision }}
VMANGOS_CLIENT_VERSION=${{ inputs.client-version }}
VMANGOS_PATCHES_REPOSITORY_URL=${{ inputs.patches-repository-url }}
tags: ${{ steps.generate-tags.outputs.result }}
annotations: ${{ steps.generate-annotations.outputs.result }}
# Since the database image builds only take a few minutes (and therefore
# always complete before the server image builds), we need to build after the
# server images; otherwise, we would push new database images without knowing
# if the server image builds will succeed (and if there is, e.g., a
# compilation error due to a bug upstream we would end up with a version
# mismatch between the latest database images and the latest server images).
build-and-push-database-images:
name: Build and push database images
needs: [setup, build-and-push-server-images]
runs-on: ubuntu-24.04
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up QEMU
if: ${{ inputs.build-aarch64-images == 'true' }}
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Generate tags
uses: actions/github-script@v7
id: generate-tags
env:
IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_DATABASE }}
REPOSITORY_OWNER: ${{ inputs.repository-owner }}
REPOSITORY_NAME: ${{ inputs.repository-name }}
REVISION: ${{ inputs.revision }}
CUSTOM_NAME: ${{ inputs.custom-name }}
with:
result-encoding: string
script: |
const tags = []
if (process.env.CUSTOM_NAME.trim() !== '') {
tags.push(`${process.env.IMAGE}:${process.env.CUSTOM_NAME}`)
return tags.join(',')
}
tags.push(`${process.env.IMAGE}:${process.env.REPOSITORY_OWNER}-${process.env.REPOSITORY_NAME}-${process.env.REVISION}`)
return tags.join(',')
# See https://github.com/opencontainers/image-spec/blob/main/annotations.md
- name: Generate OCI annotations
uses: actions/github-script@v7
id: generate-annotations
env:
IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_DATABASE }}
REPOSITORY_OWNER: ${{ inputs.repository-owner }}
REPOSITORY_NAME: ${{ inputs.repository-name }}
REVISION: ${{ inputs.revision }}
CUSTOM_NAME: ${{ inputs.custom-name }}
BUILD_AARCH64_IMAGES: ${{ inputs.build-aarch64-images }}
with:
result-encoding: string
script: |
const refName = process.env.CUSTOM_NAME.trim() !== ''
? `${process.env.IMAGE}:${process.env.CUSTOM_NAME}`
: `${process.env.IMAGE}:${process.env.REPOSITORY_OWNER}-${process.env.REPOSITORY_NAME}-${process.env.REVISION}`
const annotations = [
{ key: 'created', value: new Date().toISOString() },
{ key: 'authors', envKey: 'OCI_ANNOTATION_AUTHORS' },
{ key: 'url', envKey: 'OCI_ANNOTATION_URL' },
{ key: 'documentation', envKey: 'OCI_ANNOTATION_DOCUMENTATION' },
{ key: 'source', envKey: 'OCI_ANNOTATION_SOURCE' },
{ key: 'vendor', envKey: 'OCI_ANNOTATION_VENDOR' },
{ key: 'licenses', envKey: 'OCI_ANNOTATION_LICENSES' },
{ key: 'ref.name', value: refName },
{ key: 'title', envKey: 'OCI_ANNOTATION_DATABASE_TITLE' },
{ key: 'description', envKey: 'OCI_ANNOTATION_DATABASE_DESCRIPTION' },
{ key: 'base.name', envKey: 'OCI_ANNOTATION_DATABASE_BASE_NAME' },
].map(({ key, value, envKey }) => {
const resolvedValue = value ?? process.env[envKey] ?? ''
const prefixes = ['manifest:']
if (process.env.BUILD_AARCH64_IMAGES === 'true') prefixes.push('index:')
return prefixes.map(prefix => `${prefix}org.opencontainers.image.${key}=${resolvedValue}`)
})
.flat()
.join('\n')
return annotations
- name: Build and push images
uses: docker/build-push-action@v6
with:
context: .
platforms: ${{ inputs.build-aarch64-images == 'true' && 'linux/amd64, linux/arm64' || 'linux/amd64' }}
file: ./docker/database/Dockerfile
push: true
provenance: false
build-args: |
VMANGOS_REPOSITORY_OWNER=${{ inputs.repository-owner }}
VMANGOS_REPOSITORY_NAME=${{ inputs.repository-name }}
VMANGOS_REVISION=${{ inputs.revision }}
VMANGOS_WORLD_DB_REPOSITORY_OWNER=${{ inputs.world-db-repository-owner }}
VMANGOS_WORLD_DB_REPOSITORY_NAME=${{ inputs.world-db-repository-name }}
VMANGOS_WORLD_DB_DUMP_NAME=${{ inputs.world-db-dump-name }}
tags: ${{ steps.generate-tags.outputs.result }}
annotations: ${{ steps.generate-annotations.outputs.result }}