Merge ci/gitea-registry: publish to the Gitea registry, workflows on Gitea Actions
CI / TypeScript (auth) (push) Successful in 2m53s
CI / Trivy (dependências, segredos e Dockerfiles) (push) Successful in 1m8s
Release / Namespace das imagens (push) Successful in 1s
CI / Lint de idioma (R9) (push) Successful in 4s
CI / TypeScript (storage) (push) Successful in 14s
CI / Go (protocols) (push) Successful in 3m16s
CI / Imagem (auth) (push) Successful in 1m0s
CI / Build (webmail) (push) Successful in 2m15s
CI / Imagem (migrations) (push) Successful in 26s
CI / Imagem (rspamd) (push) Successful in 27s
CI / Imagem (protocols) (push) Successful in 1m32s
CI / Imagem (storage) (push) Successful in 1m19s
CI / Imagem (webmail) (push) Successful in 3m31s
CI / Stack completa (push) Successful in 3m42s
Release / ci (push) Successful in 11m19s
Release / Build migrations (linux/amd64) (push) Successful in 2m12s
Release / Build auth (linux/amd64) (push) Successful in 4m25s
Release / Build rspamd (linux/amd64) (push) Successful in 42s
Release / Build storage (linux/amd64) (push) Successful in 2m47s
Release / Build protocols (linux/amd64) (push) Successful in 12m49s
Release / Build auth (linux/arm64) (push) Successful in 43s
Release / Build migrations (linux/arm64) (push) Successful in 28s
Release / Build protocols (linux/arm64) (push) Successful in 1m29s
Release / Build rspamd (linux/arm64) (push) Successful in 33s
Release / Build storage (linux/arm64) (push) Successful in 42s
Release / Build webmail (linux/arm64) (push) Successful in 2m43s
Release / Build webmail (linux/amd64) (push) Successful in 21m34s
Release / Publica auth (push) Successful in 22s
Release / Publica migrations (push) Successful in 22s
Release / Publica rspamd (push) Successful in 21s
Release / Publica protocols (push) Successful in 21s
Release / Publica webmail (push) Successful in 21s
Release / Publica storage (push) Successful in 21s
CI / TypeScript (auth) (push) Successful in 2m53s
CI / Trivy (dependências, segredos e Dockerfiles) (push) Successful in 1m8s
Release / Namespace das imagens (push) Successful in 1s
CI / Lint de idioma (R9) (push) Successful in 4s
CI / TypeScript (storage) (push) Successful in 14s
CI / Go (protocols) (push) Successful in 3m16s
CI / Imagem (auth) (push) Successful in 1m0s
CI / Build (webmail) (push) Successful in 2m15s
CI / Imagem (migrations) (push) Successful in 26s
CI / Imagem (rspamd) (push) Successful in 27s
CI / Imagem (protocols) (push) Successful in 1m32s
CI / Imagem (storage) (push) Successful in 1m19s
CI / Imagem (webmail) (push) Successful in 3m31s
CI / Stack completa (push) Successful in 3m42s
Release / ci (push) Successful in 11m19s
Release / Build migrations (linux/amd64) (push) Successful in 2m12s
Release / Build auth (linux/amd64) (push) Successful in 4m25s
Release / Build rspamd (linux/amd64) (push) Successful in 42s
Release / Build storage (linux/amd64) (push) Successful in 2m47s
Release / Build protocols (linux/amd64) (push) Successful in 12m49s
Release / Build auth (linux/arm64) (push) Successful in 43s
Release / Build migrations (linux/arm64) (push) Successful in 28s
Release / Build protocols (linux/arm64) (push) Successful in 1m29s
Release / Build rspamd (linux/arm64) (push) Successful in 33s
Release / Build storage (linux/arm64) (push) Successful in 42s
Release / Build webmail (linux/arm64) (push) Successful in 2m43s
Release / Build webmail (linux/amd64) (push) Successful in 21m34s
Release / Publica auth (push) Successful in 22s
Release / Publica migrations (push) Successful in 22s
Release / Publica rspamd (push) Successful in 21s
Release / Publica protocols (push) Successful in 21s
Release / Publica webmail (push) Successful in 21s
Release / Publica storage (push) Successful in 21s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
0ff9aaaf88
11 files changed
+150
-135
No files matched your search
+2
-2
@@ -1,10 +1,10 @@
|
||||
# --- Container images ---
|
||||
# Published to GHCR by .github/workflows/release.yml, multi-architecture
|
||||
# Published to the Gitea registry by .gitea/workflows/release.yml, multi-architecture
|
||||
# (linux/amd64 and linux/arm64). The deploy host pulls these instead of
|
||||
# compiling: `docker compose pull && docker compose up -d`. Running
|
||||
# `docker compose build` locally still overrides them with a local build.
|
||||
# Pin IMAGE_TAG to a released version (e.g. 1.2.3) or a sha- tag to roll back.
|
||||
IMAGE_NAMESPACE=ghcr.io/lucasrguerra/lambdamail
|
||||
IMAGE_NAMESPACE=git.lucasrguerra.dev.br/lucasrguerra/lambdamail
|
||||
IMAGE_TAG=latest
|
||||
|
||||
# --- Postgres ---
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
# and must be URL-safe - see the note above them.
|
||||
|
||||
# --- Container images -------------------------------------------------------
|
||||
# Published by .github/workflows/release.yml for linux/amd64 and linux/arm64.
|
||||
# Published by .gitea/workflows/release.yml for linux/amd64 and linux/arm64.
|
||||
# Pin IMAGE_TAG to a released version or a sha- tag to roll back.
|
||||
IMAGE_NAMESPACE=ghcr.io/lucasrguerra/lambdamail
|
||||
IMAGE_NAMESPACE=git.lucasrguerra.dev.br/lucasrguerra/lambdamail
|
||||
IMAGE_TAG=latest
|
||||
|
||||
# --- Identity ---------------------------------------------------------------
|
||||
|
||||
@@ -15,7 +15,7 @@ on:
|
||||
workflow_call:
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.ref }}
|
||||
group: ci-${{ gitea.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -57,16 +57,30 @@ jobs:
|
||||
cache-dependency-path: services/protocols/go.sum
|
||||
- name: Run migrations
|
||||
run: |
|
||||
docker run --rm --network host \
|
||||
-v "$(pwd)/../../migrations:/migrations" \
|
||||
migrate/migrate:v4.17.1 \
|
||||
# The job's workspace is a volume of its own, invisible to the Docker
|
||||
# daemon the job talks to, so `-v "$PWD:..."` would mount an empty
|
||||
# directory. Files are copied into the container instead.
|
||||
cid=$(docker create --network host migrate/migrate:v4.17.1 \
|
||||
-path=/migrations \
|
||||
-database "postgres://lambdamail_test:lambdamail_test@localhost:5432/lambdamail_test?sslmode=disable" \
|
||||
up
|
||||
up)
|
||||
docker cp "$(pwd)/../../migrations/." "$cid:/migrations"
|
||||
docker start -a "$cid"
|
||||
status=$(docker inspect -f '{{.State.ExitCode}}' "$cid")
|
||||
docker rm "$cid" >/dev/null
|
||||
exit "$status"
|
||||
- run: go vet ./...
|
||||
- run: go test ./... -v
|
||||
# The end-to-end suites start an embedded Postgres, and initdb refuses to
|
||||
# run as root, which is what a job container is. Run the tests as a
|
||||
# throwaway unprivileged user (GitHub's hosted runners already are one).
|
||||
- name: Testes
|
||||
env:
|
||||
TEST_DATABASE_URL: postgres://lambdamail_test:lambdamail_test@localhost:5432/lambdamail_test?sslmode=disable
|
||||
run: |
|
||||
id tester >/dev/null 2>&1 || useradd -m -u 1001 tester
|
||||
chown -R tester:tester "$GITHUB_WORKSPACE"
|
||||
runuser -u tester -- env "HOME=/home/tester" "PATH=$PATH" \
|
||||
"TEST_DATABASE_URL=$TEST_DATABASE_URL" go test ./... -v
|
||||
|
||||
ts-auth:
|
||||
name: TypeScript (auth)
|
||||
@@ -97,12 +111,18 @@ jobs:
|
||||
# the database, so a mock would prove nothing.
|
||||
- name: Run migrations
|
||||
run: |
|
||||
docker run --rm --network host \
|
||||
-v "$(pwd)/../../migrations:/migrations" \
|
||||
migrate/migrate:v4.17.1 \
|
||||
# The job's workspace is a volume of its own, invisible to the Docker
|
||||
# daemon the job talks to, so `-v "$PWD:..."` would mount an empty
|
||||
# directory. Files are copied into the container instead.
|
||||
cid=$(docker create --network host migrate/migrate:v4.17.1 \
|
||||
-path=/migrations \
|
||||
-database "postgres://lambdamail_test:lambdamail_test@localhost:5432/lambdamail_test?sslmode=disable" \
|
||||
up
|
||||
up)
|
||||
docker cp "$(pwd)/../../migrations/." "$cid:/migrations"
|
||||
docker start -a "$cid"
|
||||
status=$(docker inspect -f '{{.State.ExitCode}}' "$cid")
|
||||
docker rm "$cid" >/dev/null
|
||||
exit "$status"
|
||||
- run: npm install
|
||||
- run: npm run lint
|
||||
- run: npm test
|
||||
@@ -148,14 +168,20 @@ jobs:
|
||||
# A mail server holds credentials for every mailbox it serves, so the
|
||||
# secret scanner matters as much as the vulnerability one here: a DKIM
|
||||
# key or a Cloudflare token committed by accident is a full compromise.
|
||||
#
|
||||
# Trivy runs from its official image rather than aquasecurity/trivy-action:
|
||||
# that action clones the Trivy repository from the workflow's own server,
|
||||
# which on Gitea is not GitHub.
|
||||
- name: Repositório
|
||||
uses: aquasecurity/trivy-action@v0.36.0
|
||||
with:
|
||||
scan-type: fs
|
||||
scanners: vuln,secret,misconfig
|
||||
severity: HIGH,CRITICAL
|
||||
exit-code: '1'
|
||||
skip-dirs: services/auth/node_modules,services/storage/node_modules,services/webmail/node_modules,services/webmail/.next
|
||||
run: |
|
||||
cid=$(docker create --network host -w /src aquasec/trivy:0.70.0 \
|
||||
fs --scanners vuln,secret,misconfig --severity HIGH,CRITICAL --exit-code 1 \
|
||||
--skip-dirs services/auth/node_modules,services/storage/node_modules,services/webmail/node_modules,services/webmail/.next .)
|
||||
docker cp . "$cid:/src"
|
||||
docker start -a "$cid"
|
||||
status=$(docker inspect -f '{{.State.ExitCode}}' "$cid")
|
||||
docker rm "$cid" >/dev/null
|
||||
exit "$status"
|
||||
|
||||
# MEDIUM is reported but does not fail the build.
|
||||
#
|
||||
@@ -168,13 +194,15 @@ jobs:
|
||||
# Reporting rather than gating, because failing on every MEDIUM makes the
|
||||
# scanner something people learn to skip.
|
||||
- name: Repositório (MEDIUM, informativo)
|
||||
uses: aquasecurity/trivy-action@v0.36.0
|
||||
with:
|
||||
scan-type: fs
|
||||
scanners: vuln,secret
|
||||
severity: MEDIUM
|
||||
exit-code: '0'
|
||||
skip-dirs: services/auth/node_modules,services/storage/node_modules,services/webmail/node_modules,services/webmail/.next
|
||||
run: |
|
||||
cid=$(docker create --network host -w /src aquasec/trivy:0.70.0 \
|
||||
fs --scanners vuln,secret --severity MEDIUM --exit-code 0 \
|
||||
--skip-dirs services/auth/node_modules,services/storage/node_modules,services/webmail/node_modules,services/webmail/.next .)
|
||||
docker cp . "$cid:/src"
|
||||
docker start -a "$cid"
|
||||
status=$(docker inspect -f '{{.State.ExitCode}}' "$cid")
|
||||
docker rm "$cid" >/dev/null
|
||||
exit "$status"
|
||||
|
||||
image:
|
||||
name: Imagem (${{ matrix.service }})
|
||||
@@ -198,8 +226,6 @@ jobs:
|
||||
push: false
|
||||
load: true
|
||||
tags: lambdamail-${{ matrix.service }}:ci
|
||||
cache-from: type=gha,scope=${{ matrix.service }}
|
||||
cache-to: type=gha,mode=max,scope=${{ matrix.service }}
|
||||
|
||||
# Scanned only for the images whose contents we author. migrations and
|
||||
# rspamd add .sql and .conf files to an upstream image and nothing else,
|
||||
@@ -209,11 +235,9 @@ jobs:
|
||||
# that their base images have to be watched.
|
||||
- name: Trivy na imagem
|
||||
if: matrix.service != 'migrations' && matrix.service != 'rspamd'
|
||||
uses: aquasecurity/trivy-action@v0.36.0
|
||||
with:
|
||||
image-ref: lambdamail-${{ matrix.service }}:ci
|
||||
severity: HIGH,CRITICAL
|
||||
exit-code: '1'
|
||||
run: |
|
||||
docker run --rm --network host -e DOCKER_HOST=tcp://127.0.0.1:2375 aquasec/trivy:0.70.0 \
|
||||
image --severity HIGH,CRITICAL --exit-code 1 lambdamail-${{ matrix.service }}:ci
|
||||
|
||||
compose-up:
|
||||
name: Stack completa
|
||||
@@ -1,8 +1,9 @@
|
||||
name: Release
|
||||
|
||||
# Publishes the four service images to GHCR 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.
|
||||
# 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]
|
||||
@@ -14,15 +15,15 @@ concurrency:
|
||||
cancel-in-progress: false
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
REGISTRY: git.lucasrguerra.dev.br
|
||||
|
||||
jobs:
|
||||
# Nothing is published unless the full suite passes first.
|
||||
ci:
|
||||
uses: ./.github/workflows/ci.yml
|
||||
uses: ./.gitea/workflows/ci.yml
|
||||
|
||||
# GHCR rejects an uppercase path, and this repository is "lucasrguerra/LambdaMail".
|
||||
# Lowercasing github.repository here keeps the workflow fork-safe instead of
|
||||
# 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
|
||||
@@ -31,7 +32,10 @@ jobs:
|
||||
namespace: ${{ steps.namespace.outputs.value }}
|
||||
steps:
|
||||
- id: namespace
|
||||
run: echo "value=${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT"
|
||||
# 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
|
||||
@@ -54,7 +58,7 @@ jobs:
|
||||
platform: [linux/amd64, linux/arm64]
|
||||
include:
|
||||
- platform: linux/amd64
|
||||
runner: ubuntu-latest
|
||||
runner: linux-amd64
|
||||
arch: amd64
|
||||
- platform: linux/arm64
|
||||
runner: ubuntu-24.04-arm
|
||||
@@ -62,14 +66,19 @@ jobs:
|
||||
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 GHCR
|
||||
- name: Autentica no registro
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
username: ${{ gitea.actor }}
|
||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||
|
||||
- name: Metadados
|
||||
id: meta
|
||||
@@ -77,9 +86,10 @@ jobs:
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ needs.prepare.outputs.namespace }}/${{ matrix.service }}
|
||||
|
||||
# Pushed by digest only: the tags are attached later, once both
|
||||
# architectures exist and can be joined into a single manifest list.
|
||||
- name: Build e push por digest
|
||||
# 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:
|
||||
@@ -87,26 +97,10 @@ jobs:
|
||||
file: services/${{ matrix.service }}/Dockerfile
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
outputs: type=image,name=${{ env.REGISTRY }}/${{ needs.prepare.outputs.namespace }}/${{ matrix.service }},push-by-digest=true,name-canonical=true,push=true
|
||||
cache-from: type=gha,scope=${{ matrix.service }}-${{ matrix.arch }}
|
||||
cache-to: type=gha,mode=max,scope=${{ matrix.service }}-${{ matrix.arch }}
|
||||
|
||||
- name: Exporta o digest
|
||||
run: |
|
||||
mkdir -p /tmp/digests
|
||||
# The output already carries the `sha256:` prefix; the file name must
|
||||
# not, since the merge step prepends it again.
|
||||
digest='${{ steps.build.outputs.digest }}'
|
||||
touch "/tmp/digests/${digest#sha256:}"
|
||||
|
||||
- name: Guarda o digest
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
# Slashes are not allowed in artifact names, hence the arch alias.
|
||||
name: digest-${{ matrix.service }}-${{ matrix.arch }}
|
||||
path: /tmp/digests/*
|
||||
retention-days: 1
|
||||
if-no-files-found: error
|
||||
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 }}
|
||||
@@ -124,19 +118,12 @@ jobs:
|
||||
|
||||
- uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Autentica no GHCR
|
||||
- name: Autentica no registro
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Recupera os digests
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: digest-${{ matrix.service }}-*
|
||||
merge-multiple: true
|
||||
path: /tmp/digests
|
||||
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
|
||||
@@ -156,11 +143,11 @@ jobs:
|
||||
# Joins both architectures under one manifest list, so `docker pull`
|
||||
# resolves to the right one automatically.
|
||||
- name: Cria o manifesto multi-arquitetura
|
||||
working-directory: /tmp/digests
|
||||
run: |
|
||||
image='${{ env.REGISTRY }}/${{ needs.prepare.outputs.namespace }}/${{ matrix.service }}'
|
||||
docker buildx imagetools create \
|
||||
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< '${{ steps.meta.outputs.json }}') \
|
||||
$(printf '${{ env.REGISTRY }}/${{ needs.prepare.outputs.namespace }}/${{ matrix.service }}@sha256:%s ' *)
|
||||
"$image:build-${{ gitea.sha }}-amd64" "$image:build-${{ gitea.sha }}-arm64"
|
||||
|
||||
- name: Confere o resultado
|
||||
run: |
|
||||
+6
-6
@@ -60,7 +60,7 @@ services:
|
||||
# probe - a health check on a container that is meant to stop would report
|
||||
# unhealthy exactly when it has done its job.
|
||||
migrate:
|
||||
image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/migrations:${IMAGE_TAG:-latest}
|
||||
image: ${IMAGE_NAMESPACE:-git.lucasrguerra.dev.br/lucasrguerra/lambdamail}/migrations:${IMAGE_TAG:-latest}
|
||||
# "latest" is a moving tag and Docker considers a tag it already holds
|
||||
# locally to be satisfied, so recreating this container silently reused
|
||||
# the cached image and the newly published one was never fetched: the
|
||||
@@ -80,7 +80,7 @@ services:
|
||||
|
||||
# ------------------------------------------------------------ RSPAMD
|
||||
rspamd:
|
||||
image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/rspamd:${IMAGE_TAG:-latest}
|
||||
image: ${IMAGE_NAMESPACE:-git.lucasrguerra.dev.br/lucasrguerra/lambdamail}/rspamd:${IMAGE_TAG:-latest}
|
||||
# "latest" is a moving tag and Docker considers a tag it already holds
|
||||
# locally to be satisfied, so recreating this container silently reused
|
||||
# the cached image and the newly published one was never fetched: the
|
||||
@@ -140,7 +140,7 @@ services:
|
||||
|
||||
# -------------------------------------------------------------- AUTH
|
||||
auth:
|
||||
image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/auth:${IMAGE_TAG:-latest}
|
||||
image: ${IMAGE_NAMESPACE:-git.lucasrguerra.dev.br/lucasrguerra/lambdamail}/auth:${IMAGE_TAG:-latest}
|
||||
# "latest" is a moving tag and Docker considers a tag it already holds
|
||||
# locally to be satisfied, so recreating this container silently reused
|
||||
# the cached image and the newly published one was never fetched: the
|
||||
@@ -178,7 +178,7 @@ services:
|
||||
|
||||
# ----------------------------------------------------------- STORAGE
|
||||
storage:
|
||||
image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/storage:${IMAGE_TAG:-latest}
|
||||
image: ${IMAGE_NAMESPACE:-git.lucasrguerra.dev.br/lucasrguerra/lambdamail}/storage:${IMAGE_TAG:-latest}
|
||||
# "latest" is a moving tag and Docker considers a tag it already holds
|
||||
# locally to be satisfied, so recreating this container silently reused
|
||||
# the cached image and the newly published one was never fetched: the
|
||||
@@ -214,7 +214,7 @@ services:
|
||||
|
||||
# --------------------------------------------------------- PROTOCOLS
|
||||
protocols:
|
||||
image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/protocols:${IMAGE_TAG:-latest}
|
||||
image: ${IMAGE_NAMESPACE:-git.lucasrguerra.dev.br/lucasrguerra/lambdamail}/protocols:${IMAGE_TAG:-latest}
|
||||
# "latest" is a moving tag and Docker considers a tag it already holds
|
||||
# locally to be satisfied, so recreating this container silently reused
|
||||
# the cached image and the newly published one was never fetched: the
|
||||
@@ -297,7 +297,7 @@ services:
|
||||
|
||||
# -------------------------------------------------------------- WEB
|
||||
web:
|
||||
image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/webmail:${IMAGE_TAG:-latest}
|
||||
image: ${IMAGE_NAMESPACE:-git.lucasrguerra.dev.br/lucasrguerra/lambdamail}/webmail:${IMAGE_TAG:-latest}
|
||||
# "latest" is a moving tag and Docker considers a tag it already holds
|
||||
# locally to be satisfied, so recreating this container silently reused
|
||||
# the cached image and the newly published one was never fetched: the
|
||||
|
||||
+2
-2
@@ -176,7 +176,7 @@ have propagated and the IP has some sending history.
|
||||
|
||||
## Upgrading
|
||||
|
||||
Images are published to GHCR for `linux/amd64` and `linux/arm64` on every merge
|
||||
Images are published to the Gitea container registry for `linux/amd64` and `linux/arm64` on every merge
|
||||
to `main`.
|
||||
|
||||
```bash
|
||||
@@ -198,7 +198,7 @@ every release, which is what forces the pull.
|
||||
IMAGE_TAG=sha-<full commit sha>
|
||||
|
||||
The tags are published by `release.yml`; `docker buildx imagetools inspect
|
||||
ghcr.io/<owner>/lambdamail/webmail:latest` shows what `latest` currently points
|
||||
git.lucasrguerra.dev.br/<owner>/lambdamail/webmail:latest` shows what `latest` currently points
|
||||
at.
|
||||
|
||||
**Pinning has a second edge: bump it on every release.** A pinned tag is an
|
||||
|
||||
@@ -2,6 +2,10 @@ import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
// Real Argon2id hashes cost 1-3s each on a shared CI runner, and several
|
||||
// tests chain a dozen of them. The production cost parameters stay as they
|
||||
// are; the default 5s budget is what does not fit.
|
||||
testTimeout: 30_000,
|
||||
// session.ts refuses to load without a real signing secret, and ESM hoists
|
||||
// imports - so the value has to exist before any test file is evaluated,
|
||||
// which an assignment inside a test file cannot guarantee.
|
||||
|
||||
@@ -21,7 +21,7 @@ require (
|
||||
|
||||
require (
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.6 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
|
||||
@@ -23,8 +23,8 @@ github.com/fergusstrange/embedded-postgres v1.30.0 h1:ewv1e6bBlqOIYtgGgRcEnNDpfG
|
||||
github.com/fergusstrange/embedded-postgres v1.30.0/go.mod h1:w0YvnCgf19o6tskInrOOACtnqfVlOvluz3hlNLY7tRk=
|
||||
github.com/go-acme/lego/v4 v4.35.2 h1:uVQg+KC/yj9R2g7Q9W5wDqhvQvxV5SMu5eqFVoN5xZU=
|
||||
github.com/go-acme/lego/v4 v4.35.2/go.mod h1:pX2jN5n8OphMGY1IaMjYm5DAEzguBaKRt8AvJAgJXpc=
|
||||
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
|
||||
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
||||
github.com/go-jose/go-jose/v4 v4.1.6 h1:sNRkftxFJxwsILiQukqp5z83QBSmntVwmgRY7AqBDO4=
|
||||
github.com/go-jose/go-jose/v4 v4.1.6/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
|
||||
Generated
+41
-41
@@ -14,7 +14,7 @@
|
||||
"framer-motion": "^11.18.2",
|
||||
"imagetracerjs": "1.2.6",
|
||||
"lucide-react": "^0.474.0",
|
||||
"next": "15.5.27",
|
||||
"next": "15.5.28",
|
||||
"qrcode-generator": "^2.0.4",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
@@ -1334,15 +1334,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/env": {
|
||||
"version": "15.5.27",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.27.tgz",
|
||||
"integrity": "sha512-WC5hvVqiuFOcRyz6gKPeJkiVvSMf3scNeAV49CdWtVqxmUlzh8UKR6YHt9yiNkh8LngtzqSlVz07/Ma3ZAzchA==",
|
||||
"version": "15.5.28",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.28.tgz",
|
||||
"integrity": "sha512-xxW5EBI8fMPuVTPBW7LL980IRbuDXlbkUAwp9DDhtb4Lnich3nJ13uYpvrX4VE74hWPf6AvHHAMmGCidcHjbfg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@next/swc-darwin-arm64": {
|
||||
"version": "15.5.27",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.27.tgz",
|
||||
"integrity": "sha512-fBA9QurmK4+uj4wNhmRTuO5zMVRaBHCvp6H93zTG/5i6Yi6TewbvbesXB8YQNj8T99Cwrow87hHiFV6wL/hyMA==",
|
||||
"version": "15.5.28",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.28.tgz",
|
||||
"integrity": "sha512-dPoQYXcfSIqx5o+TOXVXO7kONK5qbtNRDeiTfII0bT3puGIT6VF5e0QwmxNZfEZ5Zety5f3m9P/p4xqwfiLlPg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1356,9 +1356,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-darwin-x64": {
|
||||
"version": "15.5.27",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.27.tgz",
|
||||
"integrity": "sha512-FGZwJwry8qZNHxD/nfwrCwCHHrqx6epqItkkxbYcBQEQ2uw5S43bY83fQB5zbAsZE7TELMjoYkbhsQ4oKM7wwg==",
|
||||
"version": "15.5.28",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.28.tgz",
|
||||
"integrity": "sha512-RgCJ7buBivTH+6sddqaVm+/v8kwMHlFkobvdt3DfETutws5HrxnToMIWSN9X3MZ3aAi7BbKrGZZWUDQLEycXqw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1372,9 +1372,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||
"version": "15.5.27",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.27.tgz",
|
||||
"integrity": "sha512-GQulAaJYNF1RYuatlsw9/uzbKz4if2V7Ic9nVO+P0ljYPm4yBRTFIl6g5YkKTw40lMLbpy9edLoH44g3jSHMYA==",
|
||||
"version": "15.5.28",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.28.tgz",
|
||||
"integrity": "sha512-OHXQe13olE59aKe++zHavGcJPh5SLHXi6Anret3BBeq1+qhSuOJDNAli/EDDfxs6UTqA4Qddo4uyYry2slyjiQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1391,9 +1391,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-arm64-musl": {
|
||||
"version": "15.5.27",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.27.tgz",
|
||||
"integrity": "sha512-URFFsUmu8Pi0/1qdnUI7tx7keZw1Mt5zHfrIX1RfDG9Nih8DYxK54WZsDJUX2ZTlii1jgotL7qcbwKnSAES6xQ==",
|
||||
"version": "15.5.28",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.28.tgz",
|
||||
"integrity": "sha512-nTB7bB6vfn4ezCJNYP43ukt2o8L3+WxKF/sTcTxepdXsJh3SM9RhlU7wrZYbH7L4HO5M87dqDTwm8587vAkCiw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1410,9 +1410,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-x64-gnu": {
|
||||
"version": "15.5.27",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.27.tgz",
|
||||
"integrity": "sha512-aJp74z7uvU5jQhyH7lyk+4qSRcTdKbKT9NQE3jiO9kWYkoHZjKi0zzHDbCoZ+v2sJDEiJ/z58R0UlWMGWNF3HA==",
|
||||
"version": "15.5.28",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.28.tgz",
|
||||
"integrity": "sha512-WXCfVI32rW3xCusoUX1RpZKtyChWU2Zwe27JUDmM3KrXwcDNc9vV4zEq0GKFAURnuQ/Ouo/XqPvB0yh445XZCg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1429,9 +1429,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-x64-musl": {
|
||||
"version": "15.5.27",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.27.tgz",
|
||||
"integrity": "sha512-ILl2bQ8MbpvyMpY8AXljb3BXs0MJSC8HXZ6QV5AWpVS7ZELqNPtrHvhUk+SNarvjvICXX8bCS287TCi+gUFVYg==",
|
||||
"version": "15.5.28",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.28.tgz",
|
||||
"integrity": "sha512-Miq+NDb/HWsXuxseYxMM6fuEOQXgTziarkKIRpVKCn8W69cEfhQaQr+90pO+u4q2CbJR2wzXmUuCFyZaJs/Nng==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1448,9 +1448,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||
"version": "15.5.27",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.27.tgz",
|
||||
"integrity": "sha512-1MB9Rh5y8TOPN2x7naNTJNkCZQav9c70AI7EBYXxsEewwOffC4DjjwBwKf20NBvcA+u+5jDv7nVmHxunlP2d7Q==",
|
||||
"version": "15.5.28",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.28.tgz",
|
||||
"integrity": "sha512-5LR79lemgDlgxvG7MQJ+zHCkVcrUoQuO7CiIvq3I58vNW4goSOE2b+19Z6FujRWMouvni4gvudYFuFuNxolGWA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1464,9 +1464,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-x64-msvc": {
|
||||
"version": "15.5.27",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.27.tgz",
|
||||
"integrity": "sha512-XtYgpGOswgnyBWXzOEG6q9RhvnSw0CEZ0MbWqCsl5PISgt9EzvJvNW5mU5n1PsphX/lnamzxjgQXH2GUJL8nqg==",
|
||||
"version": "15.5.28",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.28.tgz",
|
||||
"integrity": "sha512-GNipvXUYROSTf4PXEyH95FrWImIB5zdaK6uEOg0RP1/X2drnvoMwiBkJ0VWdzX7w3iiBm3y5g2TxkKDGVTOQcg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -3016,12 +3016,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/next": {
|
||||
"version": "15.5.27",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-15.5.27.tgz",
|
||||
"integrity": "sha512-F82CrlPZ8GRxBH9RIIoR3qU1t5RT3dv1K8moe8SjlDEquiFipvEI13R1Om90TaUOEwShkWCMlg8+gvTNzfMhvg==",
|
||||
"version": "15.5.28",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-15.5.28.tgz",
|
||||
"integrity": "sha512-JjhLBBY1PNnuwPtcZ7t8yxVeJVYvD2Jyp633J+gRCNbzSt7N0E+xqCf6uQiff3+3qmUkwcF/ksfSsK1xsZ76Tw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@next/env": "15.5.27",
|
||||
"@next/env": "15.5.28",
|
||||
"@swc/helpers": "0.5.15",
|
||||
"caniuse-lite": "^1.0.30001579",
|
||||
"postcss": "8.4.31",
|
||||
@@ -3034,15 +3034,15 @@
|
||||
"node": "^18.18.0 || ^19.8.0 || >= 20.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@next/swc-darwin-arm64": "15.5.27",
|
||||
"@next/swc-darwin-x64": "15.5.27",
|
||||
"@next/swc-linux-arm64-gnu": "15.5.27",
|
||||
"@next/swc-linux-arm64-musl": "15.5.27",
|
||||
"@next/swc-linux-x64-gnu": "15.5.27",
|
||||
"@next/swc-linux-x64-musl": "15.5.27",
|
||||
"@next/swc-win32-arm64-msvc": "15.5.27",
|
||||
"@next/swc-win32-x64-msvc": "15.5.27",
|
||||
"sharp": "^0.34.3 || ^0.35.4"
|
||||
"@next/swc-darwin-arm64": "15.5.28",
|
||||
"@next/swc-darwin-x64": "15.5.28",
|
||||
"@next/swc-linux-arm64-gnu": "15.5.28",
|
||||
"@next/swc-linux-arm64-musl": "15.5.28",
|
||||
"@next/swc-linux-x64-gnu": "15.5.28",
|
||||
"@next/swc-linux-x64-musl": "15.5.28",
|
||||
"@next/swc-win32-arm64-msvc": "15.5.28",
|
||||
"@next/swc-win32-x64-msvc": "15.5.28",
|
||||
"sharp": "^0.34.3 || ^0.35.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opentelemetry/api": "^1.1.0",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"framer-motion": "^11.18.2",
|
||||
"imagetracerjs": "1.2.6",
|
||||
"lucide-react": "^0.474.0",
|
||||
"next": "15.5.27",
|
||||
"next": "15.5.28",
|
||||
"qrcode-generator": "^2.0.4",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
||||
Reference in new issue
Block a user