Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ jobs:
tar -C "$RUNNER_TEMP/microsoft" -xf "$RUNNER_TEMP/msgo.tgz"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
- name: Install rpm (provides rpmsign for RPM package signing)
run: sudo apt-get install -y rpm gnupg2

- name: Release Notes
run: ./resources/scripts/release_notes.sh > ./release_notes.md

Expand Down
85 changes: 85 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,91 @@ jobs:
skip-cache: true
skip-save-cache: true

test-push-to-gcp-ar:
runs-on: ubuntu-latest
steps:

- name: Checkout code
uses: actions/checkout@v6

- name: Install rpm tools
run: sudo apt-get install -y rpm gnupg2

- name: Set up test GPG key and test RPM
run: |
# Generate a throwaway GPG key — no passphrase, expires never
printf '%s\n' \
'%no-protection' \
'Key-Type: RSA' \
'Key-Length: 2048' \
'Name-Real: Test Signing Key' \
'Name-Email: test@redpanda.com' \
'Expire-Date: 0' \
| gpg --batch --gen-key
# Export private key so the aws mock can serve it
gpg --armor --export-secret-keys > /tmp/test-signing-key.asc

# Build a minimal empty RPM
mkdir -p /tmp/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
printf '%s\n' \
'Name: test-pkg' \
'Version: 1.0.0' \
'Release: 1' \
'Summary: Test package for RPM signing CI' \
'License: MIT' \
'BuildArch: noarch' \
'%description' \
'Minimal test RPM.' \
'%install' \
'mkdir -p %{buildroot}' \
'%files' \
> /tmp/rpmbuild/SPECS/test-pkg.spec
rpmbuild --define "_topdir /tmp/rpmbuild" -bb /tmp/rpmbuild/SPECS/test-pkg.spec
cp /tmp/rpmbuild/RPMS/noarch/test-pkg-1.0.0-1.noarch.rpm /tmp/test.rpm

- name: Mock aws and gcloud CLIs
run: |
# aws: return the test private key for any secretsmanager get-secret-value call
printf '#!/bin/bash\ncat /tmp/test-signing-key.asc\n' \
| sudo tee /usr/local/bin/aws > /dev/null
sudo chmod +x /usr/local/bin/aws
# gcloud: echo arguments so we can assert routing
printf '#!/bin/bash\necho "gcloud $*"\n' \
| sudo tee /usr/local/bin/gcloud > /dev/null
sudo chmod +x /usr/local/bin/gcloud

- name: Test RPM GA — signed and routed to redpanda-yum
env:
AWS_DEFAULT_REGION: us-east-1
run: |
out=$(./resources/scripts/push_pkg_to_gcp_ar.sh /tmp/test.rpm 1.0.0)
echo "$out"
echo "$out" | grep -q "artifacts yum upload redpanda-yum"

- name: Test RPM RC — routed to redpanda-unstable-yum
env:
AWS_DEFAULT_REGION: us-east-1
run: |
out=$(./resources/scripts/push_pkg_to_gcp_ar.sh /tmp/test.rpm 1.0.0-rc1)
echo "$out"
echo "$out" | grep -q "artifacts yum upload redpanda-unstable-yum"

- name: Test DEB — skips signing, routed to redpanda-apt
run: |
touch /tmp/test.deb
out=$(./resources/scripts/push_pkg_to_gcp_ar.sh /tmp/test.deb 1.0.0)
echo "$out"
echo "$out" | grep -q "artifacts apt upload redpanda-apt"

- name: Test missing AWS region — exits with error
env:
AWS_DEFAULT_REGION: ""
AWS_REGION: ""
run: |
out=$(./resources/scripts/push_pkg_to_gcp_ar.sh /tmp/test.rpm 1.0.0 2>&1) && {
echo "ERROR: expected non-zero exit but got 0" >&2; exit 1
} || echo "$out" | grep -q "AWS_DEFAULT_REGION"

test-push-to-cloudsmith:
runs-on: ubuntu-latest
env:
Expand Down
43 changes: 42 additions & 1 deletion resources/scripts/push_pkg_to_gcp_ar.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Push a rpm or deb to GCP Artifact Registry

set -ex
set -euo pipefail

PKG_FILE=$1
PKG_VERSION=$2
Expand Down Expand Up @@ -42,8 +42,49 @@ else
repo="redpanda-unstable"
fi

sign_rpm() {
local pkg=$1

# Pre-flight: AWS_DEFAULT_REGION (or AWS_REGION) must be set; the aws CLI
# reads it from the environment, but we check early for a clear error message.
local region=${AWS_DEFAULT_REGION:-${AWS_REGION:-}}
if [[ -z "$region" ]]; then
echo "ERROR: AWS_DEFAULT_REGION or AWS_REGION must be set for RPM signing"
exit 1
fi

# Run in a subshell so the EXIT trap fires while temp vars are still in scope.
# A RETURN trap on the outer function would not fire on set -e exits.
(
gnupghome=$(mktemp -d)
trap 'rm -rf "$gnupghome" "${tmpdb:-}" "${pubkey:-}"' EXIT
tmpdb=$(mktemp -d)
pubkey=$(mktemp)

aws secretsmanager get-secret-value \
--secret-id sdlc/prod/github/rpm_signing_key_private \
--query SecretString \
--output text | GNUPGHOME="$gnupghome" gpg --batch --import

key_id=$(GNUPGHOME="$gnupghome" gpg --list-secret-keys --with-colons | awk -F: '/^sec/{print $5}' | head -1)
if [[ -z "$key_id" ]]; then
echo "ERROR: no secret key found after import — check the secret contents"
exit 1
fi

GNUPGHOME="$gnupghome" rpmsign --define "_gpg_name $key_id" --resign "$pkg"

# Verify against our key using a temp RPM database — rpm --checksig checks
# the RPM keyring (not GNUPGHOME), so we must import the key into a temp db.
GNUPGHOME="$gnupghome" gpg --armor --export "$key_id" >"$pubkey"
rpm --dbpath "$tmpdb" --import "$pubkey"
rpm --dbpath "$tmpdb" --checksig "$pkg"
)
}

if [[ "$PKG_TYPE" == "deb" ]]; then
gcloud artifacts apt upload "${repo}-apt" --location=us-central1 --source="$PKG_FILE" --project=production-devprod
else
sign_rpm "$PKG_FILE"
gcloud artifacts yum upload "${repo}-yum" --location=us-central1 --source="$PKG_FILE" --project=production-devprod
fi