name: Build and Push Docker Image run-name: ${{ gitea.actor }} builds and pushes image on: workflow_call: inputs: registry: description: Container registry hostname (defaults to secret REGISTRY) type: string default: "" image_name: description: Full image name including registry (defaults to REGISTRY/repo) type: string default: "" dockerfile: description: Path to Dockerfile type: string default: Dockerfile context: description: Build context type: string default: . push: description: Push image after build type: boolean default: true secrets: REGISTRY: description: Container registry hostname required: false REGISTRY_USERNAME: description: Registry username required: true REGISTRY_PASSWORD: description: Registry password or token required: true jobs: build-and-push: runs-on: ubuntu-latest permissions: contents: read packages: write env: REGISTRY: ${{ inputs.registry != '' && inputs.registry || secrets.REGISTRY }} IMAGE_NAME: ${{ inputs.image_name }} REPO: ${{ gitea.repository }} steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Resolve image name run: | if [ -z "${IMAGE_NAME}" ]; then IMAGE_NAME="${REGISTRY}/${REPO}" fi echo "IMAGE_NAME=${IMAGE_NAME}" >> "$GITHUB_ENV" - name: Log in to Gitea Container Registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} - name: Validate registry configuration run: | if [ -z "${REGISTRY}" ]; then echo "::error::REGISTRY secret is missing or empty" exit 1 fi if [ -z "${IMAGE_NAME}" ] || [[ "${IMAGE_NAME}" == */ ]]; then echo "::error::IMAGE_NAME is empty or malformed (resolved to '${IMAGE_NAME}')" exit 1 fi - name: Derive image tags id: vars run: | IMAGE="${IMAGE_NAME}" TAG_NAME="" REF="${GITHUB_REF:-${GITEA_REF}}" SHA="${GITHUB_SHA:-${GITEA_SHA}}" BRANCH="" SHORT_SHA="$(git rev-parse --short=7 "${SHA}")" TAGS=() # Extract tag name when we are on a tag ref (e.g. v1.4) if [[ "${REF}" =~ refs/tags/(.+) ]]; then TAG_NAME="${BASH_REMATCH[1]}" fi if [[ "${REF}" =~ refs/heads/(.+) ]]; then BRANCH="${BASH_REMATCH[1]}" else # Tag build: detect which branch contains the tagged commit git fetch --no-tags --depth=1 origin main release develop || true if git branch -r --contains "${SHA}" | grep -q "origin/main"; then BRANCH="main" elif git branch -r --contains "${SHA}" | grep -q "origin/release"; then BRANCH="release" elif git branch -r --contains "${SHA}" | grep -q "origin/develop"; then BRANCH="develop" fi fi TAGS+=("${IMAGE}:${SHORT_SHA}") [[ -n "${TAG_NAME}" ]] && TAGS+=("${IMAGE}:${TAG_NAME}") case "${BRANCH}" in main) TAGS+=("${IMAGE}:latest") ;; release*) TAGS+=("${IMAGE}:latest-rc") ;; develop) TAGS+=("${IMAGE}:latest-dev") ;; *) TAGS+=("${IMAGE}:latest-snapshot") ;; esac echo "Computed tags:" printf '%s\n' "${TAGS[@]}" { echo "tags<> "$GITHUB_OUTPUT" - name: Show build summary run: | echo "Commit: ${GITHUB_SHA:-${GITEA_SHA}}" echo "Image: ${IMAGE_NAME}" echo "Tags:" printf '%s\n' "${{ steps.vars.outputs.tags }}" - name: Determine deploy target id: deploy run: | REF="${GITHUB_REF:-${GITEA_REF}}" SHA="${GITHUB_SHA:-${GITEA_SHA}}" TARGET="dev" if [[ "${REF}" == "refs/heads/main" ]]; then TARGET="prod" elif [[ "${REF}" =~ refs/tags/ ]]; then # Tag builds deploy to prod only if the tagged commit is in main git fetch --no-tags --depth=1 origin main || true if git branch -r --contains "${SHA}" | grep -q "origin/main"; then TARGET="prod" fi fi echo "Deploy target: ${TARGET}" echo "target=${TARGET}" >> "$GITHUB_OUTPUT" - name: Build and push image uses: docker/build-push-action@v5 with: context: ${{ inputs.context }} file: ${{ inputs.dockerfile }} push: ${{ inputs.push }} tags: ${{ steps.vars.outputs.tags }} build-args: | VITE_KEYCLOAK_URL=${{ vars.VITE_KEYCLOAK_URL }} VITE_KEYCLOAK_REALM=${{ vars.VITE_KEYCLOAK_REALM }} VITE_KEYCLOAK_CLIENT_ID=${{ vars.VITE_KEYCLOAK_CLIENT_ID }}