Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
9356329
workflow that build redis and modules from unstable/master code (#21)
chenazulay Jul 7, 2025
5310c38
snap: add llvm and libclang-dev to build-packages for RediSearch (cla…
mike-golant Aug 28, 2025
1889b3f
Release automation: initial build and test actions
Peter-Sh Nov 19, 2025
b583484
Add upload and modify unstable.yml to use actions
Peter-Sh Nov 19, 2025
d3160e2
Release automation implementation, iteration #1
Peter-Sh Nov 24, 2025
4ef2557
Add on push to release_publish.yml to make it available for dispatch
Peter-Sh Nov 24, 2025
4b334da
Remove push
Peter-Sh Nov 24, 2025
46ff3df
Debug slack error
Peter-Sh Nov 25, 2025
793702a
Debug curl
Peter-Sh Nov 25, 2025
134a204
Refactor and fix slack msg
Peter-Sh Nov 25, 2025
403d507
Output slack response only in case of failure
Peter-Sh Nov 25, 2025
1bc86f4
Update workflow required fields
Peter-Sh Nov 25, 2025
6556396
Fix update version target branch
Peter-Sh Nov 25, 2025
4f85a3b
Use prefix for version branches to avoid confilts with existing tags
Peter-Sh Nov 25, 2025
3532282
Fix ensure release branch in tests
Peter-Sh Nov 25, 2025
a7d1968
Use actual release versions
Peter-Sh Nov 25, 2025
5ae80c9
Fix action name upload-packages -> upload
Peter-Sh Nov 25, 2025
9355724
Fix upload action arguments
Peter-Sh Nov 25, 2025
ba9af78
Allow to download artifacts from different workflows
Peter-Sh Nov 25, 2025
4ad1a5a
The fact is that snapcraft doesn't output json
Peter-Sh Nov 25, 2025
133d0b6
Fixes for running unstable, remove unused workflows
Peter-Sh Nov 26, 2025
5f0c7f6
Real fixes for running unstable
Peter-Sh Nov 26, 2025
d193178
Merge remote-tracking branch 'redis/master' into release_automation
Peter-Sh Nov 26, 2025
834740e
Try to make release_build_and_test.yml compatible with unstable
Peter-Sh Nov 26, 2025
b696884
Make release_publish available for dispatch
Peter-Sh Nov 27, 2025
d99a1ca
Fix unstable version in SNAP
Peter-Sh Nov 27, 2025
5559616
Added description into .redis_versions.json
Peter-Sh Nov 27, 2025
0f6ca51
Make release_build_and_test.yml available for dispatch
Peter-Sh Nov 27, 2025
af45d75
Remove technical on push condition
Peter-Sh Nov 27, 2025
9327a0b
Don't validate archive for unstable version
Peter-Sh Nov 27, 2025
7dbaa2f
Temporary use release_automatin as unstable, fix publising for unstable
Peter-Sh Nov 27, 2025
4c1d744
Fix curl invocation
Peter-Sh Nov 28, 2025
d6b5971
Use tee to capture snapcraft output
Peter-Sh Nov 28, 2025
fd5b778
Debug slack msg
Peter-Sh Nov 28, 2025
c9aea01
Improve slack error handling and fix success message
Peter-Sh Nov 28, 2025
fcd0831
Adapt unstable workflow
Peter-Sh Nov 28, 2025
7a3e7d8
Fix workflow syntax
Peter-Sh Nov 28, 2025
ca9d82b
publish should need build for unstable
Peter-Sh Nov 28, 2025
b3b1683
Add comments, fix PR workflow branches
Peter-Sh Nov 28, 2025
c3d31a8
Move determine verison to action, fix PR build
Peter-Sh Nov 28, 2025
94f0bea
Merge remote-tracking branch 'redis/unstable' into release_automation…
Peter-Sh Nov 28, 2025
1316ef6
Remove llvm and libclang-dev
Peter-Sh Nov 28, 2025
16409ce
Use actual unstable branch
Peter-Sh Nov 28, 2025
142c27b
Merge branch 'release_automation' into release_automation_unstable
Peter-Sh Nov 28, 2025
a422421
Removed calling unstable in PR to unstable
Peter-Sh Nov 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions .github/actions/build/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
name: 'Build Redis Snap'
description: 'Build Redis snap package with configurable version'
inputs:
version:
description: 'Redis version to build (e.g., "unstable", "8.4-rc1", or a tag like "7.2.4")'
required: true
architecture:
description: 'Architecture to build for (amd64 or arm64)'
required: true
outputs:
packages_list:
description: 'JSON list of built snap files'
value: ${{ steps.list-packages.outputs.packages_list }}

runs:
using: 'composite'
steps:
- name: Checkout Redis repository
uses: actions/checkout@v4
with:
repository: redis/redis
path: redis
ref: ${{ inputs.version }}

- name: Configure Redis modules to use master
if: inputs.version == 'unstable'
shell: bash
run: |
echo "Updating module versions to use master branch"
for module in redisbloom redisearch redistimeseries redisjson; do
if [ -f "redis/modules/${module}/Makefile" ]; then
echo "Updating ${module} to use master branch"
sed -i 's/MODULE_VERSION = .*/MODULE_VERSION = master/' "redis/modules/${module}/Makefile"
echo "Verifying ${module} version: $(grep "MODULE_VERSION" "redis/modules/${module}/Makefile")"
fi
done

- name: Setup Snapcraft
shell: bash
run: |
sudo snap install snapcraft --classic

- name: Setup LXD
uses: canonical/setup-lxd@v0.1.2

- name: Build Snap
shell: bash
env:
SNAPCRAFT_BUILD_INFO: 1
run: |
sudo snapcraft

- name: List built packages
id: list-packages
shell: bash
run: |
packages=$(ls *.snap | jq -R -s -c 'split("\n") | map(select(length > 0))')
echo "packages_list=$packages" >> $GITHUB_OUTPUT
echo "Built packages: $packages"

- name: Upload to artifacts
uses: actions/upload-artifact@v4
with:
name: redis-snap-${{ inputs.architecture }}-${{ github.sha }}
path: '*.snap'
retention-days: 1

- name: Capture build logs on failure
if: failure() && inputs.version == 'unstable'
shell: bash
run: |
mkdir -p /tmp/build-logs

echo "Build failed for snap on ${{ inputs.architecture }}"
echo "Capturing detailed logs for troubleshooting..."

# Get system info
uname -a > /tmp/build-logs/system-info.log 2>&1
snap --version > /tmp/build-logs/snap-info.log 2>&1
snapcraft --version >> /tmp/build-logs/snap-info.log 2>&1

# Get LXD container info
lxc list > /tmp/build-logs/lxc-list.log 2>&1 || echo "Failed to list LXC containers"
lxc info > /tmp/build-logs/lxc-info.log 2>&1 || echo "Failed to get LXC info"

# Get snap environment info
snap list > /tmp/build-logs/snap-list.log 2>&1

# Get Redis source info
if [ -d "redis" ]; then
(cd redis && git log -n 3) > /tmp/build-logs/redis-git-info.log 2>&1
find redis/modules -name "Makefile" -exec grep "MODULE_VERSION" {} \; > /tmp/build-logs/module-versions.log 2>&1
fi

# Get snap parts info if they exist
if [ -d "parts" ]; then
find parts -name "*.log" -exec cp {} /tmp/build-logs/ \; || echo "No part logs found"
find parts -type f -name "*.log" | sort > /tmp/build-logs/parts-logs-list.txt 2>&1
fi

# Create a summary file
{
echo "Build failure summary for snap on ${{ inputs.architecture }}"
echo "Date: $(date)"
echo "GitHub SHA: ${{ github.sha }}"
echo "Architecture: ${{ inputs.architecture }}"
echo "Version: ${{ inputs.version }}"
} > /tmp/build-logs/failure-summary.txt

echo "Log capture complete"

- name: Upload build failure logs
if: failure() && inputs.version == 'unstable'
uses: actions/upload-artifact@v4
with:
name: build-failure-${{ inputs.architecture }}-snap
path: /tmp/build-logs/
retention-days: 30
if-no-files-found: warn

151 changes: 151 additions & 0 deletions .github/actions/common/slack.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#!/bin/bash


# Send a Slack message using Bot Token API
# Reads JSON message from stdin, sends to Slack API
# Usage: slack_send_with_token "$SLACK_BOT_TOKEN" < message.json
slack_send_with_token() {
set -x
local token="$1"
local curl_stderr=$(mktemp)

# Run curl with verbose output, stderr to curl_stderr
if ! curl --fail-with-body -v -X POST https://api.slack.com/api/chat.postMessage \
-H "Authorization: Bearer $token" \
-H "Content-Type: application/json" \
-d @- 2>"$curl_stderr"; then
# If curl failed, output the error log
echo "curl command failed. Error log:" >&2
cat "$curl_stderr" >&2
rm -f "$curl_stderr"
return 1
fi

rm -f "$curl_stderr"
return 0
}

# Handle Slack API response and extract message metadata
# Reads JSON response from stdin
# If GITHUB_OUTPUT is set, writes slack_ts and slack_url to it
# Usage: slack_handle_message_result "$SLACK_CHANNEL_ID" < response.json
slack_handle_message_result() {
set -x
local channel_id="$1"
local message="$2"
local response=$(cat)

echo "Slack API Response:"

# Check if successful
if echo "$response" | jq -e '.ok == true' > /dev/null; then
local slack_ts=$(echo "$response" | jq -r '.ts')
local slack_channel=$(echo "$response" | jq -r '.channel')

# Convert timestamp to URL format (remove dot)
local ts_for_url=$(echo "$slack_ts" | tr -d '.')
local slack_url="https://redis.slack.com/archives/${slack_channel}/p${ts_for_url}"

# Write to GITHUB_OUTPUT if available
if [ -n "$GITHUB_OUTPUT" ]; then
echo "slack_ts=$slack_ts" >> "$GITHUB_OUTPUT"
echo "slack_url=$slack_url" >> "$GITHUB_OUTPUT"
fi

echo "✅ Message sent successfully!"
echo "Message URL: $slack_url"
return 0
else
local error=$(echo "$response" | jq -r '.error // "unknown"')
echo "❌ Failed to send Slack message: $error" >&2
echo "$response" | jq '.'
echo "Message content: $message" >&2
return 1
fi
}

slack_format_success_message() {
jq --arg channel "$1" --arg release_tag "$2" --arg footer "$3" --arg env "$4" '
{
"channel": $channel,
"icon_emoji": ":redis-circle:",
"text": (":ubuntu: SNAP Packages Published for Redis: " + $release_tag + " (" + $env + ")"),
"blocks": (
[
{
"type": "header",
"text": { "type": "plain_text", "text": (":ubuntu: SNAP Packages Published for Release " + $release_tag + " (" + $env + ")") }
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "The following packages have been published to https://snapcraft.io/redis"
}
}
] +
map({
"type": "section",
"text": {
"type": "mrkdwn",
"text": ("*" + .file + "* (revision: " + .revision + ")")
}
}) +
[
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": $footer }
]
}
]
)
}'
}

