From a15f556e1bb3b7749d37020247c8a4d8d51b0f63 Mon Sep 17 00:00:00 2001 From: parithosh Date: Tue, 24 Sep 2024 18:49:03 +0200 Subject: [PATCH] update CI --- .github/actions/deploy/action.yaml | 79 ++++++++++++++++++++++++++++ .github/actions/manifest/action.yaml | 73 +++++++++++++++++++++++++ .github/actions/prepare/action.yaml | 54 +++++++++++++++++++ .github/workflows/build-push.yaml | 78 +++++++++++++-------------- 4 files changed, 244 insertions(+), 40 deletions(-) create mode 100644 .github/actions/deploy/action.yaml create mode 100644 .github/actions/manifest/action.yaml create mode 100644 .github/actions/prepare/action.yaml diff --git a/.github/actions/deploy/action.yaml b/.github/actions/deploy/action.yaml new file mode 100644 index 0000000..ecc8df5 --- /dev/null +++ b/.github/actions/deploy/action.yaml @@ -0,0 +1,79 @@ +name: Deploy +description: Build and push a docker image to Docker Hub + +outputs: + tag: + description: "Tags for the docker image" + value: ${{ steps.meta.outputs.tags[0] }} + +inputs: + platform: + description: The platform to build for + type: string + required: true + build_args: + description: Build arguments to pass to the Docker build + default: "" + type: string + required: false + tag: + description: Docker hub tag to push to + type: string + required: true + # Secrets + DOCKER_USERNAME: + required: true + DOCKER_PASSWORD: + required: true + MACOS_PASSWORD: + required: true + +runs: + using: composite + steps: + - name: Checkout this repo + uses: actions/checkout@v4 + - name: Set up Docker Context for Buildx + shell: bash + id: buildx-context + run: | + docker context use builders || docker context create builders + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + endpoint: builders + - name: Unlock MacOS keychain for Docker Hub login + shell: bash + if: runner.os == 'macOS' + run: | + security -v unlock-keychain -p ${{ inputs.MACOS_PASSWORD }} ~/Library/Keychains/login.keychain-db + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ inputs.DOCKER_USERNAME }} + password: ${{ inputs.DOCKER_PASSWORD }} + - name: Generate slug + id: vars + shell: bash + run: | + echo "slug=$(echo '${{ inputs.platform }}' | tr '/' '-')" >> $GITHUB_OUTPUT + echo "DEBUG" + echo "${{ inputs.tag }}" + - name: Docker build & push + id: docker_build + uses: docker/build-push-action@v5 + with: + context: '.' + file: Dockerfile + tags: ${{ inputs.tag }}-${{ steps.vars.outputs.slug }} + push: true + platforms: ${{ inputs.platform }} + build-args: ${{ inputs.build_args }} + - name: Image digest & tags + shell: bash + run: | + cat << EOF + digest: ${{ steps.docker_build.outputs.digest }} + tags: + ${{ inputs.tag }}-${{ steps.vars.outputs.slug }} + EOF diff --git a/.github/actions/manifest/action.yaml b/.github/actions/manifest/action.yaml new file mode 100644 index 0000000..31a67aa --- /dev/null +++ b/.github/actions/manifest/action.yaml @@ -0,0 +1,73 @@ +name: Manifest +description: Build and push a docker manifest to Docker Hub + +inputs: + platforms: + # eg [{"platform":"linux/amd64", "runner": "ARM64", "slug": "something-arm64"},{"platform":"linux/arm64", "runner": "ubuntu-latest", "slug": "something-amd64"}] + description: JSON list of platforms to build for + type: string + required: true + tag: + description: Docker hub tag to push to + type: string + required: true + repository: + description: Docker hub repository to push to + type: string + required: true + DOCKER_USERNAME: + required: true + DOCKER_PASSWORD: + required: true + +runs: + using: composite + steps: + - name: Checkout this repo + uses: actions/checkout@v4 + - name: Generate images list + id: generate_images_list + shell: bash + run: | + PLATFORMS='${{ inputs.platforms }}' + + # Iterate over the platforms and build the image list + len=$(echo $PLATFORMS | jq '. | length') + for ((i=0; i<$len; i++)); do + slug=$(echo $PLATFORMS | jq -r --argjson i $i '.[$i].slug') + imagetag="${{ inputs.tag }}-$slug" + imagetag=$(echo $imagetag | cut -d ':' -f2) + image="${{ inputs.repository }}:$imagetag" + url="https://hub.docker.com/v2/repositories/${{ inputs.repository }}/tags?page_size=25&page=1&ordering=&name=$imagetag" + exists=$(curl -s $url | jq '.results | length > 0') + if [ "$exists" == "true" ]; then + IMAGES+="${{ inputs.tag }}-$slug " + fi + done + + IMAGES=${IMAGES::-1} # Remove the trailing space + echo "IMAGES: $IMAGES" + echo "images=$IMAGES" >> $GITHUB_OUTPUT + - name: Check if there is atleast one image + if: ${{ steps.generate_images_list.outputs.images == '[]' || steps.generate_images_list.outputs.images == '' }} + shell: bash + run: exit 1 + - name: Set up Docker Context for Buildx + shell: bash + id: buildx-context + run: | + docker context create builders + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + endpoint: builders + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ inputs.DOCKER_USERNAME }} + password: ${{ inputs.DOCKER_PASSWORD }} + - name: Create and push manifest images + shell: bash + run: | + docker buildx imagetools create --dry-run -t ${{ inputs.tag }} ${{ steps.generate_images_list.outputs.images }} + docker buildx imagetools create -t ${{ inputs.tag }} ${{ steps.generate_images_list.outputs.images }} diff --git a/.github/actions/prepare/action.yaml b/.github/actions/prepare/action.yaml new file mode 100644 index 0000000..063a109 --- /dev/null +++ b/.github/actions/prepare/action.yaml @@ -0,0 +1,54 @@ +name: 'Setup' +description: 'Read and parse config files for builds' +outputs: + platforms: + description: "Matrix of platforms and runner to use" + value: ${{ steps.setup_platforms.outputs.platforms }} + tag: + description: "Tag for the docker image" + value: ${{ steps.set_tag.outputs.tag }} +runs: + using: "composite" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - uses: mikefarah/yq@v4.35.1 + - name: Generate platform and runner matrix from config files + id: setup_platforms + shell: bash + run: | + PLATFORMS_JSON="[" + + # Extract the platforms + platforms=$(yq e ".ethereum-genesis-generator[]" platforms.yaml) + + for platform in $platforms; do + slug=$(echo "$platform" | tr '/' '-') + runner=$(yq e ".\"$platform\"" runners.yaml) + PLATFORMS_JSON+="{\"platform\":\"$platform\", \"runner\":\"$runner\", \"slug\":\"$slug\"}," + done + + PLATFORMS_JSON="${PLATFORMS_JSON%,}]" + echo "platforms=$PLATFORMS_JSON" >> $GITHUB_OUTPUT + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ethpandaops/ethereum-genesis-generator + flavor: latest=auto + tags: | + type=semver,pattern={{version}} + type=ref,event=pr + type=ref,event=branch + type=sha + type=match,event=tag,pattern=^v\d+\.\d+\.\d+$,group=0 + type=match,event=tag,pattern=^verkle-gen-v\d+\.\d+\.\d+$,group=0 + type=match,event=tag,pattern=^ephemery-v\d+\.\d+\.\d+$,group=0 + + - name: Set tag + id: set_tag + shell: bash + run: | + echo "tag=${{ fromJSON(steps.meta.outputs.json).tags[0] }}" >> $GITHUB_OUTPUT + + diff --git a/.github/workflows/build-push.yaml b/.github/workflows/build-push.yaml index c5206a0..b04d5cc 100644 --- a/.github/workflows/build-push.yaml +++ b/.github/workflows/build-push.yaml @@ -5,48 +5,46 @@ on: - master tags: - '**' + workflow_dispatch: + jobs: - build-push: - name: build-push + prepare: runs-on: ubuntu-latest + outputs: + platforms: ${{ steps.setup.outputs.platforms }} + tag: ${{ steps.setup.outputs.tag }} steps: - - name: Checkout this repo - uses: actions/checkout@v3 - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - name: Set up Docker Context for Buildx - shell: bash - id: buildx-context - run: | - docker context create builders - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - with: - endpoint: builders - - name: Docker meta - id: meta - uses: docker/metadata-action@v4 - with: - images: ethpandaops/ethereum-genesis-generator - flavor: latest=true - tags: | - type=semver,pattern=verkle-gen-{{version}} - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - - name: Login to Docker Hub - uses: docker/login-action@v2 + - uses: actions/checkout@v4 + - name: Prepare Matrix + id: setup + uses: ./.github/actions/prepare + deploy: + needs: + - prepare + runs-on: ${{ matrix.runner }} + continue-on-error: true + strategy: + matrix: + include: ${{fromJson(needs.prepare.outputs.platforms)}} + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/deploy with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - name: docker-build-push - id: docker_build - uses: docker/build-push-action@v4 + platform: ${{ matrix.platform }} + tag: ${{ needs.prepare.outputs.tag }} + DOCKER_USERNAME: "${{ secrets.DOCKER_USERNAME }}" + DOCKER_PASSWORD: "${{ secrets.DOCKER_PASSWORD }}" + manifest: + needs: + - prepare + - deploy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/manifest with: - context: . - file: Dockerfile - tags: ${{ steps.meta.outputs.tags }} - push: true - platforms: linux/amd64,linux/arm64 - - name: Image digest - run: echo ${{ steps.docker_build.outputs.digest }} \ No newline at end of file + tag: ${{ needs.prepare.outputs.tag }} + repository: ethpandaops/ethereum-genesis-generator + platforms: ${{ needs.prepare.outputs.platforms }} + DOCKER_USERNAME: "${{ secrets.DOCKER_USERNAME }}" + DOCKER_PASSWORD: "${{ secrets.DOCKER_PASSWORD }}"