name: Build and Push Docker Image on: push: branches: [ main, master ] tags: [ 'v*', 'release-*' ] workflow_dispatch: {} env: DOCKERFILE: Dockerfile jobs: docker: runs-on: docker container: image: docker:27-cli services: docker: image: docker:27-dind options: --privileged env: DOCKER_TLS_CERTDIR: "" steps: - name: Checkout (git) env: GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} run: | set -eu apk add --no-cache git ca-certificates TOKEN="${GITEA_TOKEN:-${REGISTRY_TOKEN:-}}" REF="$GITHUB_REF" REPO_URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" if echo "$REF" | grep -q '^refs/heads/'; then NAME=${REF#refs/heads/} if [ -n "$TOKEN" ]; then git -c http.extraHeader="Authorization: Bearer $TOKEN" clone --depth 1 --branch "$NAME" "$REPO_URL" . else git clone --depth 1 --branch "$NAME" "$REPO_URL" . fi elif echo "$REF" | grep -q '^refs/tags/'; then NAME=${REF#refs/tags/} if [ -n "$TOKEN" ]; then git -c http.extraHeader="Authorization: Bearer $TOKEN" clone --depth 1 --branch "$NAME" "$REPO_URL" . else git clone --depth 1 --branch "$NAME" "$REPO_URL" . fi else if [ -n "$TOKEN" ]; then git -c http.extraHeader="Authorization: Bearer $TOKEN" clone --depth 1 "$REPO_URL" . else git clone --depth 1 "$REPO_URL" . fi git fetch --depth 1 origin "$GITHUB_SHA" git checkout --detach "$GITHUB_SHA" fi - name: Define Registry Variables id: vars env: IMAGE_NAME_VAR: ${{ vars.IMAGE_NAME }} GITEA_REGISTRY_VAR: ${{ vars.GITEA_REGISTRY }} IMAGE_NAMESPACE_VAR: ${{ vars.IMAGE_NAMESPACE }} run: | set -eu # Derive registry/namespace/image from environment provided by runner # GITHUB_REPOSITORY is like "owner/repo" OWNER=${GITHUB_REPOSITORY%%/*} REPO=${GITHUB_REPOSITORY#*/} OWNER=$(echo "$OWNER" | tr '[:upper:]' '[:lower:]') REPO=$(echo "$REPO" | tr '[:upper:]' '[:lower:]') # Optionally override namespace (owner) to push to personal or different namespace if [ -n "${IMAGE_NAMESPACE_VAR:-}" ]; then OWNER=$(echo "$IMAGE_NAMESPACE_VAR" | tr '[:upper:]' '[:lower:]') fi # Allow overriding image name via repository variable IMAGE_NAME; default to repo name IMAGE_NAME="$IMAGE_NAME_VAR" if [ -z "$IMAGE_NAME" ]; then IMAGE_NAME="$REPO"; fi IMAGE_NAME=$(echo "$IMAGE_NAME" | tr '[:upper:]' '[:lower:]') # Prefer explicit var GITEA_REGISTRY; else, use the same host as server URL if [ -n "${GITEA_REGISTRY_VAR:-}" ]; then # Strip protocol and any path if mistakenly provided REGISTRY=$(echo "$GITEA_REGISTRY_VAR" | sed -E 's#^https?://##; s#/.*$##; s#/$##') else # GITHUB_SERVER_URL like https://gitea.example.com REGISTRY=$(echo "$GITHUB_SERVER_URL" | sed -E 's#^https?://##; s#/$##') fi echo "registry=$REGISTRY" >> "$GITHUB_OUTPUT" echo "owner=$OWNER" >> "$GITHUB_OUTPUT" echo "image=$IMAGE_NAME" >> "$GITHUB_OUTPUT" - name: Compute Tags id: tags env: REGISTRY: ${{ steps.vars.outputs.registry }} OWNER: ${{ steps.vars.outputs.owner }} IMAGE: ${{ steps.vars.outputs.image }} run: | set -eu IMAGE_FULL="$REGISTRY/$OWNER/$IMAGE" REF="$GITHUB_REF" SHA_SHORT=$(echo "$GITHUB_SHA" | cut -c1-8) TAGS="" case "$REF" in refs/heads/*) BRANCH=${REF#refs/heads/} # latest for main/master if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then TAGS="${TAGS} latest" fi # branch tag SAFE_BRANCH=$(echo "$BRANCH" | tr '/' '-' ) TAGS="${TAGS} ${SAFE_BRANCH}" ;; refs/tags/*) TAG=${REF#refs/tags/} TAGS="${TAGS} ${TAG}" ;; esac # always include short sha TAGS="${TAGS} ${SHA_SHORT}" # Build -t args TAG_ARGS="" for t in $TAGS; do TAG_ARGS="$TAG_ARGS -t $IMAGE_FULL:$t" done echo "image_full=$IMAGE_FULL" >> "$GITHUB_OUTPUT" echo "tag_args=$TAG_ARGS" >> "$GITHUB_OUTPUT" - name: Log in to Gitea Registry env: REGISTRY: ${{ steps.vars.outputs.registry }} REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} run: | set -eu USER_NAME="${REGISTRY_USERNAME:-$GITHUB_ACTOR}" echo "Logging into $REGISTRY as $USER_NAME" if echo "$REGISTRY" | grep -q '^https\?://'; then REG_HOST="$REGISTRY"; else REG_HOST="$REGISTRY"; fi if ! echo "$REGISTRY_TOKEN" | docker login "$REG_HOST" -u "$USER_NAME" --password-stdin; then echo "First login attempt failed, trying with explicit /v2/ endpoint" echo "$REGISTRY_TOKEN" | docker login "https://$REGISTRY/v2/" -u "$USER_NAME" --password-stdin fi - name: Ensure buildx builder run: | set -eu docker buildx inspect dindbuilder >/dev/null 2>&1 || docker buildx create --name dindbuilder --driver docker-container --use - name: Build and push (linux/amd64) env: DOCKERFILE: ${{ env.DOCKERFILE }} IMAGE_FULL: ${{ steps.tags.outputs.image_full }} TAG_ARGS: ${{ steps.tags.outputs.tag_args }} run: | set -eu echo "Building $IMAGE_FULL with tags: $TAG_ARGS" docker buildx build \ --platform linux/amd64 \ -f "$DOCKERFILE" \ $TAG_ARGS \ --cache-from type=registry,ref="$IMAGE_FULL:buildcache" \ --cache-to type=registry,ref="$IMAGE_FULL:buildcache",mode=max \ --push \ .