Gitea copy: $uicide Music Bot — image, Unraid template, CI, publishing
Build and Test / Build and Test (push) Canceled after 1m24s

Fork of purnell569/MusicBot 0.7.1 (JMusicBot), kept here as a reliable
copy with a container image built and served from this Gitea.

- README retitled "$uicide Music Bot"; lineage table, Gitea image, Unraid
  and release instructions. Nothing under src/ changes.
- Dockerfile: Maven stage on $BUILDPLATFORM (JAR is arch-neutral, so no
  QEMU for the build), OCI labels point at this repo and record commit and
  version via GIT_SHA/VERSION build args.
- docker/entrypoint.sh: check the data dir is writable up front (the bot's
  own error for that is a misleading "another instance is running"), and
  on a missing config.txt run the bot's generate-config and stop with
  instructions instead of prompting on a console that does not exist.
- deploy/unraid/musicbot.xml: Unraid template, --user 99:100 default.
- .gitea/workflows/build-and-test.yml: mvn verify + docker build on push;
  its presence makes Gitea ignore the GitHub-only workflows in .github/.
- scripts/build-and-publish-unraid.sh + docs/PUBLISHING.md: release
  runbook (keychain-safe registry push, release with zipped JAR).
- docker-compose.example.yml points at the Gitea image.

Upstream's v0.7.1 tag is preserved as upstream/v0.7.1; this repository's
own release tag v0.7.1 is on this commit.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
Miles WardandClaude Fable 5.1 committed 2026-09-17 19:19:59 -04:00
1 parent 9991962e86
commit e772eb7c2b
8 files changed
+731 -249

No files matched your search

+120
View File
@@ -0,0 +1,120 @@
#!/usr/bin/env bash
# build-and-publish-unraid.sh — build the $uicide Music Bot image and push it
# to the Gitea container registry, ready to pull from an Unraid template.
#
# Run this on any host that can reach Gitea and has Docker. It clones a fresh
# copy rather than building the working tree, so what ships is exactly what is
# committed.
#
# Inputs (env vars, all optional except GITEA_TOKEN):
# GITEA_TOKEN personal access token with `write:package` scope
# GITEA_HOST default: gitea.milesward.dev
# GITEA_OWNER default: mward4
# GITEA_REPO default: MusicBot
# IMAGE_NAME default: musicbot
# IMAGE_TAG default: 0.7.1 (also pushed as :latest)
# PLATFORM default: linux/amd64 (Unraid is x86_64)
# GIT_REF default: v0.7.1 (tag/branch to build)
# WORKDIR default: /tmp/musicbot-build (removed on exit)
#
# After this, set the Unraid template's Repository to:
# <GITEA_HOST>/<owner>/musicbot:<tag> (or :latest)
set -euo pipefail
GITEA_HOST=${GITEA_HOST:-gitea.milesward.dev}
GITEA_OWNER=${GITEA_OWNER:-mward4}
GITEA_REPO=${GITEA_REPO:-MusicBot}
IMAGE_NAME=${IMAGE_NAME:-musicbot}
IMAGE_TAG=${IMAGE_TAG:-0.7.1}
PLATFORM=${PLATFORM:-linux/amd64}
GIT_REF=${GIT_REF:-v0.7.1}
WORKDIR=${WORKDIR:-/tmp/musicbot-build}
# OCI distribution rejects uppercase repository paths, so the image name is
# lowercased independently of the repo name.
IMAGE_NAME="$(printf '%s' "$IMAGE_NAME" | tr '[:upper:]' '[:lower:]')"
FULL_TAG="$GITEA_HOST/$GITEA_OWNER/$IMAGE_NAME:$IMAGE_TAG"
LATEST_TAG="$GITEA_HOST/$GITEA_OWNER/$IMAGE_NAME:latest"
if [[ -z "${GITEA_TOKEN:-}" ]]; then
echo "ERROR: set GITEA_TOKEN to a token with write:package scope." >&2
echo " Gitea -> Settings -> Applications -> Generate New Token." >&2
exit 2
fi
for tool in git docker; do
command -v "$tool" >/dev/null 2>&1 \
|| { echo "ERROR: '$tool' not found in PATH" >&2; exit 2; }
done
# A private docker config so the token never lands in ~/.docker/config.json.
# The trap wipes it (and the checkout) on any exit path.
#
# The auth is written into the file directly rather than via `docker login`.
# With an empty config the CLI falls back to the platform credential helper,
# and on macOS `docker-credential-osxkeychain` shares its keychain item with
# git's `osxkeychain` helper: `login` then fails with -25299 if git already
# stored the token, and `logout` deletes the credential git was using. A
# config that already contains an `auths` entry skips the helper entirely.
DOCKER_CONFIG="$(mktemp -d)"
export DOCKER_CONFIG
trap 'rm -rf "$DOCKER_CONFIG" "$WORKDIR"' EXIT
# Colima keeps its socket outside /var/run; an isolated DOCKER_CONFIG has no
# `currentContext`, so point at the daemon explicitly when one is not set.
if [[ -z "${DOCKER_HOST:-}" && -S "$HOME/.colima/default/docker.sock" ]]; then
export DOCKER_HOST="unix://$HOME/.colima/default/docker.sock"
fi
echo
echo "==> Workspace : $WORKDIR"
echo "==> Gitea host : $GITEA_HOST"
echo "==> Building ref : $GIT_REF"
echo "==> Image to push : $FULL_TAG"
echo "==> Platform : $PLATFORM"
echo
# Step 1: shallow clone of the exact ref.
rm -rf "$WORKDIR"
git -c "http.extraHeader=Authorization: token $GITEA_TOKEN" \
clone --depth 1 --branch "$GIT_REF" \
"https://$GITEA_HOST/$GITEA_OWNER/$GITEA_REPO.git" "$WORKDIR"
cd "$WORKDIR"
GIT_SHA="$(git rev-parse HEAD)"
COMMIT_TIME="$(git log -1 --format=%cI)"
# Step 2: build. --pull so a stale cached base image doesn't bake in a CVE
# that upstream has already fixed. --provenance/--sbom off because Unraid's
# Docker cannot load the attestation manifests BuildKit attaches by default.
#
# The Maven stage runs on the builder's native architecture (the JAR is
# architecture-neutral); only the jlink and runtime stages run under emulation
# when cross-building linux/amd64 on an arm64 host. BUILD_TIMESTAMP pins the
# JAR's reproducible-build timestamp to the commit, as upstream's CI does.
docker build \
--pull \
--platform "$PLATFORM" \
--provenance=false --sbom=false \
--build-arg "GIT_SHA=$GIT_SHA" \
--build-arg "VERSION=$IMAGE_TAG" \
--build-arg "BUILD_TIMESTAMP=$COMMIT_TIME" \
--tag "$FULL_TAG" \
--tag "$LATEST_TAG" \
.
# Step 3: registry auth, written straight into the private config (see above).
printf '{"auths":{"%s":{"auth":"%s"}}}' "$GITEA_HOST" \
"$(printf '%s:%s' "$GITEA_OWNER" "$GITEA_TOKEN" | base64 | tr -d '\n')" \
> "$DOCKER_CONFIG/config.json"
# Step 4: push both tags. The trap removes the config, so there is no logout.
docker push "$FULL_TAG"
docker push "$LATEST_TAG"
echo
echo "==> Done. Pull from an Unraid template with:"
echo " $FULL_TAG"
echo " $LATEST_TAG"
echo