Skip to content
Merged
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
10 changes: 6 additions & 4 deletions .github/scripts/nfpm/build-client-packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -384,12 +384,14 @@ docker_rpm_tool() {
# --no-absolute-filenames keeps RPM payload members with
# absolute names (Ubuntu 24.04 rpm2cpio / nFPM 2.47) private to
# /extract; keep the log off the mounted volume so the host-side
# cleanup trap never meets a root-owned file, and surface it on
# failure instead of discarding stderr.
# cleanup trap never meets a root-owned file. Pipeline status is
# deliberately not the success criterion: the rpm 4.17 rpm2cpio
# exits nonzero on valid nFPM 2.47 RPMs while writing a complete
# payload (see the verify_rpm host branch). Note the status, then
# let the payload/SHA checks below stay fail-closed.
if ! rpm2cpio /pkg.rpm | cpio --no-absolute-filenames -idmv >/tmp/rpm-extract.log 2>&1; then
echo "RPM payload extraction failed for /pkg.rpm (rpm2cpio | cpio --no-absolute-filenames -idmv):" >&2
echo "NOTE: rpm2cpio|cpio returned nonzero for /pkg.rpm; verifying extracted payload" >&2
sed "s/^/ /" /tmp/rpm-extract.log >&2
exit 1
fi
payload="/extract/usr/bin/$2"
if test -L "$payload" || ! test -f "$payload" || ! test -s "$payload"; then
Expand Down
33 changes: 25 additions & 8 deletions .github/scripts/nfpm/tests/test_client_nfpm_native.sh
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,16 @@ inspect_rpm() {
if command -v rpm2cpio >/dev/null 2>&1 && command -v rpm >/dev/null 2>&1 && command -v cpio >/dev/null 2>&1; then
# --no-absolute-filenames keeps absolute RPM payload member names
# (Ubuntu 24.04 rpm2cpio / nFPM 2.47) private to $extract instead of
# writing toward the host's real /usr, and surfaces the extraction
# diagnostics on failure instead of discarding them.
# writing toward the host's real /usr. Pipeline status is deliberately
# not the success criterion: rpm 4.17's rpm2cpio (Ubuntu 24.04 and
# Pop!_OS, i.e. every runner this gate runs on) exits 1 on nFPM 2.47
# RPMs while writing a complete, correct payload. Note the status,
# then let the payload-presence and SHA-256 checks below stay
# fail-closed.
local extract_log="$extract.cpio.log"
if ! (cd "$extract" && rpm2cpio "$rpm_pkg" | cpio --no-absolute-filenames -idmv) >"$extract_log" 2>&1; then
echo "RPM payload extraction failed for $rpm_pkg (rpm2cpio | cpio --no-absolute-filenames -idmv):" >&2
echo "NOTE: rpm2cpio|cpio returned nonzero for $rpm_pkg; verifying extracted payload" >&2
sed 's/^/ /' "$extract_log" >&2
exit 1
fi
{
printf 'arch='
Expand Down Expand Up @@ -270,10 +273,17 @@ inspect_rpm() {
cd /extract
# --no-absolute-filenames keeps absolute RPM payload member
# names (Ubuntu 24.04 rpm2cpio / nFPM 2.47) private to
# /extract; the log stays off the mounted volume and is
# surfaced on failure instead of discarded.
# /extract. Pipeline status is deliberately not the success
# criterion: the rpm 4.17 rpm2cpio exits 1 on nFPM 2.47 RPMs
# while writing a complete, correct payload. Note the status,
# then let the payload-presence check stay fail-closed (the
# host side SHA-compares the extracted binary afterwards).
if ! rpm2cpio /pkg.rpm | cpio --no-absolute-filenames -idmv >/tmp/rpm-extract.log 2>&1; then
echo "RPM payload extraction failed for /pkg.rpm (rpm2cpio | cpio --no-absolute-filenames -idmv):" >&2
echo "NOTE: rpm2cpio|cpio returned nonzero for /pkg.rpm; verifying extracted payload" >&2
sed "s/^/ /" /tmp/rpm-extract.log >&2
fi
if ! test -f "/extract/usr/bin/$1"; then
echo "RPM payload extraction produced no /extract/usr/bin/$1 (rpm2cpio | cpio --no-absolute-filenames -idmv):" >&2
sed "s/^/ /" /tmp/rpm-extract.log >&2
exit 1
fi
Expand All @@ -287,12 +297,19 @@ inspect_rpm() {
printf "\n"
} > /metadata
chmod -R a+rwX /extract /metadata
'
' sh "$bin_name"
else
echo "BLOCKED: RPM inspection requires host rpm/rpm2cpio/cpio or Docker" >&2
exit 127
fi

# Fail-closed payload judgement for both branches: rpm2cpio|cpio status is
# only advisory (NOTE above), so the extracted binary itself is the
# criterion, SHA-compared immediately after.
[[ -f "$extract/usr/bin/$bin_name" ]] || {
echo "RPM payload extraction produced no $bin_name for $rpm_pkg" >&2
exit 1
}
actual_sha="$(sha256sum "$extract/usr/bin/$bin_name" | awk '{print $1}')"
[[ "$actual_sha" == "$expected_sha" ]] || {
echo "RPM payload SHA mismatch expected=$expected_sha actual=$actual_sha" >&2
Expand Down
43 changes: 35 additions & 8 deletions .github/workflows/release-binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -549,12 +549,18 @@ jobs:
- name: Sign, notarize, and revalidate final macOS binaries
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
CERT_BASE64: ${{ secrets.CERT_BASE64 }}
CERT_PASSWORD: ${{ secrets.CERT_PASSWORD }}
VERSION: ${{ needs.preflight.outputs.version }}
run: |
set -euo pipefail
load_masked() {
local name="$1" reference="$2" value
value="$(op read "$reference" --no-newline)"
# Shared validation: non-empty, CERT_BASE64 newline-stripped, all
# other values single-line, masked in logs, exported under $name.
normalise_and_mask() {
local name="$1" value="$2"
[ -n "$value" ] || { echo "empty credential $name" >&2; exit 1; }
if [ "$name" = "CERT_BASE64" ]; then
value="${value//$'\r'/}"
Expand All @@ -570,11 +576,32 @@ jobs:
# masking above and the empty-value check are unchanged.
export "${name?}"
}
load_masked APPLE_ID 'op://TerraphimPlatform/apple.developer.credentials/username'
load_masked APPLE_TEAM_ID 'op://TerraphimPlatform/apple.developer.credentials/APPLE_TEAM_ID'
load_masked APPLE_APP_PASSWORD 'op://TerraphimPlatform/apple.developer.credentials/APPLE_APP_SPECIFIC_PASSWORD'
load_masked CERT_BASE64 'op://TerraphimPlatform/apple.developer.certificate/base64'
load_masked CERT_PASSWORD 'op://TerraphimPlatform/apple.developer.certificate/password'
load_masked() {
local name="$1" reference="$2"
normalise_and_mask "$name" "$(op read "$reference" --no-newline)"
}
load_masked_env() {
local name="$1"
normalise_and_mask "$name" "${!name:-}"
}
# Preferred source is the 1Password service account; when it has not
# been provisioned, the identical credentials held by the reviewed
# tsm-production-release environment (the same source
# finalize-prebuilt-release.yml uses) keep the lane unblocked.
if [ -n "${OP_SERVICE_ACCOUNT_TOKEN:-}" ]; then
load_masked APPLE_ID 'op://TerraphimPlatform/apple.developer.credentials/username'
load_masked APPLE_TEAM_ID 'op://TerraphimPlatform/apple.developer.credentials/APPLE_TEAM_ID'
load_masked APPLE_APP_PASSWORD 'op://TerraphimPlatform/apple.developer.credentials/APPLE_APP_SPECIFIC_PASSWORD'
load_masked CERT_BASE64 'op://TerraphimPlatform/apple.developer.certificate/base64'
load_masked CERT_PASSWORD 'op://TerraphimPlatform/apple.developer.certificate/password'
else
echo "NOTE: OP_SERVICE_ACCOUNT_TOKEN not set; using tsm-production-release environment secrets" >&2
load_masked_env APPLE_ID
load_masked_env APPLE_TEAM_ID
load_masked_env APPLE_APP_PASSWORD
load_masked_env CERT_BASE64
load_masked_env CERT_PASSWORD
fi
chmod 755 macos/*
for path in macos/*; do
scripts/sign-macos-binary.sh "$path" "$APPLE_ID" "$APPLE_TEAM_ID" "$APPLE_APP_PASSWORD" "$CERT_BASE64" "$CERT_PASSWORD"
Expand Down
Loading