diff --git a/.github/WORKFLOWS.md b/.github/WORKFLOWS.md index 3efa125..b436437 100644 --- a/.github/WORKFLOWS.md +++ b/.github/WORKFLOWS.md @@ -22,12 +22,12 @@ Automates chart releases: - Publishes to GitHub Pages (Helm repository) - Updates Artifact Hub -### 3. Auto-Update Valkey Version (`update-valkey-version.yml`) +### 3. Auto-Update Versions (`update-valkey-version.yml`) **Trigger**: - Weekly schedule (Mondays at 9:00 AM UTC) - Manual dispatch -Automatically keeps Valkey version up-to-date: +Automatically keeps Valkey and redis-exporter versions up-to-date: #### How It Works @@ -49,19 +49,23 @@ graph TD #### What It Does 1. **Version Detection** - - Pulls the latest Chainguard Valkey image - - Runs `valkey-server --version` to detect the exact version - - Compares with current `appVersion` in `Chart.yaml` + - **Valkey**: Pulls `cgr.dev/chainguard/valkey:latest` and runs `--version` + - **Redis-exporter**: Queries GitHub API for latest `oliver006/redis_exporter` release + - Compares both with current versions in chart files -2. **If Version Changed** - - Updates `appVersion` in `Chart.yaml` to the new version +2. **If Any Version Changed** + - **Valkey update**: Updates `appVersion` in `Chart.yaml` + - **Exporter update**: Updates `values.yaml`, `values.schema.json`, and `Chart.yaml` annotations - Bumps the chart patch version (e.g., `0.2.0` → `0.2.1`) - - Adds entry to `CHANGELOG.md` with the version change + - Adds entry to `CHANGELOG.md` with version changes - Creates a pull request with all changes 3. **Pull Request Contents** - - Clear title: `chore: update Valkey to version X.Y.Z` - - Detailed body with old → new version info + - Dynamic title based on what updated: + - `chore: update Valkey to X.Y.Z` (Valkey only) + - `chore: update redis-exporter to X.Y.Z` (exporter only) + - `chore: update Valkey and redis-exporter` (both) + - Detailed body with old → new version info for each component - Labeled as `automated`, `version-update`, `dependencies` - Ready for review and merge @@ -84,11 +88,12 @@ This is useful when you want to check for updates immediately instead of waiting #### Why This Approach? **Benefits:** -- ✅ Chart stays current with latest Valkey releases +- ✅ Chart stays current with latest Valkey and redis-exporter releases - ✅ Security updates are tracked and applied quickly - ✅ Full transparency via pull requests - ✅ Human review before changes are published - ✅ Automatic changelog maintenance +- ✅ Both core application and metrics tooling kept in sync **Trade-offs:** - ⚠️ Chainguard free tier only provides `latest` tag diff --git a/.github/workflows/update-valkey-version.yml b/.github/workflows/update-valkey-version.yml index e2f32d4..d632896 100644 --- a/.github/workflows/update-valkey-version.yml +++ b/.github/workflows/update-valkey-version.yml @@ -44,43 +44,117 @@ jobs: echo "current_version=$CURRENT" >> $GITHUB_OUTPUT echo "Current appVersion: $CURRENT" - - name: Compare versions - id: compare + - name: Compare Valkey versions + id: compare-valkey run: | DETECTED="${{ steps.get-version.outputs.detected_version }}" CURRENT="${{ steps.current-version.outputs.current_version }}" if [ "$DETECTED" != "$CURRENT" ]; then + echo "valkey_needs_update=true" >> $GITHUB_OUTPUT + echo "Valkey version mismatch: $CURRENT -> $DETECTED" + else + echo "valkey_needs_update=false" >> $GITHUB_OUTPUT + echo "Valkey version is up to date: $CURRENT" + fi + + - name: Get latest redis-exporter version from GitHub + id: get-exporter-version + run: | + # Get latest release from GitHub API + LATEST=$(curl -s https://api.github.com/repos/oliver006/redis_exporter/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') + + if [ -z "$LATEST" ]; then + echo "Failed to detect redis-exporter version" + exit 1 + fi + + echo "detected_exporter_version=$LATEST" >> $GITHUB_OUTPUT + echo "Detected redis-exporter version: $LATEST" + + - name: Get current redis-exporter version from values.yaml + id: current-exporter-version + run: | + # Extract tag from metrics section (more robust method) + CURRENT=$(awk '/^metrics:/,/^[a-z]+:/ {if (/^\s+tag:/) {print $2; exit}}' values.yaml | tr -d '"') + echo "current_exporter_version=$CURRENT" >> $GITHUB_OUTPUT + echo "Current redis-exporter version: $CURRENT" + + - name: Compare redis-exporter versions + id: compare-exporter + run: | + DETECTED="${{ steps.get-exporter-version.outputs.detected_exporter_version }}" + CURRENT="${{ steps.current-exporter-version.outputs.current_exporter_version }}" + + if [ "$DETECTED" != "$CURRENT" ]; then + echo "exporter_needs_update=true" >> $GITHUB_OUTPUT + echo "Redis-exporter version mismatch: $CURRENT -> $DETECTED" + else + echo "exporter_needs_update=false" >> $GITHUB_OUTPUT + echo "Redis-exporter version is up to date: $CURRENT" + fi + + - name: Check if any update is needed + id: compare + run: | + VALKEY_UPDATE="${{ steps.compare-valkey.outputs.valkey_needs_update }}" + EXPORTER_UPDATE="${{ steps.compare-exporter.outputs.exporter_needs_update }}" + + if [ "$VALKEY_UPDATE" == "true" ] || [ "$EXPORTER_UPDATE" == "true" ]; then echo "needs_update=true" >> $GITHUB_OUTPUT - echo "Version mismatch detected: $CURRENT -> $DETECTED" + echo "Updates needed - Valkey: $VALKEY_UPDATE, Exporter: $EXPORTER_UPDATE" else echo "needs_update=false" >> $GITHUB_OUTPUT - echo "Version is up to date: $CURRENT" + echo "All versions are up to date" fi - - name: Update Chart.yaml - if: steps.compare.outputs.needs_update == 'true' + - name: Update redis-exporter version + if: steps.compare-exporter.outputs.exporter_needs_update == 'true' + run: | + NEW_EXPORTER_VERSION="${{ steps.get-exporter-version.outputs.detected_exporter_version }}" + + # Update values.yaml + sed -i "/metrics:/,/pullPolicy:/ s|tag: .*|tag: \"$NEW_EXPORTER_VERSION\"|" values.yaml + + # Update values.schema.json + sed -i "s|\"default\": \"v[0-9]*\.[0-9]*\.[0-9]*\"|\"default\": \"$NEW_EXPORTER_VERSION\"|g" values.schema.json + + # Update Chart.yaml annotations (redis-exporter image reference) + sed -i "s|oliver006/redis_exporter:v[0-9]*\.[0-9]*\.[0-9]*|oliver006/redis_exporter:$NEW_EXPORTER_VERSION|g" Chart.yaml + + echo "Updated redis-exporter to $NEW_EXPORTER_VERSION" + + - name: Update Valkey version in Chart.yaml + if: steps.compare-valkey.outputs.valkey_needs_update == 'true' run: | NEW_VERSION="${{ steps.get-version.outputs.detected_version }}" # Update appVersion in Chart.yaml sed -i "s/^appVersion: .*/appVersion: \"$NEW_VERSION\"/" Chart.yaml + echo "Updated Valkey appVersion to $NEW_VERSION" + + - name: Bump chart version + if: steps.compare.outputs.needs_update == 'true' + run: | # Bump patch version of chart CHART_VERSION=$(grep '^version:' Chart.yaml | awk '{print $2}') - # Simple patch bump (you might want to use semver tool for production) NEW_CHART_VERSION=$(echo $CHART_VERSION | awk -F. '{$NF = $NF + 1;} 1' | sed 's/ /./g') sed -i "s/^version: .*/version: $NEW_CHART_VERSION/" Chart.yaml - echo "Updated appVersion to $NEW_VERSION" echo "Updated chart version to $NEW_CHART_VERSION" - name: Update CHANGELOG if: steps.compare.outputs.needs_update == 'true' run: | - NEW_VERSION="${{ steps.get-version.outputs.detected_version }}" CHART_VERSION=$(grep '^version:' Chart.yaml | awk '{print $2}') DATE=$(date +%Y-%m-%d) + VALKEY_UPDATE="${{ steps.compare-valkey.outputs.valkey_needs_update }}" + EXPORTER_UPDATE="${{ steps.compare-exporter.outputs.exporter_needs_update }}" + NEW_VALKEY="${{ steps.get-version.outputs.detected_version }}" + OLD_VALKEY="${{ steps.current-version.outputs.current_version }}" + NEW_EXPORTER="${{ steps.get-exporter-version.outputs.detected_exporter_version }}" + OLD_EXPORTER="${{ steps.current-exporter-version.outputs.current_exporter_version }}" # Create or update CHANGELOG if [ ! -f CHANGELOG.md ]; then @@ -88,6 +162,15 @@ jobs: echo "" >> CHANGELOG.md fi + # Build changelog entry + CHANGES="" + if [ "$VALKEY_UPDATE" == "true" ]; then + CHANGES="${CHANGES}- Updated Valkey from $OLD_VALKEY to $NEW_VALKEY (from Chainguard latest image)\n" + fi + if [ "$EXPORTER_UPDATE" == "true" ]; then + CHANGES="${CHANGES}- Updated redis-exporter from $OLD_EXPORTER to $NEW_EXPORTER\n" + fi + # Add new entry using a temp file (compatible with both Linux and macOS) { head -n 2 CHANGELOG.md @@ -95,38 +178,61 @@ jobs: echo "## [$CHART_VERSION] - $DATE" echo "" echo "### Changed" - echo "- Updated Valkey to version $NEW_VERSION (from Chainguard latest image)" - echo "" + echo -e "$CHANGES" tail -n +3 CHANGELOG.md } > CHANGELOG.tmp && mv CHANGELOG.tmp CHANGELOG.md + - name: Generate PR title and description + if: steps.compare.outputs.needs_update == 'true' + id: pr-content + run: | + VALKEY_UPDATE="${{ steps.compare-valkey.outputs.valkey_needs_update }}" + EXPORTER_UPDATE="${{ steps.compare-exporter.outputs.exporter_needs_update }}" + + # Generate title + if [ "$VALKEY_UPDATE" == "true" ] && [ "$EXPORTER_UPDATE" == "true" ]; then + TITLE="chore: update Valkey and redis-exporter" + BRANCH="auto-update-valkey-exporter" + elif [ "$VALKEY_UPDATE" == "true" ]; then + TITLE="chore: update Valkey to ${{ steps.get-version.outputs.detected_version }}" + BRANCH="auto-update-valkey-${{ steps.get-version.outputs.detected_version }}" + else + TITLE="chore: update redis-exporter to ${{ steps.get-exporter-version.outputs.detected_exporter_version }}" + BRANCH="auto-update-exporter-${{ steps.get-exporter-version.outputs.detected_exporter_version }}" + fi + + echo "title=$TITLE" >> $GITHUB_OUTPUT + echo "branch=$BRANCH" >> $GITHUB_OUTPUT + - name: Create Pull Request if: steps.compare.outputs.needs_update == 'true' uses: peter-evans/create-pull-request@v6 with: token: ${{ secrets.GITHUB_TOKEN }} commit-message: | - chore: update Valkey to version ${{ steps.get-version.outputs.detected_version }} + ${{ steps.pr-content.outputs.title }} - - Updated appVersion from ${{ steps.current-version.outputs.current_version }} to ${{ steps.get-version.outputs.detected_version }} - - Automatically detected from cgr.dev/chainguard/valkey:latest + Updates: + ${{ steps.compare-valkey.outputs.valkey_needs_update == 'true' && format('- Valkey: {0} → {1}', steps.current-version.outputs.current_version, steps.get-version.outputs.detected_version) || '' }} + ${{ steps.compare-exporter.outputs.exporter_needs_update == 'true' && format('- Redis-exporter: {0} → {1}', steps.current-exporter-version.outputs.current_exporter_version, steps.get-exporter-version.outputs.detected_exporter_version) || '' }} Co-Authored-By: github-actions[bot] - branch: auto-update-valkey-${{ steps.get-version.outputs.detected_version }} + branch: ${{ steps.pr-content.outputs.branch }} delete-branch: true - title: "chore: update Valkey to version ${{ steps.get-version.outputs.detected_version }}" + title: ${{ steps.pr-content.outputs.title }} body: | - ## 🤖 Automated Valkey Version Update + ## 🤖 Automated Version Update This PR was automatically created by the version checker workflow. ### Changes - - **Valkey version**: `${{ steps.current-version.outputs.current_version }}` → `${{ steps.get-version.outputs.detected_version }}` - - **Source**: Detected from `cgr.dev/chainguard/valkey:latest` + ${{ steps.compare-valkey.outputs.valkey_needs_update == 'true' && format('- **Valkey**: `{0}` → `{1}` (from Chainguard latest)', steps.current-version.outputs.current_version, steps.get-version.outputs.detected_version) || '' }} + ${{ steps.compare-exporter.outputs.exporter_needs_update == 'true' && format('- **Redis-exporter**: `{0}` → `{1}` (from GitHub releases)', steps.current-exporter-version.outputs.current_exporter_version, steps.get-exporter-version.outputs.detected_exporter_version) || '' }} - **Chart version**: Bumped patch version ### Verification - The version was detected by pulling the latest Chainguard Valkey image and running `--version`. + ${{ steps.compare-valkey.outputs.valkey_needs_update == 'true' && '- Valkey version detected from `cgr.dev/chainguard/valkey:latest`' || '' }} + ${{ steps.compare-exporter.outputs.exporter_needs_update == 'true' && '- Redis-exporter version from GitHub API (oliver006/redis_exporter latest release)' || '' }} ### Next Steps - Review the changes @@ -143,7 +249,15 @@ jobs: - name: Summary run: | if [ "${{ steps.compare.outputs.needs_update }}" == "true" ]; then - echo "✅ Version update PR created: ${{ steps.current-version.outputs.current_version }} → ${{ steps.get-version.outputs.detected_version }}" + echo "✅ Version update PR created" + if [ "${{ steps.compare-valkey.outputs.valkey_needs_update }}" == "true" ]; then + echo " - Valkey: ${{ steps.current-version.outputs.current_version }} → ${{ steps.get-version.outputs.detected_version }}" + fi + if [ "${{ steps.compare-exporter.outputs.exporter_needs_update }}" == "true" ]; then + echo " - Redis-exporter: ${{ steps.current-exporter-version.outputs.current_exporter_version }} → ${{ steps.get-exporter-version.outputs.detected_exporter_version }}" + fi else - echo "✅ No update needed. Current version ${{ steps.current-version.outputs.current_version }} is up to date." + echo "✅ No updates needed" + echo " - Valkey: ${{ steps.current-version.outputs.current_version }} (up to date)" + echo " - Redis-exporter: ${{ steps.current-exporter-version.outputs.current_exporter_version }} (up to date)" fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 6107895..5501ac9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,17 +5,27 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.2] - 2026-02-15 +## [0.2.3] - 2026-02-15 -### Security -- **CRITICAL**: Switch redis-exporter to Chainguard image (eliminates 6 CVEs: 1 Critical, 4 High, 1 Medium) -- Changed from `docker.io/oliver006/redis_exporter:v1.80.0` to `cgr.dev/chainguard/prometheus-redis-exporter:latest` +### Changed +- Update redis-exporter from `v1.80.0` to `v1.81.0` (latest stable release) +- Remove bash dependency from metrics exporter in replica and sentinel templates +- Metrics exporter now uses native entrypoint instead of bash wrapper (cleaner, more portable) +- Simplified metrics configuration across all deployment modes ### Added - Automated weekly version checking workflow for Valkey - Documentation for image versioning strategy - Complete CHANGELOG.md with release history +### Fixed +- Remove redundant password configuration in metrics exporter (was configured twice) + +### Note +- Chainguard `prometheus-redis-exporter` image requires authentication (not in public free tier) +- Using `oliver006/redis_exporter:v1.81.0` for public accessibility +- Template improvements support both oliver006 and distroless images + ## [0.2.1] - 2026-02-15 ### Changed diff --git a/Chart.yaml b/Chart.yaml index 10c48af..7437944 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: valkey description: Valkey is an open source, high-performance data structure server compatible with Redis. It supports strings, hashes, lists, sets, and sorted sets. type: application -version: 0.2.2 +version: 0.2.3 appVersion: "9.0.2" annotations: artifacthub.io/signKey: | @@ -21,20 +21,22 @@ annotations: - name: wolfi-base image: cgr.dev/chainguard/wolfi-base:latest - name: redis-exporter - image: cgr.dev/chainguard/prometheus-redis-exporter:latest + image: docker.io/oliver006/redis_exporter:v1.81.0 - name: kubectl image: cgr.dev/chainguard/kubectl:latest artifacthub.io/containsSecurityUpdates: "true" artifacthub.io/prerelease: "false" artifacthub.io/changes: | - - kind: security - description: Switch to Chainguard images for zero CVE (valkey, kubectl, wolfi-base, prometheus-redis-exporter) + - kind: changed + description: Update redis-exporter to v1.81.0 (from v1.80.0) + - kind: changed + description: Remove bash dependency from metrics exporter templates + - kind: changed + description: Switch to Chainguard images for zero CVE (valkey, kubectl, wolfi-base) - kind: changed description: Update container user from 999 to 65532 (Chainguard default) - kind: changed description: Simplify health check scripts for distroless compatibility - - kind: changed - description: Update pre-upgrade hook to work without shell - kind: added description: Automated version checking workflow for weekly updates keywords: diff --git a/README.md b/README.md index 80f3d97..1c60ea8 100644 --- a/README.md +++ b/README.md @@ -203,8 +203,8 @@ helm install my-valkey valkey/valkey \ | Parameter | Description | Default | |-----------|-------------|---------| | `metrics.enabled` | Enable Prometheus exporter | `false` | -| `metrics.image.repository` | Exporter image | `chainguard/prometheus-redis-exporter` | -| `metrics.image.tag` | Exporter tag | `latest` | +| `metrics.image.repository` | Exporter image | `oliver006/redis_exporter` | +| `metrics.image.tag` | Exporter tag | `v1.81.0` | | `metrics.serviceMonitor.enabled` | Create ServiceMonitor | `false` | | `metrics.podMonitor.enabled` | Create PodMonitor | `false` | diff --git a/templates/replica/statefulset.yaml b/templates/replica/statefulset.yaml index 2629b07..694ba3d 100644 --- a/templates/replica/statefulset.yaml +++ b/templates/replica/statefulset.yaml @@ -222,14 +222,12 @@ spec: {{- if .Values.metrics.containerSecurityContext.enabled }} securityContext: {{- omit .Values.metrics.containerSecurityContext "enabled" | toYaml | nindent 12 }} {{- end }} - command: - - /bin/bash - - -c - - | - if [[ -f '/secrets/valkey-password' ]]; then - export REDIS_PASSWORD=$(cat /secrets/valkey-password) - fi - redis_exporter{{- range $key, $value := .Values.metrics.extraArgs }} --{{ $key }}={{ $value }}{{- end }} + {{- if .Values.metrics.extraArgs }} + args: + {{- range $key, $value := .Values.metrics.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- end }} env: - name: REDIS_ALIAS value: {{ include "valkey.fullname" . }} diff --git a/templates/sentinel/statefulset.yaml b/templates/sentinel/statefulset.yaml index 15ea416..a8f9e78 100644 --- a/templates/sentinel/statefulset.yaml +++ b/templates/sentinel/statefulset.yaml @@ -220,14 +220,12 @@ spec: {{- if .Values.metrics.containerSecurityContext.enabled }} securityContext: {{- omit .Values.metrics.containerSecurityContext "enabled" | toYaml | nindent 12 }} {{- end }} - command: - - /bin/bash - - -c - - | - if [[ -f '/secrets/valkey-password' ]]; then - export REDIS_PASSWORD=$(cat /secrets/valkey-password) - fi - redis_exporter{{- range $key, $value := .Values.metrics.extraArgs }} --{{ $key }}={{ $value }}{{- end }} + {{- if .Values.metrics.extraArgs }} + args: + {{- range $key, $value := .Values.metrics.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- end }} env: - name: REDIS_ALIAS value: {{ include "valkey.fullname" . }} diff --git a/values.schema.json b/values.schema.json index bcf08c3..cc490d7 100644 --- a/values.schema.json +++ b/values.schema.json @@ -523,15 +523,15 @@ "properties": { "registry": { "type": "string", - "default": "cgr.dev" + "default": "docker.io" }, "repository": { "type": "string", - "default": "chainguard/prometheus-redis-exporter" + "default": "oliver006/redis_exporter" }, "tag": { "type": "string", - "default": "latest" + "default": "v1.81.0" }, "pullPolicy": { "type": "string", diff --git a/values.yaml b/values.yaml index 389df76..f9ae85e 100644 --- a/values.yaml +++ b/values.yaml @@ -453,11 +453,13 @@ metrics: enabled: false port: 9121 - # Using Chainguard image for zero CVE security (same as Valkey) + # Redis/Valkey metrics exporter for Prometheus + # Note: Chainguard image (cgr.dev/chainguard/prometheus-redis-exporter) + # requires authentication and is not publicly available in free tier image: - registry: cgr.dev - repository: chainguard/prometheus-redis-exporter - tag: "latest" + registry: docker.io + repository: oliver006/redis_exporter + tag: "v1.81.0" pullPolicy: IfNotPresent containerSecurityContext: