Skip to content

Commit 7582f45

Browse files
keypair34claude
andcommitted
ci(gem-release): fail loudly on push errors; add credential-test toggle
The push step swallowed every gem push failure as "may already exist" and exited 0, so a 401 from a missing RUBYGEMS_API_KEY looked like a successful, no-op release (v0.4.0–v0.4.3 reported green but published nothing). Now: - credentials step fails fast if RUBYGEMS_API_KEY is empty/unset - push step only skips a genuine "Repushing not allowed" response and fails the job on any other error (401, validation, 5xx) - new force_push_existing dispatch input runs the push against an already-published version to verify credentials without creating a new release (RubyGems rejects the re-push) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 17ce8fa commit 7582f45

1 file changed

Lines changed: 45 additions & 8 deletions

File tree

.github/workflows/release-sdk-gem.yml

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ on:
1313
tag:
1414
description: "Release tag (e.g. v0.3.35)"
1515
required: true
16+
force_push_existing:
17+
description: "Attempt the push even if this version is already on RubyGems. Credential test only — RubyGems rejects re-push, so no new release is created."
18+
type: boolean
19+
default: false
20+
required: false
1621

1722
permissions:
1823
contents: read
@@ -206,7 +211,10 @@ jobs:
206211
id: rubygems-check
207212
shell: bash
208213
run: |
209-
if curl -fsS \
214+
if [[ "${{ github.event.inputs.force_push_existing }}" == "true" ]]; then
215+
echo "force_push_existing is set — running the push even if the version exists (credential test)."
216+
echo "exists=false" >> "$GITHUB_OUTPUT"
217+
elif curl -fsS \
210218
"https://rubygems.org/api/v2/rubygems/smbcloud-auth/versions/${RELEASE_VERSION}.json" \
211219
>/dev/null 2>&1; then
212220
echo "smbcloud-auth ${RELEASE_VERSION} already exists on RubyGems, skipping publish"
@@ -232,20 +240,49 @@ jobs:
232240
- name: Configure RubyGems credentials
233241
if: steps.rubygems-check.outputs.exists != 'true'
234242
shell: bash
243+
env:
244+
RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
235245
run: |
246+
# Fail fast and loudly if the secret is missing or empty. Without this
247+
# guard, gem push gets blank credentials, returns 401, and the push
248+
# step used to disguise that as "already exists" — silently shipping
249+
# nothing while the run stayed green.
250+
if [ -z "${RUBYGEMS_API_KEY}" ]; then
251+
echo "::error::RUBYGEMS_API_KEY secret is empty or unset. Add a RubyGems API key with push scope as the RUBYGEMS_API_KEY repository secret."
252+
exit 1
253+
fi
236254
mkdir -p "${HOME}/.gem"
237-
echo ":rubygems_api_key: ${{ secrets.RUBYGEMS_API_KEY }}" > "${HOME}/.gem/credentials"
255+
printf ':rubygems_api_key: %s\n' "${RUBYGEMS_API_KEY}" > "${HOME}/.gem/credentials"
238256
chmod 0600 "${HOME}/.gem/credentials"
239257
240-
# Push each .gem file individually. Platform-specific gems that are already
241-
# published (e.g. from a re-run) emit a warning and continue rather than
242-
# failing the whole job.
258+
# Push each .gem file individually. A version that is genuinely already
259+
# published (e.g. a partial re-run) is skipped; any other failure —
260+
# bad credentials, validation errors, server errors — fails the job.
243261
- name: Push gems to RubyGems
244262
if: steps.rubygems-check.outputs.exists != 'true'
245263
shell: bash
246264
run: |
265+
set -uo pipefail
266+
push_failed=0
247267
for gem_file in gems/*.gem; do
248-
echo "Pushing $(basename "${gem_file}")…"
249-
gem push "${gem_file}" \
250-
|| echo "::warning::$(basename "${gem_file}") may already exist for this version — skipping."
268+
name="$(basename "${gem_file}")"
269+
echo "Pushing ${name}…"
270+
if push_output="$(gem push "${gem_file}" 2>&1)"; then
271+
echo "${push_output}"
272+
echo "Pushed ${name}."
273+
continue
274+
fi
275+
echo "${push_output}"
276+
# The only acceptable failure is the version already existing on
277+
# RubyGems; repushing is rejected with this specific message.
278+
if echo "${push_output}" | grep -qiE "Repushing of gem versions is not allowed|has already been pushed"; then
279+
echo "::notice::${name} is already published for this version — skipping."
280+
continue
281+
fi
282+
echo "::error::Failed to push ${name}."
283+
push_failed=1
251284
done
285+
if [ "${push_failed}" -ne 0 ]; then
286+
echo "::error::One or more gems failed to push (see logs above). The release did not fully publish."
287+
exit 1
288+
fi

0 commit comments

Comments
 (0)