Files
LambdaMail/.gitea/workflows/release.yml
T
Lucas RayanandClaude Sonnet 5.5 59363734ff
CI / Lint de idioma (R9) (push) Successful in 4s
CI / Go (protocols) (push) Failing after 5s
CI / TypeScript (auth) (push) Failing after 6s
CI / TypeScript (storage) (push) Successful in 12s
CI / Build (webmail) (push) Successful in 1m38s
CI / Stack completa (push) Skipped
CI / Trivy (dependências, segredos e Dockerfiles) (push) Failing after 1m32s
CI / Imagem (auth) (push) Failing after 11s
CI / Imagem (migrations) (push) Failing after 11s
CI / Imagem (protocols) (push) Failing after 11s
CI / Imagem (rspamd) (push) Failing after 11s
CI / Imagem (storage) (push) Failing after 11s
CI / Imagem (webmail) (push) Failing after 11s
ci: publish images to the Gitea registry, use the gitea context
Release now pushes to git.lucasrguerra.dev.br instead of ghcr.io, tags each
architecture separately (no artifact upload, no gha cache) and joins them with
imagetools. GITHUB_OUTPUT and GITHUB_STEP_SUMMARY stay: they are the runner's
own interface and the GITEA_* equivalents are not set.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-30 08:48:44 -03:00

163 lines
6.0 KiB
YAML

name: Release
# Publishes the service images to the Gitea container registry after a merge
# into main, and again under semver tags when a v* tag is pushed. The deploy
# host only pulls, so nothing has to be built on the server. Needs the user
# secret REGISTRY_TOKEN (a Gitea token with the write:package scope).
on:
push:
branches: [main]
tags: ['v*']
workflow_dispatch:
concurrency:
group: release
cancel-in-progress: false
env:
REGISTRY: git.lucasrguerra.dev.br
jobs:
# Nothing is published unless the full suite passes first.
ci:
uses: ./.gitea/workflows/ci.yml
# Registry paths must be lowercase, and this repository is "lucasrguerra/LambdaMail".
# Lowercasing gitea.repository here keeps the workflow fork-safe instead of
# hardcoding the owner.
prepare:
name: Namespace das imagens
runs-on: ubuntu-latest
outputs:
namespace: ${{ steps.namespace.outputs.value }}
steps:
- id: namespace
# GITHUB_OUTPUT is the runner's own interface: Gitea sets it under that name.
run: |
repo='${{ gitea.repository }}'
echo "value=${repo,,}" >> "$GITHUB_OUTPUT"
# Each architecture is built on a runner of its own kind. QEMU emulation
# would also work, but it makes the Go and Next builds roughly an order of
# magnitude slower.
build:
name: Build ${{ matrix.service }} (${{ matrix.platform }})
needs: [ci, prepare]
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
# Both are axes, so this is a cross product: four services on two
# architectures is eight jobs. Declaring platform only under `include`
# would not multiply anything - include can add keys to existing
# combinations, but it cannot create the combinations themselves.
service: [protocols, auth, storage, webmail, migrations, rspamd]
platform: [linux/amd64, linux/arm64]
include:
- platform: linux/amd64
runner: linux-amd64
arch: amd64
- platform: linux/arm64
runner: ubuntu-24.04-arm
arch: arm64
steps:
- uses: actions/checkout@v7
- uses: docker/setup-buildx-action@v4
- name: Autentica no registro
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ gitea.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Metadados
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.REGISTRY }}/${{ needs.prepare.outputs.namespace }}/${{ matrix.service }}
# Each architecture is pushed under its own tag (no digest artifacts: they
# are not portable to Gitea). The final tags are attached later, once both
# exist and can be joined into a single manifest list.
- name: Build e push por arquitetura
id: build
uses: docker/build-push-action@v7
with:
context: ${{ (matrix.service == 'migrations' || matrix.service == 'rspamd') && '.' || format('services/{0}', matrix.service) }}
file: services/${{ matrix.service }}/Dockerfile
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
push: true
tags: ${{ env.REGISTRY }}/${{ needs.prepare.outputs.namespace }}/${{ matrix.service }}:build-${{ gitea.sha }}-${{ matrix.arch }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ needs.prepare.outputs.namespace }}/${{ matrix.service }}:buildcache-${{ matrix.arch }}
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ needs.prepare.outputs.namespace }}/${{ matrix.service }}:buildcache-${{ matrix.arch }},mode=max
publish:
name: Publica ${{ matrix.service }}
needs: [build, prepare]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
service: [protocols, auth, storage, webmail, migrations, rspamd]
steps:
- uses: actions/checkout@v7
- uses: docker/setup-buildx-action@v4
- name: Autentica no registro
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ gitea.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
# `latest` is what compose pulls. The semver tags only materialise on a
# v* tag push and make it possible to pin or roll back to an exact
# release; the sha tag does the same for any main build.
- name: Metadados
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.REGISTRY }}/${{ needs.prepare.outputs.namespace }}/${{ matrix.service }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest
type=sha,format=long
# Joins both architectures under one manifest list, so `docker pull`
# resolves to the right one automatically.
- name: Cria o manifesto multi-arquitetura
run: |
image='${{ env.REGISTRY }}/${{ needs.prepare.outputs.namespace }}/${{ matrix.service }}'
docker buildx imagetools create \
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< '${{ steps.meta.outputs.json }}') \
"$image:build-${{ gitea.sha }}-amd64" "$image:build-${{ gitea.sha }}-arm64"
- name: Confere o resultado
run: |
docker buildx imagetools inspect \
"${{ env.REGISTRY }}/${{ needs.prepare.outputs.namespace }}/${{ matrix.service }}:latest" \
--format '{{json .Manifest}}' \
| jq -r '.manifests[] | select(.platform.os == "linux") | "\(.platform.os)/\(.platform.architecture)"'
- name: Resumo
run: |
{
echo "### ${{ matrix.service }} publicado (linux/amd64 e linux/arm64)"
echo
echo '```'
echo "${{ steps.meta.outputs.tags }}"
echo '```'
} >> "$GITHUB_STEP_SUMMARY"