ci: reuse published images when the image sources are unchanged
Release hashes services/, migrations/ and config/; when images for that hash already exist it skips CI and the build and only applies the new tags. Tagging a release no longer recompiles the webmail. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2db5915061
commit
a3e071bb03
4 files changed
+80
-15
No files matched your search
@@ -18,8 +18,46 @@ env:
|
||||
REGISTRY: git.lucasrguerra.dev.br
|
||||
|
||||
jobs:
|
||||
# Nothing is published unless the full suite passes first.
|
||||
# The images are built from services/, migrations/ and config/ and nothing
|
||||
# else, so those three trees identify them. When an image for the same trees
|
||||
# is already in the registry (a docs-only merge, a workflow change, or a tag on
|
||||
# a commit that was just released), there is nothing to build: the new tags
|
||||
# are pointed at the existing manifest. This is what keeps tagging a release
|
||||
# from compiling the webmail a second time.
|
||||
plan:
|
||||
name: Plano (reaproveitar as imagens?)
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
inputs: ${{ steps.plan.outputs.inputs }}
|
||||
reuse: ${{ steps.plan.outputs.reuse }}
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- id: plan
|
||||
env:
|
||||
REGISTRY: ${{ env.REGISTRY }}
|
||||
REPO: ${{ gitea.repository }}
|
||||
run: |
|
||||
inputs=$(git rev-parse HEAD:services HEAD:migrations HEAD:config | sha256sum | cut -c1-16)
|
||||
ns="${REPO,,}"
|
||||
reuse=true
|
||||
for s in protocols auth storage webmail migrations rspamd; do
|
||||
token=$(curl -fsS "https://$REGISTRY/v2/token?service=container_registry&scope=repository:$ns/$s:pull" | jq -r .token)
|
||||
code=$(curl -s -o /dev/null -w '%{http_code}' -I \
|
||||
-H "Authorization: Bearer $token" \
|
||||
-H 'Accept: application/vnd.oci.image.index.v1+json,application/vnd.docker.distribution.manifest.list.v2+json' \
|
||||
"https://$REGISTRY/v2/$ns/$s/manifests/inputs-$inputs")
|
||||
echo "$s: inputs-$inputs -> HTTP $code"
|
||||
[ "$code" = 200 ] || reuse=false
|
||||
done
|
||||
echo "inputs=$inputs" >> "$GITHUB_OUTPUT"
|
||||
echo "reuse=$reuse" >> "$GITHUB_OUTPUT"
|
||||
echo "reuse the published images: $reuse"
|
||||
|
||||
# Nothing is published unless the full suite passes first. Skipped when the
|
||||
# images are reused: the same trees already went through it.
|
||||
ci:
|
||||
needs: plan
|
||||
if: ${{ needs.plan.outputs.reuse != 'true' }}
|
||||
uses: ./.gitea/workflows/ci.yml
|
||||
|
||||
# Registry paths must be lowercase, and this repository is "lucasrguerra/LambdaMail".
|
||||
@@ -42,7 +80,8 @@ jobs:
|
||||
# magnitude slower.
|
||||
build:
|
||||
name: Build ${{ matrix.service }} (${{ matrix.platform }})
|
||||
needs: [ci, prepare]
|
||||
needs: [plan, ci, prepare]
|
||||
if: ${{ needs.plan.outputs.reuse != 'true' }}
|
||||
runs-on: ${{ matrix.runner }}
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -104,7 +143,9 @@ jobs:
|
||||
|
||||
publish:
|
||||
name: Publica ${{ matrix.service }}
|
||||
needs: [build, prepare]
|
||||
needs: [plan, build, prepare]
|
||||
# build is skipped, not successful, when the images are reused.
|
||||
if: ${{ !cancelled() && needs.plan.result == 'success' && needs.prepare.result == 'success' && (needs.build.result == 'success' || needs.plan.outputs.reuse == 'true') }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -141,13 +182,20 @@ jobs:
|
||||
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
|
||||
# resolves to the right one automatically. The inputs-<hash> tag is what
|
||||
# lets a later run recognise these images and skip the build.
|
||||
- name: Aplica as tags
|
||||
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"
|
||||
tags=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< '${{ steps.meta.outputs.json }}')
|
||||
inputs='${{ needs.plan.outputs.inputs }}'
|
||||
if [ '${{ needs.plan.outputs.reuse }}' = true ]; then
|
||||
# Same manifest under new names: no layer is read or written.
|
||||
docker buildx imagetools create $tags "$image:inputs-$inputs"
|
||||
else
|
||||
docker buildx imagetools create $tags -t "$image:inputs-$inputs" \
|
||||
"$image:build-${{ gitea.sha }}-amd64" "$image:build-${{ gitea.sha }}-arm64"
|
||||
fi
|
||||
|
||||
- name: Confere o resultado
|
||||
run: |
|
||||
|
||||
Reference in new issue
Block a user