From 7f91cc0aa1cf6eeae5821b20e88ed90e6adecaaf Mon Sep 17 00:00:00 2001 From: Sarath Chandra Oruganti <39090092+sarathchandra24@users.noreply.github.com> Date: Fri, 8 Mar 2024 00:06:58 -0600 Subject: [PATCH] push image to multiple registry (#1079) * push image to multiple registry Signed-off-by: Sarath Chandra Oruganti <39090092+SarathChandra24@users.noreply.github.com> Signed-off-by: Sarath Chandra Oruganti * github actions permissions Signed-off-by: Sarath Chandra Oruganti <39090092+SarathChandra24@users.noreply.github.com> Signed-off-by: Sarath Chandra Oruganti * fluentd multi registry image push Signed-off-by: Sarath Chandra Oruganti * Limit build to PR changes for certain files Signed-off-by: Sarath Chandra Oruganti --------- Signed-off-by: Sarath Chandra Oruganti <39090092+SarathChandra24@users.noreply.github.com> Signed-off-by: Sarath Chandra Oruganti --- .github/workflows/build-fb-image.yaml | 206 +++++++++++- .github/workflows/build-fd-image.yaml | 301 +++++++++++++++++- .github/workflows/build-op-image.yaml | 135 ++++++-- .../workflows/clone-docker-image-action.yaml | 82 +++++ .../workflows/scan-docker-image-action.yaml | 69 ++++ 5 files changed, 745 insertions(+), 48 deletions(-) create mode 100644 .github/workflows/clone-docker-image-action.yaml create mode 100644 .github/workflows/scan-docker-image-action.yaml diff --git a/.github/workflows/build-fb-image.yaml b/.github/workflows/build-fb-image.yaml index 31ddfee1a..591e0894c 100644 --- a/.github/workflows/build-fb-image.yaml +++ b/.github/workflows/build-fb-image.yaml @@ -11,16 +11,98 @@ on: - "cmd/fluent-watcher/fluentbit/**" - "cmd/fluent-watcher/hooks/**" - "pkg/filenotify/**" + pull_request: + branches: + - "master" + paths: + - ".github/workflows/build-fb-image.yaml" + - "cmd/fluent-watcher/fluentbit/**" + - "cmd/fluent-watcher/hooks/**" + - "pkg/filenotify/**" env: - FB_IMG: 'kubesphere/fluent-bit:v2.2.2' - FB_IMG_DEBUG: 'kubesphere/fluent-bit:v2.2.2-debug' + DOCKER_REPO: 'kubesphere' + DOCKER_IMAGE: 'fluent-bit' + GITHUB_IMAGE: '${{ github.repository }}/fluent-bit' + +permissions: + contents: read + packages: write jobs: - build: + build-prod-image-metadata: + runs-on: ubuntu-latest + name: Build prod image metadata + outputs: + IMG_NAME: ${{ steps.set-outputs.outputs.IMAGE_NAME }} + DOCKER_IMG_NAME: ${{ steps.set-outputs.outputs.DOCKER_IMG_NAME }} + version: ${{ steps.image-metadata.outputs.version }} + tags: ${{ steps.image-metadata.outputs.tags }} + labels: ${{ steps.image-metadata.outputs.labels }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: docker metadata + id: image-metadata + uses: docker/metadata-action@v5 + with: + images: "ghcr.io/${{ env.GITHUB_IMAGE }}" + tags: | + raw,latest + type=ref,event=branch + type=ref,event=pr + type=ref,event=tag + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + + - name: Set outputs + id: set-outputs + run: | + echo "IMAGE_NAME=${{ env.GITHUB_IMAGE }}" >> $GITHUB_OUTPUT + echo "DOCKER_IMG_NAME=${{env.DOCKER_REPO}}/${{ env.DOCKER_IMAGE }}" >> $GITHUB_OUTPUT + + build-debug-image-metadata: + runs-on: ubuntu-latest + name: Build debug image metadata + outputs: + IMG_NAME: ${{ steps.set-outputs.outputs.IMAGE_NAME }} + DOCKER_IMG_NAME: ${{ steps.set-outputs.outputs.DOCKER_IMG_NAME }} + version: ${{ steps.image-metadata.outputs.version }} + tags: ${{ steps.image-metadata.outputs.tags }} + labels: ${{ steps.image-metadata.outputs.labels }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: docker metadata + id: image-metadata + uses: docker/metadata-action@v5 + with: + images: "ghcr.io/${{ env.GITHUB_IMAGE }}" + flavor: | + latest=false + suffix=-debug + tags: | + raw,latest + type=ref,event=branch + type=ref,event=pr + type=ref,event=tag + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + + - name: Set outputs + id: set-outputs + run: | + echo "IMAGE_NAME=${{ env.GITHUB_IMAGE }}" >> $GITHUB_OUTPUT + echo "DOCKER_IMG_NAME=${{env.DOCKER_REPO}}/${{ env.DOCKER_IMAGE }}" >> $GITHUB_OUTPUT + + build-FluentBit-prod-image: + needs: + - build-prod-image-metadata runs-on: ubuntu-latest timeout-minutes: 30 - name: Build Image for Fluent Bit + name: Build Fluent Bit prod image steps: - name: Install Go uses: actions/setup-go@v4 @@ -37,17 +119,121 @@ jobs: with: fetch-depth: 0 - - name: Login to Docker Hub + - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: - username: ${{ secrets.REGISTRY_USER }} - password: ${{ secrets.REGISTRY_PASSWORD }} + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@v3 - name: Build and Push Image for Fluent Bit - run: | - make build-fb -e FB_IMG=${{ env.FB_IMG }} - make build-fb-debug -e FB_IMG_DEBUG=${{ env.FB_IMG_DEBUG }} \ No newline at end of file + id: docker-build + uses: docker/build-push-action@v5 + with: + context: . + file: ./cmd/fluent-watcher/fluentbit/Dockerfile + push: true + platforms: linux/amd64,linux/arm64 + tags: ${{ needs.build-prod-image-metadata.outputs.tags }} + labels: ${{ needs.build-prod-image-metadata.outputs.labels }} + + build-FluentBit-debug-image: + needs: + - build-debug-image-metadata + runs-on: ubuntu-latest + timeout-minutes: 30 + name: Build Fluent Bit debug image + steps: + - name: Install Go + uses: actions/setup-go@v4 + with: + go-version: 1.21 + + - uses: actions/cache@v3 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and Push Fluent Bit Debug Image + id: docker-build-debug + uses: docker/build-push-action@v5 + with: + context: . + file: ./cmd/fluent-watcher/fluentbit/Dockerfile.debug + push: true + platforms: linux/amd64,linux/arm64 + tags: ${{ needs.build-debug-image-metadata.outputs.tags }} + labels: ${{ needs.build-debug-image-metadata.outputs.labels }} + + scan-FluentBit-image: + name: Scan prod image + needs: + - build-prod-image-metadata + - build-FluentBit-prod-image + uses: ./.github/workflows/scan-docker-image-action.yaml + with: + source_image: "${{ needs.build-prod-image-metadata.outputs.IMG_NAME }}:${{ needs.build-prod-image-metadata.outputs.version }}" + source_registry: ghcr.io + platforms: "['linux/arm64', 'linux/amd64']" + secrets: + registry_username: ${{ github.actor }} + registry_password: ${{ secrets.GITHUB_TOKEN }} + + release-prod-image-to-docker-hub: + if: ${{ github.event_name != 'pull_request' }} + name: Release prod image to Docker Hub + uses: ./.github/workflows/clone-docker-image-action.yaml + needs: + - build-FluentBit-prod-image + - scan-FluentBit-image + - build-prod-image-metadata + with: + source_image: "${{ needs.build-prod-image-metadata.outputs.IMG_NAME }}:${{ needs.build-prod-image-metadata.outputs.version }}" + source_registry: ghcr.io + target_image: "${{ needs.build-prod-image-metadata.outputs.DOCKER_IMG_NAME }}:${{ needs.build-prod-image-metadata.outputs.version }}" + target_registry: docker.io + platforms: "['linux/arm64', 'linux/amd64']" + secrets: + source_registry_username: ${{ github.actor }} + source_registry_token: ${{ secrets.GITHUB_TOKEN }} + target_registry_username: ${{ secrets.REGISTRY_USER }} + target_registry_token: ${{ secrets.REGISTRY_PASSWORD }} + + release-debug-image-to-docker-hub: + if: ${{ github.event_name != 'pull_request' }} + name: Release debug image to Docker Hub + uses: ./.github/workflows/clone-docker-image-action.yaml + needs: + - build-FluentBit-debug-image + - build-debug-image-metadata + with: + source_image: "${{ needs.build-debug-image-metadata.outputs.IMG_NAME }}:${{ needs.build-debug-image-metadata.outputs.version }}" + source_registry: ghcr.io + target_image: "${{ needs.build-debug-image-metadata.outputs.DOCKER_IMG_NAME }}:${{ needs.build-debug-image-metadata.outputs.version }}" + target_registry: docker.io + platforms: "['linux/arm64', 'linux/amd64']" + secrets: + source_registry_username: ${{ github.actor }} + source_registry_token: ${{ secrets.GITHUB_TOKEN }} + target_registry_username: ${{ secrets.REGISTRY_USER }} + target_registry_token: ${{ secrets.REGISTRY_PASSWORD }} diff --git a/.github/workflows/build-fd-image.yaml b/.github/workflows/build-fd-image.yaml index 1d82c7206..9df652699 100644 --- a/.github/workflows/build-fd-image.yaml +++ b/.github/workflows/build-fd-image.yaml @@ -13,13 +13,120 @@ on: - "pkg/filenotify/**" env: - FD_IMG: 'kubesphere/fluentd:v1.15.3' - ARCH: '-arm64' - FD_IMG_BASE: 'kubesphere/fluentd:v1.15.3-arm64-base' + DOCKER_REPO: 'kubesphere' + DOCKER_IMAGE: 'fluentd' + GITHUB_IMAGE: '${{ github.repository }}/fluentd' + +permissions: + contents: read + packages: write jobs: + build-amd64-prod-image-metadata: + runs-on: ubuntu-latest + name: Build prod image metadata for amd64 + outputs: + IMG_NAME: ${{ steps.set-outputs.outputs.IMAGE_NAME }} + version: ${{ steps.image-metadata.outputs.version }} + tags: ${{ steps.image-metadata.outputs.tags }} + labels: ${{ steps.image-metadata.outputs.labels }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: docker metadata for amd64 + id: image-metadata + uses: docker/metadata-action@v5 + with: + images: "ghcr.io/${{ env.GITHUB_IMAGE }}" + flavor: | + latest=false + suffix=-amd64 + tags: | + raw,latest + type=ref,event=branch + type=ref,event=pr + type=ref,event=tag + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + + - name: Set outputs + id: set-outputs + run: | + echo "IMAGE_NAME=${{ env.GITHUB_IMAGE }}" >> $GITHUB_OUTPUT + + build-arm64-prod-image-metadata: + runs-on: ubuntu-latest + name: Build prod image metadata for arm64 + outputs: + IMG_NAME: ${{ steps.set-outputs.outputs.IMAGE_NAME }} + version: ${{ steps.image-metadata.outputs.version }} + tags: ${{ steps.image-metadata.outputs.tags }} + labels: ${{ steps.image-metadata.outputs.labels }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: docker metadata for arm64 + id: image-metadata + uses: docker/metadata-action@v5 + with: + images: "ghcr.io/${{ env.GITHUB_IMAGE }}" + flavor: | + latest=false + suffix=-arm64 + tags: | + raw,latest + type=ref,event=branch + type=ref,event=pr + type=ref,event=tag + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + + - name: Set outputs + id: set-outputs + run: | + echo "IMAGE_NAME=${{ env.GITHUB_IMAGE }}" >> $GITHUB_OUTPUT + + build-arm64-base-image-metadata: + runs-on: ubuntu-latest + name: Build prod image metadata for arm64 base image + outputs: + IMG_NAME: ${{ steps.set-outputs.outputs.IMAGE_NAME }} + DOCKER_IMG_NAME: ${{ steps.set-outputs.outputs.DOCKER_IMG_NAME }} + version: ${{ steps.image-metadata.outputs.version }} + tags: ${{ steps.image-metadata.outputs.tags }} + labels: ${{ steps.image-metadata.outputs.labels }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: docker metadata for arm64 base image + id: image-metadata + uses: docker/metadata-action@v5 + with: + images: "ghcr.io/${{ env.GITHUB_IMAGE }}" + flavor: | + latest=false + suffix=-arm64-base + tags: | + raw,latest + type=ref,event=branch + type=ref,event=pr + type=ref,event=tag + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + + - name: Set outputs + id: set-outputs + run: | + echo "IMAGE_NAME=${{ env.GITHUB_IMAGE }}" >> $GITHUB_OUTPUT + echo "DOCKER_IMG_NAME=${{env.DOCKER_REPO}}/${{ env.DOCKER_IMAGE }}" >> $GITHUB_OUTPUT + build-amd64: runs-on: ubuntu-latest + needs: build-amd64-prod-image-metadata timeout-minutes: 30 name: Build amd64 Image for Fluentd steps: @@ -41,16 +148,91 @@ jobs: - name: Login to Docker Hub uses: docker/login-action@v3 with: - username: ${{ secrets.REGISTRY_USER }} - password: ${{ secrets.REGISTRY_PASSWORD }} + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and Push amd64 Image for Fluentd - run: | - make build-fd-amd64 -e FD_IMG=${{ env.FD_IMG }} - docker push ${{ env.FD_IMG }} + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and Push amd64 base Image for Fluentd + uses: docker/build-push-action@v5 + with: + context: . + file: cmd/fluent-watcher/fluentd/Dockerfile.amd64 + push: true + platforms: linux/amd64 + tags: ${{ needs.build-amd64-prod-image-metadata.outputs.tags }} + labels: ${{ needs.build-amd64-prod-image-metadata.outputs.labels }} + + build-arm64-base: + runs-on: ubuntu-latest + needs: build-arm64-base-image-metadata + timeout-minutes: 90 + name: Build arm64 base Image for Fluentd + steps: + - name: Install Go + uses: actions/setup-go@v4 + with: + go-version: 1.21 + + - uses: actions/cache@v3 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and Push arm64 base Image for Fluentd + uses: docker/build-push-action@v5 + with: + context: . + file: cmd/fluent-watcher/fluentd/Dockerfile.arm64.base + push: true + platforms: linux/arm64 + tags: ${{ needs.build-arm64-base-image-metadata.outputs.tags }} + labels: ${{ needs.build-arm64-base-image-metadata.outputs.labels }} + + release-arm64-base-image-to-docker-hub: + if: ${{ github.event_name != 'pull_request' }} + name: Release Image to Docker Hub + uses: ./.github/workflows/clone-docker-image-action.yaml + needs: + - build-arm64-base-image-metadata + - build-arm64-base + with: + source_image: "${{ needs.build-arm64-base-image-metadata.outputs.IMG_NAME }}:${{ needs.build-arm64-base-image-metadata.outputs.version }}" + source_registry: ghcr.io + target_image: "${{ needs.build-arm64-base-image-metadata.outputs.DOCKER_IMG_NAME }}:${{ needs.build-arm64-base-image-metadata.outputs.version }}" + target_registry: docker.io + platforms: "['linux/arm64']" + secrets: + source_registry_username: ${{ github.actor }} + source_registry_token: ${{ secrets.GITHUB_TOKEN }} + target_registry_username: ${{ secrets.REGISTRY_USER }} + target_registry_token: ${{ secrets.REGISTRY_PASSWORD }} build-arm64: runs-on: ubuntu-latest + needs: + - build-arm64-prod-image-metadata + - build-arm64-base-image-metadata + - build-arm64-base timeout-minutes: 90 name: Build arm64 Image for Fluentd steps: @@ -72,17 +254,106 @@ jobs: - name: Login to Docker Hub uses: docker/login-action@v3 with: - username: ${{ secrets.REGISTRY_USER }} - password: ${{ secrets.REGISTRY_PASSWORD }} + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@v3 - name: Build and Push arm64 base Image for Fluentd - run: | - make build-fd-arm64-base -e FD_IMG_BASE=${{ env.FD_IMG_BASE }} + uses: docker/build-push-action@v5 + with: + context: . + file: cmd/fluent-watcher/fluentd/Dockerfile.arm64.quick + push: true + platforms: linux/arm64 + tags: ${{ needs.build-arm64-prod-image-metadata.outputs.tags }} + labels: ${{ needs.build-arm64-prod-image-metadata.outputs.labels }} + build-args: | + BASE_IMAGE_TAG=${{ needs.build-arm64-base-image-metadata.outputs.version }} + BASE_IMAGE=ghcr.io/${{needs.build-arm64-base-image-metadata.outputs.IMG_NAME}} + + prod-image-manifest: + needs: + - build-amd64-prod-image-metadata + - build-arm64-prod-image-metadata + - build-amd64 + - build-arm64 + runs-on: ubuntu-latest + name: Create image manifest + outputs: + IMG_NAME: ${{ steps.set-outputs.outputs.IMAGE_NAME }} + DOCKER_IMG_NAME: ${{ steps.set-outputs.outputs.DOCKER_IMG_NAME }} + version: ${{ steps.image-metadata.outputs.version }} + tags: ${{ steps.image-metadata.outputs.tags }} + labels: ${{ steps.image-metadata.outputs.labels }} + steps: + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and Push arm64 Image for Fluentd + - name: docker metadata for manifest + id: image-metadata + uses: docker/metadata-action@v5 + with: + images: "ghcr.io/${{ env.GITHUB_IMAGE }}" + flavor: | + latest=false + tags: | + raw,latest + type=ref,event=branch + type=ref,event=pr + type=ref,event=tag + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + + - name: Set outputs + id: set-outputs run: | - make build-fd-arm64 -e FD_IMG=${{ env.FD_IMG }} -e ARCH=${{ env.ARCH }} \ No newline at end of file + echo "IMAGE_NAME=${{ env.GITHUB_IMAGE }}" >> $GITHUB_OUTPUT + echo "DOCKER_IMG_NAME=${{env.DOCKER_REPO}}/${{ env.DOCKER_IMAGE }}" >> $GITHUB_OUTPUT + + - name: Create image manifest + uses: int128/docker-manifest-create-action@v2 + with: + push: true + tags: ${{ steps.image-metadata.outputs.tags }} + sources: | + ghcr.io/${{ needs.build-amd64-prod-image-metadata.outputs.IMG_NAME }}:${{ needs.build-amd64-prod-image-metadata.outputs.version }} + ghcr.io/${{ needs.build-arm64-prod-image-metadata.outputs.IMG_NAME }}:${{ needs.build-arm64-prod-image-metadata.outputs.version }} + + scan-image: + needs: + - prod-image-manifest + name: Scan Fluentd Image + uses: ./.github/workflows/scan-docker-image-action.yaml + with: + source_image: "${{ needs.prod-image-manifest.outputs.IMG_NAME }}:${{ needs.prod-image-manifest.outputs.version }}" + source_registry: ghcr.io + platforms: "['linux/arm64', 'linux/amd64']" + secrets: + registry_username: ${{ github.actor }} + registry_password: ${{ secrets.GITHUB_TOKEN }} + + release-images-to-docker-hub: + if: ${{ github.event_name != 'pull_request' }} + name: Release Image to Docker Hub + uses: ./.github/workflows/clone-docker-image-action.yaml + needs: + - prod-image-manifest + - scan-image + with: + source_image: "${{ needs.prod-image-manifest.outputs.IMG_NAME }}:${{ needs.prod-image-manifest.outputs.version }}" + source_registry: ghcr.io + target_image: "${{ needs.prod-image-manifest.outputs.DOCKER_IMG_NAME }}:${{ needs.prod-image-manifest.outputs.version }}" + target_registry: docker.io + platforms: "['linux/arm64', 'linux/amd64']" + secrets: + source_registry_username: ${{ github.actor }} + source_registry_token: ${{ secrets.GITHUB_TOKEN }} + target_registry_username: ${{ secrets.REGISTRY_USER }} + target_registry_token: ${{ secrets.REGISTRY_PASSWORD }} diff --git a/.github/workflows/build-op-image.yaml b/.github/workflows/build-op-image.yaml index f0edc06f0..6940808da 100644 --- a/.github/workflows/build-op-image.yaml +++ b/.github/workflows/build-op-image.yaml @@ -3,11 +3,12 @@ name: Building Fluent Operator image on: push: branches: - - 'master' + - "master" tags: - - 'v*' + - "v*" paths: - ".github/workflows/build-op-image.yaml" + - ".github/workflows/clone-docker-image-action.yaml" - "apis/**" - "cmd/fluent-manager/**" - "controllers/**" @@ -18,41 +19,129 @@ on: - "pkg/fluentd/utils/**" - "Makefile" + pull_request: + branches: + - "master" + paths: + - ".github/workflows/build-op-image.yaml" + - ".github/workflows/clone-docker-image-action.yaml" + - "apis/**" + - "cmd/fluent-manager/**" + - "controllers/**" + - "hack/**" + - "manifests/setup/setup.yaml" + - "pkg/fluentd/router/**" + - "pkg/fluentd/operator/**" + - "pkg/fluentd/utils/**" + env: - REGISTRY_REPO: 'kubesphere' + DOCKER_REPO: "kubesphere" + DOCKER_IMAGE: "fluent-operator" + GITHUB_IMAGE: "${{ github.repository }}/fluent-operator" + +permissions: + contents: read + packages: write jobs: - operator-build: + build-image-metadata: runs-on: ubuntu-latest - timeout-minutes: 30 - name: Build Image for Fluent Operator + name: Build Image Metadata + outputs: + IMG_NAME: ${{ steps.set-outputs.outputs.IMAGE_NAME }} + DOCKER_IMG_NAME: ${{ steps.set-outputs.outputs.DOCKER_IMG_NAME }} + version: ${{ steps.image-metadata.outputs.version }} + tags: ${{ steps.image-metadata.outputs.tags }} + labels: ${{ steps.image-metadata.outputs.labels }} + steps: - - name: Install Go - uses: actions/setup-go@v4 + - name: Checkout code + uses: actions/checkout@v4 + + - name: docker metadata + id: image-metadata + uses: docker/metadata-action@v5 with: - go-version: 1.21 + images: "ghcr.io/${{ env.GITHUB_IMAGE }}" + tags: | + raw,latest + type=ref,event=branch + type=ref,event=pr + type=ref,event=tag + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} - - uses: actions/cache@v3 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + - name: Set outputs + id: set-outputs + run: | + echo "IMAGE_NAME=${{ env.GITHUB_IMAGE }}" >> $GITHUB_OUTPUT + echo "DOCKER_IMG_NAME=${{env.DOCKER_REPO}}/${{ env.DOCKER_IMAGE }}" >> $GITHUB_OUTPUT + operator-build: + runs-on: ubuntu-latest + timeout-minutes: 30 + name: Build Image for Fluent Operator + needs: + - build-image-metadata + steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.REGISTRY_USER }} - password: ${{ secrets.REGISTRY_PASSWORD }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - id: buildx uses: docker/setup-buildx-action@v3 - - name: Build and Push Image for Fluent Operator - run: | - tag=$(cat VERSION | tr -d " \t\n\r") - make build-op -e FO_IMG=${{ env.REGISTRY_REPO }}/fluent-operator:$tag \ No newline at end of file + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + file: ./cmd/fluent-manager/Dockerfile + push: true + platforms: linux/amd64,linux/arm64 + tags: ${{ needs.build-image-metadata.outputs.tags }} + labels: ${{ needs.build-image-metadata.outputs.labels }} + + scan-operator-image: + name: Scan Docker Image + needs: + - operator-build + - build-image-metadata + uses: ./.github/workflows/scan-docker-image-action.yaml + with: + source_image: "${{ needs.build-image-metadata.outputs.IMG_NAME }}:${{ needs.build-image-metadata.outputs.version }}" + source_registry: ghcr.io + platforms: "['linux/arm64', 'linux/amd64']" + secrets: + registry_username: ${{ github.actor }} + registry_password: ${{ secrets.GITHUB_TOKEN }} + + release-image-to-docker-hub: + if: ${{ github.event_name != 'pull_request' }} + name: Release Image to Docker Hub + uses: ./.github/workflows/clone-docker-image-action.yaml + needs: + - operator-build + - scan-operator-image + - build-image-metadata + with: + source_image: "${{ needs.build-image-metadata.outputs.IMG_NAME }}:${{ needs.build-image-metadata.outputs.version }}" + source_registry: ghcr.io + target_image: "${{ needs.build-image-metadata.outputs.DOCKER_IMG_NAME }}:${{ needs.build-image-metadata.outputs.version }}" + target_registry: docker.io + platforms: "['linux/arm64', 'linux/amd64']" + secrets: + source_registry_username: ${{ github.actor }} + source_registry_token: ${{ secrets.GITHUB_TOKEN }} + target_registry_username: ${{ secrets.REGISTRY_USER }} + target_registry_token: ${{ secrets.REGISTRY_PASSWORD }} diff --git a/.github/workflows/clone-docker-image-action.yaml b/.github/workflows/clone-docker-image-action.yaml new file mode 100644 index 000000000..46cecc626 --- /dev/null +++ b/.github/workflows/clone-docker-image-action.yaml @@ -0,0 +1,82 @@ +--- + name: Reusable workflow to clone a Docker image from one registry to another + on: + workflow_call: + inputs: + source_image: + description: The source image to clone + required: true + type: string + source_registry: + description: The source registry + required: true + type: string + target_image: + description: The target image to clone + required: true + type: string + target_registry: + description: 'The target registry' + required: true + type: string + platforms: + description: 'The platforms to clone' + required: false + type: string + default: '["linux/arm64", "linux/amd64"]' + secrets: + source_registry_token: + description: The Github token or similar to authenticate with for the registry. + required: true + target_registry_token: + description: The Github token or similar to authenticate with for the registry. + required: true + source_registry_username: + description: The source registry username + required: true + target_registry_username: + description: The target registry username + required: true + + jobs: + check-image-exists: + strategy: + matrix: + platform: ${{ fromJson(inputs.platforms) }} + runs-on: ubuntu-latest + steps: + - name: Login to source container registry ${{ inputs.source_registry }} + uses: docker/login-action@v3 + with: + registry: ${{ inputs.source_registry }} + username: ${{ secrets.source_registry_username }} + password: ${{ secrets.source_registry_token }} + + - name: Pull the source image; verify it exists + run: + docker pull "$SOURCE_IMAGE" --platform=${{ matrix.platform }} + env: + SOURCE_IMAGE: ${{ inputs.source_registry }}/${{ inputs.source_image }} + shell: bash + + push-image: + needs: check-image-exists + runs-on: ubuntu-latest + steps: + - name: Promote container images from ${{ inputs.source_registry }} to ${{ inputs.target_registry }} + run: | + echo "Promoting $SOURCE_IMAGE to $RELEASE_IMAGE" + docker run --rm \ + quay.io/skopeo/stable:latest \ + copy \ + --all \ + --retry-times 10 \ + --dest-creds "$RELEASE_CREDS" \ + --src-creds "$SOURCE_CREDS" \ + "docker://$SOURCE_IMAGE" \ + "docker://$RELEASE_IMAGE" + env: + SOURCE_IMAGE: "${{ inputs.source_registry }}/${{ inputs.source_image }}" + RELEASE_IMAGE: "${{ inputs.target_registry }}/${{ inputs.target_image }}" + RELEASE_CREDS: ${{ secrets.target_registry_username }}:${{ secrets.target_registry_token }} + SOURCE_CREDS: ${{ secrets.source_registry_username }}:${{ secrets.source_registry_token }} diff --git a/.github/workflows/scan-docker-image-action.yaml b/.github/workflows/scan-docker-image-action.yaml new file mode 100644 index 000000000..ae10eeb7e --- /dev/null +++ b/.github/workflows/scan-docker-image-action.yaml @@ -0,0 +1,69 @@ +--- + name: Reusable workflow for Trivy and Dockle to scan images + on: + workflow_call: + inputs: + platforms: + description: The platform to scan the image + required: true + type: string + default: '["linux/arm64", "linux/amd64"]' + source_image: + description: The image to clone + required: true + type: string + source_registry: + description: Image registry from which to pull the image + required: true + type: string + secrets: + registry_password: + description: The Github token or similar to authenticate with for the registry. + required: true + registry_username: + description: The username to authenticate with for the registry. + required: true + + jobs: + scan: + strategy: + matrix: + platform: ${{ fromJson(inputs.platforms) }} + runs-on: ubuntu-latest + name: Trivy + Dockle image scan + steps: + + - name: Login to ${{ inputs.source_registry }} + uses: docker/login-action@v3 + with: + registry: ${{ inputs.source_registry }} + username: ${{ secrets.registry_username }} + password: ${{ secrets.registry_password }} + + - name: Display platform + run: | + echo "Platform: ${{ matrix.platform }}" + + - name: check docker image exists + run: | + docker pull --platform ${{ matrix.platform }} ${{ inputs.source_registry }}/${{ inputs.source_image }} + + - name: Trivy - multi-arch + uses: aquasecurity/trivy-action@0.13.1 + with: + image-ref: ${{ inputs.source_registry }}/${{ inputs.source_image }} + format: "table" + exit-code: "1" + ignore-unfixed: true + vuln-type: "os,library" + severity: "CRITICAL,HIGH" + trivy-config: trivy.yaml + env: + TRIVY_PLATFORM: ${{ matrix.platform }} + + - name: Dockle - multi-arch + uses: hands-lab/dockle-action@v1 + with: + image: ${{ inputs.source_registry }}/${{ inputs.source_image }} + exit-code: "0" + exit-level: WARN