CI / Lint de idioma (R9) (push) Successful in 10s
CI / Go (protocols) (push) Failing after 31s
CI / TypeScript (auth) (push) Failing after 37s
CI / TypeScript (storage) (push) Successful in 23s
CI / Build (webmail) (push) Successful in 1m47s
CI / Stack completa (push) Skipped
CI / Trivy (dependências, segredos e Dockerfiles) (push) Failing after 3m8s
CI / Imagem (auth) (push) Canceled after 3m32s
CI / Imagem (migrations) (push) Canceled after 2m4s
CI / Imagem (protocols) (push) Canceled after 48s
CI / Imagem (rspamd) (push) Canceled after 48s
CI / Imagem (storage) (push) Canceled after 0s
CI / Imagem (webmail) (push) Canceled after 0s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
168 lines
6.3 KiB
YAML
168 lines
6.3 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
|
|
|
|
# The only runner is arm64; linux/amd64 is built under QEMU emulation
|
|
# (label linux-amd64 points at the same runner), so it is slower.
|
|
- uses: docker/setup-qemu-action@v3
|
|
if: matrix.arch == 'amd64'
|
|
|
|
- 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"
|