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 build-args: | PUBLIC_API_BASE_URL=/api/v1 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@v4 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@v4 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:]') # List all container package versions for this image (page size 50 is # enough for typical repos; increase if you push very frequently). response=$(curl -sf \ -H "Authorization: token $TOKEN" \ -H "Accept: application/json" \ "${GITEA_URL}/api/v1/packages/${OWNER}?type=container&limit=50&q=${image}") # Keep the KEEP_VERSIONS newest SHA-tagged versions; always preserve 'latest'. 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"