slack_format_failure_message() {
channel=$1
header=$2
workflow_url=$3
footer=$4
if [ -z "$header" ]; then
header=" "
fi
if [ -z "$footer" ]; then
footer=" "
fi

# Create Slack message payload
cat << EOF
{
"channel": "$channel",
"icon_emoji": ":redis-circle:",
"text": "$header",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "❌ $header"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Workflow run: $workflow_url"
}
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "$footer"
}
]
}
]
}
EOF
}
47 changes: 47 additions & 0 deletions .github/actions/determine-version/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: 'Determine Redis Version'
description: 'Determine Redis version to build based on risk level from .redis_versions.json'
inputs:
risk_level:
description: 'Risk level (edge, candidate, stable)'
required: true

outputs:
redis_version:
description: 'Redis version to build (e.g., "8.4.0", "unstable")'
value: ${{ steps.determine-version.outputs.redis_version }}

runs:
using: 'composite'
steps:
- name: Validate risk level
shell: bash
run: |
if [[ ! "${{ inputs.risk_level }}" =~ ^(edge|candidate|stable)$ ]]; then
echo "Error: risk_level must be one of: edge, candidate, stable"
echo "Provided value: ${{ inputs.risk_level }}"
exit 1
fi
echo "Risk level validation passed: ${{ inputs.risk_level }}"

- name: Determine Redis version from risk level
id: determine-version
shell: bash
run: |
if [ ! -f ".redis_versions.json" ]; then
echo "Error: .redis_versions.json not found"
exit 1
fi

REDIS_VERSION=$(jq -r ".${{ inputs.risk_level }}" .redis_versions.json)

if [ "$REDIS_VERSION" = "null" ] || [ -z "$REDIS_VERSION" ]; then
echo "Error: Risk level '${{ inputs.risk_level }}' not found in .redis_versions.json"
echo "Available risk levels:"
jq -r 'keys[]' .redis_versions.json
exit 1
fi

echo "Risk level: ${{ inputs.risk_level }}"
echo "Redis version: $REDIS_VERSION"
echo "redis_version=$REDIS_VERSION" >> $GITHUB_OUTPUT

Loading
Loading