name: Build and Push Docker Image on: push: tags: - 'v*' workflow_dispatch: inputs: test_tag: description: 'Test tag name (e.g., v0.1.1-test)' required: false default: 'v0.1.1-test' env: GHCR_REGISTRY: ghcr.io IMAGE_NAME: insforge-oss jobs: build-amd64: runs-on: ubuntu-latest permissions: contents: read packages: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v6 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Log in to GitHub Container Registry uses: docker/login-action@v4 with: registry: ${{ env.GHCR_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GHCR_PAT }} - name: Extract metadata for GHCR id: meta uses: docker/metadata-action@v6 with: images: ${{ env.GHCR_REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} flavor: | suffix=-amd64 latest=false tags: | type=ref,event=tag type=raw,value=${{ github.event.inputs.test_tag }},enable=${{ github.event_name == 'workflow_dispatch' }} - name: Build and push (amd64) uses: docker/build-push-action@v7 with: context: . target: runner platforms: linux/amd64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha,scope=amd64 cache-to: type=gha,mode=max,scope=amd64 build-args: | VERSION=${{ github.ref_name }} BUILD_DATE=${{ github.event.head_commit.timestamp }} COMMIT_SHA=${{ github.sha }} VITE_PUBLIC_POSTHOG_KEY=${{ secrets.POSTHOG_KEY }} build-arm64: runs-on: ubuntu-24.04-arm permissions: contents: read packages: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v6 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Log in to GitHub Container Registry uses: docker/login-action@v4 with: registry: ${{ env.GHCR_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GHCR_PAT }} - name: Extract metadata for GHCR id: meta uses: docker/metadata-action@v6 with: images: ${{ env.GHCR_REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} flavor: | suffix=-arm64 latest=false tags: | type=ref,event=tag type=raw,value=${{ github.event.inputs.test_tag }},enable=${{ github.event_name == 'workflow_dispatch' }} - name: Build and push (arm64) uses: docker/build-push-action@v7 with: context: . target: runner platforms: linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha,scope=arm64 cache-to: type=gha,mode=max,scope=arm64 build-args: | VERSION=${{ github.ref_name }} BUILD_DATE=${{ github.event.head_commit.timestamp }} COMMIT_SHA=${{ github.sha }} VITE_PUBLIC_POSTHOG_KEY=${{ secrets.POSTHOG_KEY }} merge-manifests: needs: [build-amd64, build-arm64] runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Log in to GitHub Container Registry uses: docker/login-action@v4 with: registry: ${{ env.GHCR_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GHCR_PAT }} - name: Extract metadata for GHCR id: meta uses: docker/metadata-action@v6 with: images: ${{ env.GHCR_REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} flavor: | latest=false tags: | type=ref,event=tag type=raw,value=${{ github.event.inputs.test_tag }},enable=${{ github.event_name == 'workflow_dispatch' }} type=raw,value=latest,enable=${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && !contains(github.ref_name, '-') }} - name: Create and push multi-arch manifest env: GHCR_IMAGE_RAW: ${{ env.GHCR_REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} SOURCE_VERSION: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.test_tag || github.ref_name }} run: | GHCR_IMAGE=$(echo "${GHCR_IMAGE_RAW}" | tr '[:upper:]' '[:lower:]') for TAG in $(echo "${{ steps.meta.outputs.tags }}" | tr ',' '\n'); do docker buildx imagetools create \ --tag "${TAG}" \ "${GHCR_IMAGE}:${SOURCE_VERSION}-amd64" \ "${GHCR_IMAGE}:${SOURCE_VERSION}-arm64" done push-to-ecr: needs: merge-manifests runs-on: ubuntu-latest if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && !contains(github.ref_name, '-') permissions: id-token: write contents: read steps: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ secrets.AWS_ECR_ROLE_ARN }} aws-region: ${{ secrets.AWS_ECR_REGION }} - name: Login to Amazon ECR id: ecr-login uses: aws-actions/amazon-ecr-login@v2 - name: Log in to GitHub Container Registry uses: docker/login-action@v4 with: registry: ${{ env.GHCR_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GHCR_PAT }} - name: Install crane uses: imjasonh/setup-crane@6da1ae018866400525525ce74ff892880c099987 # v0.5 - name: Copy multi-arch image to ECR env: ECR_REGISTRY: ${{ steps.ecr-login.outputs.registry }} VERSION: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.test_tag || github.ref_name }} GHCR_IMAGE_RAW: ${{ env.GHCR_REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} ECR_IMAGE: ${{ steps.ecr-login.outputs.registry }}/${{ env.IMAGE_NAME }} TAG_LATEST: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && !contains(github.ref_name, '-') }} run: | # Convert GHCR image name to lowercase (Docker requires lowercase) GHCR_IMAGE=$(echo "${GHCR_IMAGE_RAW}" | tr '[:upper:]' '[:lower:]') # Copy multi-arch image from GHCR to ECR (preserves all platforms) crane copy ${GHCR_IMAGE}:${VERSION} ${ECR_IMAGE}:${VERSION} if [[ "${TAG_LATEST}" == "true" ]]; then crane copy ${GHCR_IMAGE}:${VERSION} ${ECR_IMAGE}:latest fi