name: docker on: workflow_run: workflows: [backend] types: [completed] concurrency: group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch }} cancel-in-progress: true jobs: build: name: Build Docker image (${{ matrix.platform }}) if: >- github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event != 'pull_request' && (github.event.workflow_run.head_branch == 'master' || startsWith(github.event.workflow_run.head_branch, 'v')) permissions: contents: read packages: write strategy: fail-fast: false matrix: include: - platform: linux/amd64 runner: ubuntu-latest artifact: linux-amd64 - platform: linux/arm64 runner: ubuntu-24.04-arm artifact: linux-arm64 runs-on: ${{ matrix.runner }} steps: - name: checkout uses: actions/checkout@v7 with: ref: ${{ github.event.workflow_run.head_sha }} persist-credentials: false - name: set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: login to ghcr.io uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.PKG_TOKEN }} - name: login to DockerHub uses: docker/login-action@v4 with: username: umputun password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: free disk space run: | sudo rm -rf /usr/share/dotnet sudo rm -rf /opt/ghc sudo rm -rf /usr/local/share/boost docker system prune -af - name: build and push to ghcr.io by digest id: build-ghcr uses: docker/build-push-action@v7 with: context: . platforms: ${{ matrix.platform }} cache-from: type=gha,scope=${{ matrix.platform }} cache-to: type=gha,scope=${{ matrix.platform }},mode=max build-args: | SKIP_BACKEND_TEST=true SKIP_FRONTEND_TEST=true CI=github GITHUB_SHA=${{ github.event.workflow_run.head_sha }} GIT_BRANCH=${{ github.event.workflow_run.head_branch }} GITHUB_REF=refs/heads/${{ github.event.workflow_run.head_branch }} outputs: type=image,name=ghcr.io/umputun/remark42,push-by-digest=true,name-canonical=true,push=true - name: build and push to DockerHub by digest id: build-dockerhub uses: docker/build-push-action@v7 with: context: . platforms: ${{ matrix.platform }} cache-from: type=gha,scope=${{ matrix.platform }} build-args: | SKIP_BACKEND_TEST=true SKIP_FRONTEND_TEST=true CI=github GITHUB_SHA=${{ github.event.workflow_run.head_sha }} GIT_BRANCH=${{ github.event.workflow_run.head_branch }} GITHUB_REF=refs/heads/${{ github.event.workflow_run.head_branch }} outputs: type=image,name=umputun/remark42,push-by-digest=true,name-canonical=true,push=true - name: export digests run: | mkdir -p /tmp/digests/ghcr /tmp/digests/dockerhub digest_ghcr="${{ steps.build-ghcr.outputs.digest }}" digest_dockerhub="${{ steps.build-dockerhub.outputs.digest }}" touch "/tmp/digests/ghcr/${digest_ghcr#sha256:}" touch "/tmp/digests/dockerhub/${digest_dockerhub#sha256:}" - name: upload ghcr digest uses: actions/upload-artifact@v7 with: name: digests-ghcr-${{ matrix.artifact }} path: /tmp/digests/ghcr/* retention-days: 1 - name: upload dockerhub digest uses: actions/upload-artifact@v7 with: name: digests-dockerhub-${{ matrix.artifact }} path: /tmp/digests/dockerhub/* retention-days: 1 merge: name: Create multi-arch manifest runs-on: ubuntu-latest needs: build permissions: contents: read packages: write steps: - name: download ghcr digests uses: actions/download-artifact@v8 with: path: /tmp/digests/ghcr pattern: digests-ghcr-* merge-multiple: true - name: download dockerhub digests uses: actions/download-artifact@v8 with: path: /tmp/digests/dockerhub pattern: digests-dockerhub-* merge-multiple: true - name: verify all digests present run: | expected=2 for registry in ghcr dockerhub; do actual=$(find /tmp/digests/$registry -maxdepth 1 -type f | wc -l) if [ "$actual" -ne "$expected" ]; then echo "Expected $expected digests for $registry, found $actual" ls -la /tmp/digests/$registry exit 1 fi done echo "All digests present for both registries" - name: set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: login to ghcr.io uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.PKG_TOKEN }} - name: login to DockerHub uses: docker/login-action@v4 with: username: umputun password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: create ghcr.io manifest and push working-directory: /tmp/digests/ghcr env: HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} run: | if [[ "$HEAD_BRANCH" == v* ]]; then docker buildx imagetools create \ -t ghcr.io/umputun/remark42:${HEAD_BRANCH} \ -t ghcr.io/umputun/remark42:latest \ $(printf 'ghcr.io/umputun/remark42@sha256:%s ' *) else docker buildx imagetools create \ -t ghcr.io/umputun/remark42:${HEAD_BRANCH} \ $(printf 'ghcr.io/umputun/remark42@sha256:%s ' *) fi - name: create DockerHub manifest and push working-directory: /tmp/digests/dockerhub env: HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} run: | if [[ "$HEAD_BRANCH" == v* ]]; then docker buildx imagetools create \ -t umputun/remark42:${HEAD_BRANCH} \ -t umputun/remark42:latest \ $(printf 'umputun/remark42@sha256:%s ' *) else docker buildx imagetools create \ -t umputun/remark42:${HEAD_BRANCH} \ $(printf 'umputun/remark42@sha256:%s ' *) fi deploy: name: Deploy to remark42.com runs-on: ubuntu-latest needs: merge if: github.event.workflow_run.head_branch == 'master' permissions: {} # only calls an external URL via curl, no GitHub API access needed steps: - name: trigger deployment env: UPDATER_KEY: ${{ secrets.UPDATER_KEY }} run: curl -sf https://jess.umputun.com/update/remark42-core/${UPDATER_KEY}