Compare commits

...
Sign in to create a new pull request.
Author SHA1 Message Date
12aa310b8d
fix(ci): detect existing R versions via public object HEAD probe
The existing-version check listed the bucket with an anonymous curl, but
Backblaze B2 requires authentication for the list-bucket API, so it returned
AccessDenied and r-versions-existing.txt was always empty -> every version
was rebuilt despite already existing in s3. Signing the request is not
workable here: the B2 credentials are scoped to the plugin-s3 image in crow
and are not injected into this plain alpine step.

Individual artifacts are public-read, so probe each expected object URL with
an anonymous HEAD instead. The filename mirrors what nfpm produces (version
and release pinned to 1): r-<ver>_1_<arch>.{apk,deb} for alpine/ubuntu and
R-<ver>-1-1.<arch>.rpm for el*. Verified against the live bucket for all
three packager families.

Shell variables use bare $name rather than ${name}: crow runs its own
${VAR} substitution over the commands before the shell executes, so a
${VAR} naming a shell var (BASE, VERSION) was blanked to empty -- only
matrix vars resolve at that stage. Build the filename with printf to avoid
the ${VERSION}_1 brace requirement entirely.
2026-06-29 14:14:27 +02:00

View file

@ -158,28 +158,29 @@ steps:
- name: Check which R versions already exist in s3 - name: Check which R versions already exist in s3
image: reg.devxy.io/docker.io/library/alpine:3.23 image: reg.devxy.io/docker.io/library/alpine:3.23
privileged: true privileged: true
environment:
AWS_ACCESS_KEY_ID:
from_secret: B2_S3_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY:
from_secret: B2_S3_SECRET_KEY
commands: commands:
- ip link set dev eth0 mtu 1280 2>/dev/null || true - ip link set dev eth0 mtu 1280 2>/dev/null || true
- for i in 1 2 3 4 5; do apk add -q --no-cache curl && break; sleep 5; done - for i in 1 2 3 4 5; do apk add -q --no-cache curl && break; sleep 5; done
- | - |
# Backblaze B2 requires authentication for the list-bucket API (anonymous # Backblaze B2's list-bucket API requires authentication, but the upload
# GET works only for individual public-read objects), so the request must be # credentials are scoped to the plugin-s3 image and aren't available here.
# SigV4-signed with the same credentials used for the upload step. Without # Individual objects are public-read, so probe each expected artifact URL
# this the listing returns AccessDenied, r-versions-existing.txt stays empty, # with an anonymous HEAD instead of listing the bucket. The filename mirrors
# and every version is rebuilt even though it already exists. # what nfpm produces in builder/package.${PLATFORM} (version/release pinned
LISTING=$(curl -s --aws-sigv4 "aws:amz:eu-central-003:s3" \ # to 1): r-<ver>_1_<arch>.{apk,deb} for alpine/ubuntu, R-<ver>-1-1.<arch>.rpm
--user "${AWS_ACCESS_KEY_ID}:${AWS_SECRET_ACCESS_KEY}" \ # for el*. Shell variables must use bare $name, not ${name}: crow performs
"https://s3.eu-central-003.backblazeb2.com/devxy-r-builds?prefix=${PLATFORM_ID}/" | \ # its own ${VAR} substitution on these commands before the shell runs, so
grep -oE '<Key>[^<]+</Key>' | sed 's/<[^>]*>//g') # ${VAR} for a shell var would be blanked out (only matrix vars resolve there).
case "${PLATFORM}" in
alpine-*) FMT="r-%s_1_%s.apk" ;;
ubuntu-*) FMT="r-%s_1_%s.deb" ;;
*) FMT="R-%s-1-1.%s.rpm" ;;
esac
BASE="https://s3.eu-central-003.backblazeb2.com/devxy-r-builds/${PLATFORM_ID}"
: > r-versions-existing.txt : > r-versions-existing.txt
for VERSION in $(cat r-versions-to-build.txt); do for VERSION in $(cat r-versions-to-build.txt); do
if printf '%s\n' "$LISTING" | \ URL="$BASE/$(printf "$FMT" "$VERSION" "${ARCH_ID}")"
awk -v arch="${ARCH_ID}" -v ver="$VERSION" 'index($0, arch) && index($0, ver) { found=1 } END { exit !found }'; then if [ "$(curl -s -o /dev/null -w '%{http_code}' -I "$URL")" = "200" ]; then
echo "$VERSION" >> r-versions-existing.txt echo "$VERSION" >> r-versions-existing.txt
fi fi
done done