Build and publish / Test and build (darwin) (push) Successful in 2m4s
Build and publish / Test and build (linux) (push) Successful in 3m3s
Build and publish / Test and build (windows) (push) Successful in 2m50s
Build and publish / Build and publish Docker image (push) Successful in 2m4s
A set-but-empty environment variable wiped the corresponding .env value, so an EMBY_SERVER_URL='' guard on CI broke the config tests. Empty variables now count as unset, and the tests clear the config env keys explicitly for hermeticity.
214 lines
7.8 KiB
YAML
214 lines
7.8 KiB
YAML
name: Build and publish
|
|
|
|
on:
|
|
push:
|
|
branches: ['**']
|
|
tags: ['v*']
|
|
pull_request:
|
|
workflow_dispatch:
|
|
|
|
env:
|
|
CGO_ENABLED: '0'
|
|
|
|
jobs:
|
|
binaries:
|
|
name: Test and build (${{ matrix.goos }})
|
|
runs-on: ${{ matrix.runner }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- runner: macos
|
|
goos: darwin
|
|
- runner: ubuntu-latest
|
|
goos: linux
|
|
- runner: windows
|
|
goos: windows
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
steps:
|
|
- name: Checkout (macOS/Linux)
|
|
if: matrix.goos != 'windows'
|
|
uses: https://github.com/actions/checkout@v4
|
|
with:
|
|
persist-credentials: false
|
|
# The Windows self-hosted runner fails while starting the Node-based
|
|
# checkout action. The repository is public, so use Git directly there.
|
|
- name: Checkout (Windows)
|
|
if: matrix.goos == 'windows'
|
|
env:
|
|
GIT_SERVER_URL: ${{ gitea.server_url }}
|
|
GIT_REPOSITORY: ${{ gitea.repository }}
|
|
GIT_SHA: ${{ gitea.sha }}
|
|
run: |
|
|
git init .
|
|
git config core.autocrlf false
|
|
git remote add origin "${GIT_SERVER_URL}/${GIT_REPOSITORY}.git"
|
|
git fetch --depth=1 origin "$GIT_SHA"
|
|
git checkout --detach FETCH_HEAD
|
|
- uses: https://github.com/actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: false
|
|
- name: Check formatting
|
|
run: |
|
|
files=$(gofmt -l .)
|
|
if [ -n "$files" ]; then
|
|
printf 'Run gofmt on:\n%s\n' "$files"
|
|
exit 1
|
|
fi
|
|
- name: Vet
|
|
run: go vet ./...
|
|
- name: Unit tests
|
|
run: go test ./...
|
|
- name: Build and package
|
|
env:
|
|
GOOS: ${{ matrix.goos }}
|
|
run: |
|
|
for arch in amd64 arm64; do
|
|
package="emby-mcp-${GOOS}-${arch}"
|
|
binary=emby-mcp
|
|
if [ "$GOOS" = windows ]; then binary=emby-mcp.exe; fi
|
|
mkdir -p "dist/$package"
|
|
GOARCH="$arch" go build -trimpath -ldflags='-s -w' -o "dist/$package/$binary" ./cmd/emby-mcp
|
|
cp README.md LICENCE.md "dist/$package/"
|
|
tar -czf "dist/$package.tar.gz" -C dist "$package"
|
|
done
|
|
# v3 uses the artifact API supported by older Gitea installations too.
|
|
- uses: https://github.com/actions/upload-artifact@v3
|
|
with:
|
|
name: emby-mcp-${{ matrix.goos }}
|
|
path: dist/*.tar.gz
|
|
if-no-files-found: error
|
|
|
|
docker:
|
|
name: Build and publish Docker image
|
|
needs: binaries
|
|
runs-on: ubuntu-latest
|
|
container:
|
|
options: >-
|
|
--volume /certs/client:/certs/client:ro
|
|
--add-host=docker:host-gateway
|
|
env:
|
|
DOCKER_CONFIG: /tmp/emby-mcp-docker-config
|
|
# The act_runner service's environment is not inherited by job
|
|
# containers, so explicitly target the sibling Docker-in-Docker service.
|
|
DOCKER_HOST: tcp://docker:2376
|
|
DOCKER_TLS_VERIFY: '1'
|
|
DOCKER_CERT_PATH: /certs/client
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
steps:
|
|
- name: Verify Docker daemon access
|
|
run: |
|
|
for certificate in ca.pem cert.pem key.pem; do
|
|
if [ ! -r "$DOCKER_CERT_PATH/$certificate" ] || [ ! -s "$DOCKER_CERT_PATH/$certificate" ]; then
|
|
echo "Missing Docker TLS file: $DOCKER_CERT_PATH/$certificate" >&2
|
|
echo 'The runner must allow /certs/client in container.valid_volumes.' >&2
|
|
echo 'Mount the DinD client certs into the runner container.' >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
docker version
|
|
- uses: https://github.com/actions/checkout@v4
|
|
with:
|
|
persist-credentials: false
|
|
- name: Image metadata
|
|
id: image
|
|
env:
|
|
REPOSITORY: ${{ gitea.repository }}
|
|
COMMIT_SHA: ${{ gitea.sha }}
|
|
REF: ${{ gitea.ref }}
|
|
EVENT_NAME: ${{ gitea.event_name }}
|
|
DEFAULT_BRANCH: ${{ gitea.event.repository.default_branch }}
|
|
run: |
|
|
image="git.i3omb.com/$(printf '%s' "$REPOSITORY" | tr '[:upper:]' '[:lower:]')"
|
|
publish=false
|
|
tags="$image:sha-$COMMIT_SHA"
|
|
if [ "$EVENT_NAME" = push ]; then
|
|
if [ "$REF" = "refs/heads/$DEFAULT_BRANCH" ]; then
|
|
publish=true
|
|
tags="$tags,$image:latest"
|
|
elif [[ "$REF" == refs/tags/v* ]]; then
|
|
tag="${REF#refs/tags/}"
|
|
if [[ ! "$tag" =~ ^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$ ]]; then
|
|
echo 'Version tag is not a valid Docker tag'
|
|
exit 1
|
|
fi
|
|
publish=true
|
|
tags="$tags,$image:$tag"
|
|
fi
|
|
fi
|
|
echo "publish=$publish" >> "$GITHUB_OUTPUT"
|
|
echo "tags=$tags" >> "$GITHUB_OUTPUT"
|
|
echo "go_version=$(awk '$1 == "go" { print $2 }' go.mod)" >> "$GITHUB_OUTPUT"
|
|
- name: Log in to Gitea registry
|
|
if: steps.image.outputs.publish == 'true'
|
|
env:
|
|
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
|
|
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
|
run: |
|
|
printf '%s' "$REGISTRY_TOKEN" | docker login git.i3omb.com \
|
|
--username "$REGISTRY_USERNAME" --password-stdin
|
|
- name: Install Docker Buildx when unavailable
|
|
env:
|
|
BUILDX_VERSION: v0.16.2
|
|
run: |
|
|
if ! docker buildx version >/dev/null 2>&1; then
|
|
mkdir -p "$DOCKER_CONFIG/cli-plugins"
|
|
case "$(uname -m)" in
|
|
x86_64) buildx_arch=amd64 ;;
|
|
aarch64|arm64) buildx_arch=arm64 ;;
|
|
*) echo "Unsupported runner architecture: $(uname -m)" >&2; exit 1 ;;
|
|
esac
|
|
curl -fsSL \
|
|
"https://github.com/docker/buildx/releases/download/${BUILDX_VERSION}/buildx-${BUILDX_VERSION}.linux-${buildx_arch}" \
|
|
-o "$DOCKER_CONFIG/cli-plugins/docker-buildx"
|
|
chmod +x "$DOCKER_CONFIG/cli-plugins/docker-buildx"
|
|
fi
|
|
docker buildx version
|
|
- name: Build image with Docker Buildx
|
|
env:
|
|
IMAGE_TAGS: ${{ steps.image.outputs.tags }}
|
|
PUBLISH: ${{ steps.image.outputs.publish }}
|
|
GO_VERSION: ${{ steps.image.outputs.go_version }}
|
|
SOURCE_LABEL: ${{ gitea.server_url }}/${{ gitea.repository }}
|
|
REVISION_LABEL: ${{ gitea.sha }}
|
|
CI_RUN_ID: ${{ gitea.run_id }}
|
|
CI_RUN_ATTEMPT: ${{ gitea.run_attempt }}
|
|
run: |
|
|
docker buildx version
|
|
# Buildx requires a named context when the Docker endpoint uses TLS.
|
|
docker context create emby-mcp-dind --docker \
|
|
"host=$DOCKER_HOST,ca=$DOCKER_CERT_PATH/ca.pem,cert=$DOCKER_CERT_PATH/cert.pem,key=$DOCKER_CERT_PATH/key.pem"
|
|
builder_name="emby-mcp-${CI_RUN_ID}-${CI_RUN_ATTEMPT:-1}"
|
|
docker buildx create --name "$builder_name" --driver docker-container --use emby-mcp-dind
|
|
trap 'docker buildx rm --force "$builder_name" >/dev/null 2>&1 || true' EXIT
|
|
docker buildx inspect "$builder_name" --bootstrap
|
|
|
|
tag_args=()
|
|
IFS=',' read -ra tags <<< "$IMAGE_TAGS"
|
|
for tag in "${tags[@]}"; do
|
|
tag_args+=(--tag "$tag")
|
|
done
|
|
|
|
push_args=()
|
|
if [ "$PUBLISH" = true ]; then
|
|
push_args+=(--push)
|
|
else
|
|
# Validate pull-request and branch builds without exporting an image.
|
|
push_args+=(--output=type=cacheonly)
|
|
fi
|
|
|
|
docker buildx build \
|
|
--builder "$builder_name" \
|
|
--platform linux/amd64,linux/arm64 \
|
|
--build-arg "GO_VERSION=$GO_VERSION" \
|
|
--label "org.opencontainers.image.source=$SOURCE_LABEL" \
|
|
--label "org.opencontainers.image.revision=$REVISION_LABEL" \
|
|
"${tag_args[@]}" \
|
|
"${push_args[@]}" \
|
|
.
|