v1.33.0 #35
Workflow file for this run
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: Docker Release-v2 | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| TAG_NAME: | |
| description: 'Tag name that the major tag will point to' | |
| required: true | |
| PRERELEASE: | |
| description: 'Whether this is a prerelease' | |
| type: boolean | |
| required: true | |
| release: | |
| types: [published] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} | |
| IS_PRERELEASE: ${{ github.event.release.prerelease || github.event.inputs.PRERELEASE }} | |
| IMAGE: ghcr.io/dragonflydb/dragonfly | |
| GCS_IMAGE: us-central1-docker.pkg.dev/dragonflydb-public/dragonfly-registry/dragonfly | |
| jobs: | |
| build_and_tag: | |
| name: Build and Push ${{matrix.flavor}} ${{ matrix.os.arch }} image | |
| strategy: | |
| matrix: | |
| flavor: [ubuntu] | |
| 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@v4 | |
| with: | |
| fetch-depth: 0 | |
| submodules: true | |
| - name: Set up Docker Build | |
| uses: docker/setup-buildx-action@v3 | |
| - 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: Fetch release asset | |
| uses: dsaltares/fetch-gh-release-asset@1.1.2 | |
| with: | |
| version: "tags/${{ env.TAG_NAME }}" | |
| regex: true | |
| file: "dragonfly-.*\\.tar\\.gz" | |
| target: 'releases/' | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract artifacts | |
| run: | | |
| echo "Event prerelease ${{ github.event.release.prerelease }}" | |
| echo "Input prerelease ${{ github.event.inputs.PRERELEASE }}" | |
| ls -l | |
| ls -l releases | |
| for f in releases/*.tar.gz; do tar xvfz $f -C releases; done | |
| rm releases/*.tar.gz | |
| - name: Docker meta | |
| id: metadata | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: | | |
| ${{ env.IMAGE }} | |
| ${{ env.GCS_IMAGE }} | |
| flavor: | | |
| latest=false | |
| prefix=${{ matrix.flavor}}- | |
| suffix=-${{ matrix.os.arch }} | |
| tags: | | |
| type=semver,pattern={{version}},enable=true,value=${{ env.TAG_NAME }} | |
| type=semver,pattern={{raw}},enable=true,value=${{ env.TAG_NAME }} | |
| type=ref,event=pr | |
| labels: | | |
| org.opencontainers.image.vendor=DragonflyDB LTD | |
| org.opencontainers.image.title=Dragonfly Production Image | |
| org.opencontainers.image.description=The fastest in-memory store | |
| org.opencontainers.image.version=${{ env.TAG_NAME }} | |
| - name: Build image | |
| id: build | |
| uses: docker/build-push-action@v6 | |
| 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 }}-prod | |
| cache-from: type=gha,scope=prod-${{ matrix.flavor }} | |
| cache-to: type=gha,scope=prod-${{ matrix.flavor }},mode=max | |
| load: true # Load the build images into the local docker. | |
| - name: Test Image | |
| uses: ./.github/actions/test-docker | |
| timeout-minutes: 1 | |
| with: | |
| image_id: ${{ env.IMAGE }}@${{ steps.build.outputs.digest }} | |
| name: ${{ matrix.flavor }}-${{ matrix.os.arch }} | |
| - id: output-sha | |
| run: | | |
| echo "sha_${{ matrix.os.arch }}=${{ steps.build.outputs.digest }}" >> $GITHUB_OUTPUT | |
| outputs: | |
| sha_amd: ${{ steps.output-sha.outputs.sha_amd64 }} | |
| sha_arm: ${{ steps.output-sha.outputs.sha_arm64 }} | |
| merge_manifest: | |
| needs: [build_and_tag] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| flavor: [ubuntu] | |
| steps: | |
| - name: checkout | |
| uses: actions/checkout@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: Merge and Push | |
| run: | | |
| # Function to create and push manifests for a given registry | |
| create_and_push_manifests() { | |
| local registry=$1 | |
| local sha_amd=$2 | |
| local sha_arm=$3 | |
| local flavor=$4 | |
| local tag_name=$5 | |
| local is_prerelease=$6 | |
| # Function for semantic version comparison | |
| # Returns true if current_version >= latest_version | |
| semver_cmp() { | |
| local current_version=$1 | |
| local latest_version=$2 | |
| local should_update=true | |
| # Extract major.minor.patch components | |
| IFS='.' read -ra CURRENT_PARTS <<< "$current_version" | |
| IFS='.' read -ra LATEST_PARTS <<< "$latest_version" | |
| # Pad arrays to same length for comparison | |
| while [ ${#CURRENT_PARTS[@]} -lt 3 ]; do CURRENT_PARTS+=(0); done | |
| while [ ${#LATEST_PARTS[@]} -lt 3 ]; do LATEST_PARTS+=(0); done | |
| # Compare major.minor.patch numerically | |
| if (( 10#${CURRENT_PARTS[0]} < 10#${LATEST_PARTS[0]} )); then | |
| should_update=false | |
| elif (( 10#${CURRENT_PARTS[0]} == 10#${LATEST_PARTS[0]} )) && (( 10#${CURRENT_PARTS[1]} < 10#${LATEST_PARTS[1]} )); then | |
| should_update=false | |
| elif (( 10#${CURRENT_PARTS[0]} == 10#${LATEST_PARTS[0]} )) && (( 10#${CURRENT_PARTS[1]} == 10#${LATEST_PARTS[1]} )) && (( 10#${CURRENT_PARTS[2]} < 10#${LATEST_PARTS[2]} )); then | |
| should_update=false | |
| fi | |
| # Log debug info to stderr instead of stdout | |
| echo "Version comparison: current=${CURRENT_PARTS[0]}.${CURRENT_PARTS[1]}.${CURRENT_PARTS[2]} vs latest=${LATEST_PARTS[0]}.${LATEST_PARTS[1]}.${LATEST_PARTS[2]}" >&2 | |
| # Return only the result | |
| echo $should_update | |
| } | |
| if [[ "$is_prerelease" == 'true' ]]; then | |
| # Create and push the manifest like dragonfly:alpha-ubuntu | |
| tag="${registry}:alpha-${flavor}" | |
| docker manifest create ${tag} --amend ${sha_amd} --amend ${sha_arm} | |
| docker manifest push ${tag} | |
| elif [[ "$flavor" == 'ubuntu' ]]; then | |
| # Checking if this version should be tagged as latest | |
| echo "Checking if ${tag_name} should be tagged as latest..." | |
| # Remove 'v' prefix if present for semantic comparison | |
| current_version=${tag_name#v} | |
| # Get the current latest version by running the latest image | |
| latest_version="" | |
| if docker pull ${registry}:latest &>/dev/null; then | |
| echo "Found latest tag, checking its version..." | |
| # First try to get version from image labels using docker inspect | |
| echo "Method 1: Trying to get version from image labels..." | |
| label_version=$(docker image inspect --format '{{ index .Config.Labels "org.opencontainers.image.version" }}' ${registry}:latest 2>/dev/null || echo "") | |
| if [[ -n "$label_version" ]]; then | |
| echo "Found version from image labels: $label_version" | |
| # Extract version from format like "ubuntu-1.28.1-arm64" | |
| if [[ $label_version == ubuntu-*-* ]]; then | |
| # Extract the middle part (version) from ubuntu-VERSION-arch | |
| latest_full_version=$(echo "$label_version" | cut -d'-' -f2) | |
| else | |
| # Use the label as is | |
| latest_full_version=$label_version | |
| fi | |
| echo "Extracted version: $latest_full_version" | |
| else | |
| # Fallback to running the container if label inspect failed | |
| echo "Method 2: Falling back to container execution..." | |
| latest_full_version=$(docker run --rm --entrypoint /bin/sh ${registry}:latest -c "dragonfly --version | cut -d' ' -f2 | head -n 1") | |
| fi | |
| echo "Latest full version: ${latest_full_version}" | |
| # Extract only the semantic version part (before any dash) | |
| latest_version=$(echo "${latest_full_version}" | cut -d'-' -f1) | |
| # Remove 'v' prefix if present | |
| latest_version=${latest_version#v} | |
| echo "Current latest version: ${latest_version}" | |
| else | |
| echo "No latest tag found yet or couldn't pull it" | |
| fi | |
| # Compare versions only if we have a latest version | |
| should_update_latest=true | |
| if [[ -n "$latest_version" ]]; then | |
| # Call our semver comparison function | |
| should_update_latest=$(semver_cmp "$current_version" "$latest_version") | |
| fi | |
| if [[ "$should_update_latest" == true ]]; then | |
| echo "Version ${tag_name} is newer than or equal to current latest, updating latest tag" | |
| tag="${registry}:latest" | |
| # Create and push the manifest like dragonfly:latest | |
| docker manifest create ${tag} --amend ${sha_amd} --amend ${sha_arm} | |
| docker manifest push ${tag} | |
| else | |
| echo "Version ${tag_name} is older than current latest (${latest_version}), NOT updating latest tag" | |
| fi | |
| fi | |
| # Create and push the manifest like dragonfly:v1.26.4 | |
| tag="${registry}:${tag_name}" | |
| docker manifest create ${tag} --amend ${sha_amd} --amend ${sha_arm} | |
| docker manifest push ${tag} | |
| } | |
| # GitHub Container Registry manifests | |
| ghcr_sha_amd=${{ env.IMAGE }}@${{ needs.build_and_tag.outputs.sha_amd }} | |
| ghcr_sha_arm=${{ env.IMAGE }}@${{ needs.build_and_tag.outputs.sha_arm }} | |
| create_and_push_manifests "${{ env.IMAGE }}" "$ghcr_sha_amd" "$ghcr_sha_arm" "${{ matrix.flavor }}" "${{ env.TAG_NAME }}" "${{ env.IS_PRERELEASE }}" | |
| # Google Artifact Registry manifests | |
| gar_sha_amd=${{ env.GCS_IMAGE }}@${{ needs.build_and_tag.outputs.sha_amd }} | |
| gar_sha_arm=${{ env.GCS_IMAGE }}@${{ needs.build_and_tag.outputs.sha_arm }} | |
| create_and_push_manifests "${{ env.GCS_IMAGE }}" "$gar_sha_amd" "$gar_sha_arm" "${{ matrix.flavor }}" "${{ env.TAG_NAME }}" "${{ env.IS_PRERELEASE }}" | |
| release_helm_and_notify: | |
| needs: [merge_manifest] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: print_env | |
| run: env | |
| - name: checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install helm | |
| uses: azure/setup-helm@v4 | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| - name: Configure Git | |
| if: env.IS_PRERELEASE != 'true' | |
| run: | | |
| git config user.name "$GITHUB_ACTOR" | |
| git config user.email "$GITHUB_ACTOR@users.noreply.github.com" | |
| - name: Update helm chart | |
| if: env.IS_PRERELEASE != 'true' | |
| run: | | |
| git checkout main | |
| sed -Ei \ | |
| -e 's/^(version\:) .*/\1 '${{ env.TAG_NAME }}'/g' \ | |
| -e 's/^(appVersion\:) .*/\1 "'${{ env.TAG_NAME }}'"/g' \ | |
| contrib/charts/dragonfly/Chart.yaml | |
| go test ./contrib/charts/dragonfly/... -update | |
| git commit \ | |
| -m 'chore(helm-chart): update to ${{ env.TAG_NAME }}' \ | |
| contrib/charts/dragonfly/Chart.yaml \ | |
| contrib/charts/dragonfly/ci || true | |
| - name: Push Helm chart as OCI to Github | |
| if: env.IS_PRERELEASE != 'true' | |
| run: | | |
| echo "${{ secrets.GITHUB_TOKEN }}" | \ | |
| helm registry login -u ${{ github.actor }} --password-stdin ghcr.io | |
| helm package contrib/charts/dragonfly | |
| helm push dragonfly-${{ env.TAG_NAME }}.tgz oci://ghcr.io/${{ github.repository }}/helm | |
| - name: GitHub Push | |
| uses: CasperWA/push-protected@v2 | |
| if: env.IS_PRERELEASE != 'true' | |
| with: | |
| token: ${{ secrets.DRAGONFLY_TOKEN }} | |
| branch: main | |
| - name: Discord notification | |
| env: | |
| DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} | |
| uses: Ilshidur/action-discord@0c4b27844ba47cb1c7bee539c8eead5284ce9fa9 | |
| with: | |
| args: 'DragonflyDB version [${{ env.TAG_NAME }}](https://github.com/dragonflydb/dragonfly/releases/tag/${{ env.TAG_NAME }}) has been released 🎉' | |
| - name: Re-build Docs | |
| if: env.IS_PRERELEASE != 'true' | |
| run: | | |
| curl -s -X POST '${{ secrets.VERCEL_DOCS_WEBHOOK }}' |