diff --git a/.gitea/workflows/docker-publish.yml b/.gitea/workflows/docker-publish.yml new file mode 100644 index 0000000..db39309 --- /dev/null +++ b/.gitea/workflows/docker-publish.yml @@ -0,0 +1,116 @@ +name: Docker Build & Publish + +on: + push: + branches: [master] + workflow_dispatch: + +env: + # Number of tagged (non-latest) versions to keep per image name. + KEEP_VERSIONS: "5" + +jobs: + build: + runs-on: ubuntu-latest + outputs: + host: ${{ steps.meta.outputs.host }} + image: ${{ steps.meta.outputs.image }} + sha: ${{ steps.meta.outputs.sha }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Resolve registry metadata + id: meta + run: | + host=$(echo "${{ gitea.server_url }}" | sed 's|https\?://||; s|/$||') + repo_lc=$(echo "${{ gitea.repository }}" | tr '[:upper:]' '[:lower:]') + echo "host=$host" >> "$GITHUB_OUTPUT" + echo "image=$host/$repo_lc" >> "$GITHUB_OUTPUT" + echo "sha=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build image + uses: docker/build-push-action@v5 + with: + context: . + file: dockerfiles/Dockerfile.prod + push: false + tags: | + ${{ steps.meta.outputs.image }}:latest + ${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.sha }} + outputs: type=docker,dest=/tmp/image.tar + + - name: Upload image artifact + uses: actions/upload-artifact@v3 + with: + name: docker-image + path: /tmp/image.tar + retention-days: 1 + + push: + needs: build + runs-on: ubuntu-latest + steps: + - name: Download image artifact + uses: actions/download-artifact@v3 + with: + name: docker-image + path: /tmp + + - name: Load image + run: docker load < /tmp/image.tar + + - name: Log in to Gitea registry + uses: docker/login-action@v3 + with: + registry: ${{ needs.build.outputs.host }} + username: ${{ gitea.actor }} + password: ${{ secrets.PACKAGE_REGISTRY_TOKEN }} + + - name: Push image + run: | + docker push ${{ needs.build.outputs.image }}:latest + docker push ${{ needs.build.outputs.image }}:${{ needs.build.outputs.sha }} + + cleanup: + name: Prune old image versions + needs: push + runs-on: ubuntu-latest + steps: + - name: Delete versions beyond KEEP_VERSIONS + env: + GITEA_URL: ${{ gitea.server_url }} + OWNER: ${{ gitea.repository_owner }} + IMAGE: ${{ gitea.event.repository.name }} + TOKEN: ${{ secrets.PACKAGE_REGISTRY_TOKEN }} + run: | + image=$(echo "$IMAGE" | tr '[:upper:]' '[:lower:]') + + response=$(curl -sf \ + -H "Authorization: token $TOKEN" \ + -H "Accept: application/json" \ + "${GITEA_URL}/api/v1/packages/${OWNER}?type=container&limit=50&q=${image}") + + to_delete=$(printf '%s' "$response" \ + | jq -r \ + --arg name "$image" \ + --argjson keep "$KEEP_VERSIONS" \ + '[.[] | select(.name == $name and .version != "latest")] + | sort_by(.created) | reverse + | .[$keep:][].version') + + if [ -z "$to_delete" ]; then + echo "Nothing to prune." + exit 0 + fi + + while IFS= read -r version; do + echo "Deleting ${image}:${version}" + curl -sf -X DELETE \ + -H "Authorization: token $TOKEN" \ + "${GITEA_URL}/api/v1/packages/${OWNER}/container/${image}/${version}" \ + && echo " ok" || echo " failed (may already be gone, continuing)" + done <<< "$to_delete"