Skip to content

Release Publish

Release Publish #2

name: Release Publish
# Publish the redis-cli binaries built by "Release Build and Test" (+ the
# install script) to S3. Follows the redis-oss-release-automation contract used
# by redis-debian / redis-rpm: the binaries are NOT rebuilt here — they are
# downloaded from the build run identified by `release_handle.run_id`.
#
# Hosts (where install.sh points users):
# release_type=public -> https://packages.redis.io (CDN in front of the prod bucket; literal)
# release_type=internal -> https://<CLI_S3_BUCKET_STAGING>.s3.<CLI_S3_REGION_STAGING>.amazonaws.com
# (the staging bucket's S3 endpoint, derived from the secrets)
#
# Authentication follows redis-rpm: fully OIDC, with a separate IAM role per
# environment (no long-lived access keys). The public role is
# GitHub_OIDC_S3_Upload_RedisCliStatic.
#
# Required repository secrets (CLI_ prefix, mirroring redis-debian/redis-rpm):
# secrets.CLI_S3_IAM_ARN public IAM role (OIDC) to assume
# secrets.CLI_S3_IAM_ARN_STAGING internal IAM role (OIDC) to assume
# secrets.CLI_S3_BUCKET public bucket (served at packages.redis.io)
# secrets.CLI_S3_BUCKET_STAGING internal/staging bucket
# secrets.CLI_S3_REGION public bucket region
# secrets.CLI_S3_REGION_STAGING internal/staging bucket region
#
# The key prefix ("redis-cli") is the same in both buckets; only the bucket
# differs, matching how redis-debian keeps the "deb" prefix across environments.
on:
workflow_dispatch:
inputs:
release_tag:
description: 'Redis version/tag to publish (e.g. 8.8.0). Defaults to .redis_version.'
required: false
release_type:
description: 'Where to publish'
type: choice
options: [internal, public]
default: internal
workflow_uuid:
description: 'Optional UUID to identify this workflow run (used by release automation)'
required: false
release_handle:
description: 'JSON from the Release Build and Test run; provides run_id of the built artifacts.'
required: true
make_latest:
description: "Move the stable/latest pointers to this version (works for internal too, so staging can rehearse it)"
type: boolean
default: false
# UUID lets automation find this run in the list of workflow runs.
run-name: "Release Publish${{ inputs.workflow_uuid && format(': {0}', inputs.workflow_uuid) || '' }}"
permissions:
contents: read
actions: read # download artifacts from the build run
id-token: write # for AWS OIDC
jobs:
publish:
runs-on: ubuntu-latest
outputs:
base_url: ${{ steps.pub.outputs.base_url }}
prefix: ${{ steps.pub.outputs.prefix }}
release_tag: ${{ steps.v.outputs.release_tag }}
steps:
- uses: actions/checkout@v4
- name: Parse release handle
id: handle
run: |
HANDLE='${{ inputs.release_handle }}'
echo "$HANDLE" | jq . >/dev/null 2>&1 || { echo "release_handle is not valid JSON"; exit 1; }
RUN_ID="$(echo "$HANDLE" | jq -r '.run_id // empty')"
{ [ -n "$RUN_ID" ] && [[ "$RUN_ID" =~ ^[0-9]+$ ]]; } || { echo "run_id missing/invalid in release_handle"; exit 1; }
echo "run_id=$RUN_ID" >> "$GITHUB_OUTPUT"
- name: Resolve release tag
id: v
run: |
TAG="${{ inputs.release_tag }}"
[ -n "$TAG" ] || TAG="$(cat .redis_version)"
echo "release_tag=$TAG" >> "$GITHUB_OUTPUT"
# Pull the binaries built by the Release Build and Test run (its handle
# carries that run's id). No rebuild here.
- uses: actions/download-artifact@v4
with:
run-id: ${{ steps.handle.outputs.run_id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
path: dist-all
- name: Collect artifacts
run: |
mkdir -p dist
find dist-all -type f -name 'redis-cli-*' -exec cp {} dist/ \;
ls -l dist
ls dist/redis-cli-* >/dev/null 2>&1 || { echo "no redis-cli-* artifacts in build run ${{ steps.handle.outputs.run_id }}"; exit 1; }
# Fully OIDC (like redis-rpm): assume the per-environment role. The public
# role is GitHub_OIDC_S3_Upload_RedisCliStatic; staging has its own.
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ inputs.release_type == 'public' && secrets.CLI_S3_IAM_ARN || secrets.CLI_S3_IAM_ARN_STAGING }}
aws-region: ${{ inputs.release_type == 'public' && secrets.CLI_S3_REGION || secrets.CLI_S3_REGION_STAGING }}
- name: Publish to S3
id: pub
env:
# packages.redis.io is a CDN/vanity domain in front of the prod
# bucket — NOT the bucket's S3 endpoint — so it can't be derived and
# stays a literal. Staging is served straight from S3, so its read URL
# is derived from the bucket/region secrets to avoid drift.
PUBLIC_BASE_URL: https://packages.redis.io
# Same key prefix in both buckets; only the bucket differs.
PREFIX: redis-cli
BUCKET: ${{ inputs.release_type == 'public' && secrets.CLI_S3_BUCKET || secrets.CLI_S3_BUCKET_STAGING }}
REGION: ${{ inputs.release_type == 'public' && secrets.CLI_S3_REGION || secrets.CLI_S3_REGION_STAGING }}
run: |
if [ "${{ inputs.release_type }}" = "public" ]; then
BASE_URL="$PUBLIC_BASE_URL"
else
BASE_URL="https://${BUCKET}.s3.${REGION}.amazonaws.com"
fi
MAKE_LATEST=""
if [ "${{ inputs.release_type }}" = "public" ] && [ "${{ inputs.make_latest }}" = "true" ]; then
MAKE_LATEST="--make-latest"
fi
echo "Publishing release_type=${{ inputs.release_type }} bucket=$BUCKET base=$BASE_URL prefix=$PREFIX"
./publish.sh \
--version "${{ steps.v.outputs.release_tag }}" \
--bucket "$BUCKET" \
--base-url "$BASE_URL" \
--prefix "$PREFIX" \
--dist dist \
$MAKE_LATEST
echo "base_url=$BASE_URL" >> "$GITHUB_OUTPUT"
echo "prefix=$PREFIX" >> "$GITHUB_OUTPUT"
# Validate the just-published artifacts install and run across many distros.
# Runs natively per arch (amd64 on ubuntu-latest, arm64 on ubuntu-24.04-arm),
# so test-distros.sh's containers need no QEMU.
smoke-test:
needs: publish
strategy:
fail-fast: false
matrix:
include:
- { arch: amd64, runner: ubuntu-latest }
- { arch: arm64, runner: ubuntu-24.04-arm }
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
- name: Smoke test published artifacts across distros
env:
REDIS_CLI_BASE_URL: ${{ needs.publish.outputs.base_url }}/${{ needs.publish.outputs.prefix }}
run: ./test-distros.sh --arch ${{ matrix.arch }} --version "${{ needs.publish.outputs.release_tag }}"