name: Build & Publish Images on: push: branches: [ main, dev ] tags: - '*' workflow_dispatch: env: REGISTRY: ghcr.io IMAGE_BACKEND: papercrate-dms/papercrate-backend IMAGE_FRONTEND: papercrate-dms/papercrate-frontend jobs: build: runs-on: ubuntu-latest strategy: matrix: component: [backend, frontend] platform: [linux/amd64, linux/arm64] permissions: contents: read packages: write id-token: write steps: - name: Check out repository uses: actions/checkout@v4 - name: Set component metadata run: | if [ "${{ matrix.component }}" = "backend" ]; then echo "COMPONENT_CONTEXT=./backend" >> "$GITHUB_ENV" echo "COMPONENT_IMAGE=${{ env.IMAGE_BACKEND }}" >> "$GITHUB_ENV" else echo "COMPONENT_CONTEXT=./frontend" >> "$GITHUB_ENV" echo "COMPONENT_IMAGE=${{ env.IMAGE_FRONTEND }}" >> "$GITHUB_ENV" fi echo "COMPONENT_NAME=${{ matrix.component }}" >> "$GITHUB_ENV" - name: Compute tags env: GITHUB_SHA: ${{ github.sha }} GITHUB_REF: ${{ github.ref }} REGISTRY: ${{ env.REGISTRY }} PLATFORM: ${{ matrix.platform }} run: | ARCH=${PLATFORM#*/} TAGS=("${GITHUB_SHA::7}") BRANCH=${GITHUB_REF##*/} if [ "$BRANCH" = "dev" ]; then TAGS+=("${GITHUB_SHA::7}-dev") fi if [[ "$GITHUB_REF" == refs/tags/* ]]; then TAGS+=("${GITHUB_REF#refs/tags/}") fi UNIQUE=() for tag in "${TAGS[@]}"; do [[ -z "$tag" ]] && continue skip=false for seen in "${UNIQUE[@]}"; do if [ "$tag" = "$seen" ]; then skip=true break fi done if [ "$skip" = false ]; then UNIQUE+=("$tag") fi done { echo "BASE_TAGS<> "$GITHUB_ENV" - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to GHCR uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build & push ${{ env.COMPONENT_NAME }} (${{ matrix.platform }}) uses: docker/build-push-action@v5 with: context: ${{ env.COMPONENT_CONTEXT }} push: true platforms: ${{ matrix.platform }} tags: ${{ env.IMAGE_TAGS }} manifest: runs-on: ubuntu-latest needs: build strategy: matrix: component: [backend, frontend] permissions: contents: read packages: write env: REGISTRY: ghcr.io ARCHES: amd64 arm64 steps: - name: Set component metadata run: | if [ "${{ matrix.component }}" = "backend" ]; then echo "COMPONENT_IMAGE=${{ env.IMAGE_BACKEND }}" >> "$GITHUB_ENV" else echo "COMPONENT_IMAGE=${{ env.IMAGE_FRONTEND }}" >> "$GITHUB_ENV" fi echo "COMPONENT_NAME=${{ matrix.component }}" >> "$GITHUB_ENV" - name: Compute base tags env: GITHUB_SHA: ${{ github.sha }} GITHUB_REF: ${{ github.ref }} run: | TAGS=("${GITHUB_SHA::7}") BRANCH=${GITHUB_REF##*/} if [ "$BRANCH" = "dev" ]; then TAGS+=("${GITHUB_SHA::7}-dev") fi if [[ "$GITHUB_REF" == refs/tags/* ]]; then TAGS+=("${GITHUB_REF#refs/tags/}") fi UNIQUE=() for tag in "${TAGS[@]}"; do [[ -z "$tag" ]] && continue skip=false for seen in "${UNIQUE[@]}"; do if [ "$tag" = "$seen" ]; then skip=true break fi done if [ "$skip" = false ]; then UNIQUE+=("$tag") fi done { echo "BASE_TAGS<> "$GITHUB_ENV" - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to GHCR uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Create manifests for ${{ env.COMPONENT_NAME }} run: | while IFS= read -r tag; do [ -n "$tag" ] || continue args=() for arch in $ARCHES; do args+=("$REGISTRY/$COMPONENT_IMAGE:${tag}-${arch}") done docker buildx imagetools create \ --tag "$REGISTRY/$COMPONENT_IMAGE:$tag" \ "${args[@]}" done <<< "$BASE_TAGS"