Development Docker Build #583
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Development Docker Build | |
| on: | |
| schedule: | |
| - cron: '15 0 * * *' | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| image: ghcr.io/dragonflydb/dragonfly-dev | |
| GCS_IMAGE: us-central1-docker.pkg.dev/dragonflydb-public/dragonfly-registry/dragonfly-dev | |
| jobs: | |
| build_and_tag: | |
| if: github.repository == 'dragonflydb/dragonfly' | |
| name: Build and Push ${{matrix.flavor}} ${{ matrix.os.arch }} image | |
| strategy: | |
| matrix: | |
| flavor: [alpine,ubuntu,distroless] | |
| os: | |
| - image: ubuntu-24.04 | |
| arch: amd64 | |
| - image: ubuntu-24.04-arm | |
| arch: arm64 | |
| runs-on: ${{ matrix.os.image }} | |
| permissions: | |
| contents: read | |
| packages: write | |
| id-token: write | |
| steps: | |
| - name: checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 1 | |
| submodules: true | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Login to Registries | |
| uses: ./.github/actions/multi-registry-docker-login | |
| with: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} | |
| - name: Authenticate to Google Cloud | |
| uses: google-github-actions/auth@v3 | |
| with: | |
| credentials_json: ${{ secrets.GCP_SA_KEY }} | |
| - name: Configure AWS Credentials | |
| if: github.repository_owner == 'dragonflydb' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) | |
| uses: aws-actions/configure-aws-credentials@v6 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_CI_S3_ROLE_ARN }} | |
| aws-region: us-east-1 | |
| - name: Get Build Information | |
| id: build_info | |
| run: | | |
| echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT | |
| - name: Docker meta | |
| id: metadata | |
| uses: docker/metadata-action@v6 | |
| with: | |
| images: | | |
| ${{ env.image }} | |
| ${{ env.GCS_IMAGE }} | |
| tags: | | |
| type=sha,enable=true,prefix=${{ matrix.flavor}}-,suffix=-${{ matrix.os.arch }},format=short | |
| labels: | | |
| org.opencontainers.image.vendor=DragonflyDB LTD | |
| org.opencontainers.image.title=Dragonfly Development Image | |
| org.opencontainers.image.description=The fastest in-memory store | |
| - name: Build image | |
| id: build | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| push: true | |
| provenance: false # Prevent pushing a docker manifest | |
| tags: | | |
| ${{ steps.metadata.outputs.tags }} | |
| labels: ${{ steps.metadata.outputs.labels }} | |
| file: tools/packaging/Dockerfile.${{ matrix.flavor }}-dev | |
| cache-from: type=gha,scope=tagged${{ matrix.flavor }} | |
| cache-to: type=gha,scope=tagged${{ matrix.flavor }},mode=max | |
| load: true # Load the build images into the local docker. | |
| - name: Test Image | |
| run: | | |
| echo ${{ steps.build.outputs.digest }} | |
| image_tags=(${{ steps.metadata.outputs.tags }}) | |
| # install redis-tools | |
| sudo apt-get update && sudo apt-get install redis-tools -y | |
| for image_tag in "${image_tags[@]}"; do | |
| echo "Testing image: ${image_tag}" | |
| docker image inspect ${image_tag} | |
| echo "Testing ${{ matrix.flavor }} image" | |
| # docker run with port-forwarding | |
| docker run -d -p 6379:6379 ${image_tag} | |
| sleep 5 | |
| redis-cli -h localhost ping | grep -q "PONG" || exit 1 | |
| docker stop $(docker ps -q --filter ancestor=${image_tag}) | |
| done | |
| - name: Extract and Upload Binaries | |
| if: matrix.flavor == 'ubuntu' # Only run once per flavor | |
| run: | | |
| # Get the image tag | |
| image_tags=(${{ steps.metadata.outputs.tags }}) | |
| image_tag=${image_tags[0]} | |
| # Extract version from the image | |
| echo "Extracting version from image..." | |
| VERSION=$(docker run --rm ${image_tag} dragonfly --version | sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]//g" | head -n1 | cut -d' ' -f2 | cut -d'-' -f1) | |
| # Check if version starts with a release version (v*.*.*) | |
| if [[ ! $VERSION =~ ^v[0-9]+\.[0-9]+\.[0-9]+ ]]; then | |
| # Get the latest release version to use as prefix | |
| LATEST_RELEASE=$(curl -s https://api.github.com/repos/dragonflydb/dragonfly/releases/latest | jq -r .tag_name) | |
| VERSION="${LATEST_RELEASE}+${VERSION}" | |
| fi | |
| echo "Dragonfly version: $VERSION" | |
| echo "Extracting binary from ${image_tag} for ${{ matrix.os.arch }}" | |
| # Create a temporary container and copy the binary | |
| container_id=$(docker create ${image_tag}) | |
| docker cp ${container_id}:/usr/local/bin/dragonfly ./dragonfly | |
| docker rm ${container_id} | |
| # Create a tar archive | |
| if [[ "${{ matrix.os.arch }}" == "arm64" ]]; then | |
| arch_name="aarch64" | |
| else | |
| arch_name="x86_64" | |
| fi | |
| tar_name="dragonfly-${arch_name}-dbgsym.tar.gz" | |
| tar czf ${tar_name} dragonfly | |
| # Upload to GCS | |
| echo "Uploading ${tar_name} to GCS" | |
| gcloud storage cp "$tar_name" "gs://${{ secrets.STAGING_BINARY_BUCKET }}/dragonfly/$VERSION/$tar_name" | |
| # Upload to AWS | |
| echo "Uploading ${tar_name} to AWS" | |
| aws s3 cp "$tar_name" "s3://${{ secrets.STAGING_BINARY_BUCKET }}/dragonfly/$VERSION/$tar_name" | |
| # Cleanup | |
| rm -f dragonfly ${tar_name} | |
| outputs: | |
| # matrix jobs outputs override each other, but we use the same sha | |
| # for all images, so we can use the same output name. | |
| sha: ${{ steps.build_info.outputs.short_sha }} | |
| merge_manifest: | |
| if: github.repository == 'dragonflydb/dragonfly' | |
| needs: [build_and_tag] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| flavor: [alpine,ubuntu,distroless] | |
| steps: | |
| - name: checkout | |
| uses: actions/checkout@v6 | |
| - name: Login to Registries | |
| uses: ./.github/actions/multi-registry-docker-login | |
| with: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} | |
| - name: Merge and Push | |
| run: | | |
| # Function to create and push manifests for a given registry | |
| create_and_push_manifests() { | |
| local registry=$1 | |
| local flavor=$2 | |
| local sha=$3 | |
| # Create and push the manifest like dragonfly-dev:alpine-<sha> | |
| local sha_tag="${registry}:${flavor}-${sha}" | |
| docker manifest create ${sha_tag} --amend ${sha_tag}-amd64 --amend ${sha_tag}-arm64 | |
| docker manifest push ${sha_tag} | |
| # Create and push the manifest like dragonfly-dev:alpine | |
| local flavor_tag="${registry}:${flavor}" | |
| docker manifest create ${flavor_tag} --amend ${sha_tag}-amd64 --amend ${sha_tag}-arm64 | |
| docker manifest push ${flavor_tag} | |
| } | |
| # GitHub Container Registry manifests | |
| create_and_push_manifests "${{ env.image }}" "${{ matrix.flavor }}" "${{ needs.build_and_tag.outputs.sha }}" | |
| # Google Artifact Registry manifests | |
| create_and_push_manifests "${{ env.GCS_IMAGE }}" "${{ matrix.flavor }}" "${{ needs.build_and_tag.outputs.sha }}" |