@@ -256,14 +256,21 @@ jobs:
256256 GPG_FINGERPRINT : ${{ secrets.GPG_FINGERPRINT }}
257257 GPG_PASSPHRASE : ${{ secrets.GPG_PASSPHRASE }}
258258 run : |
259+ # Install gnupg2 if not already available (includes gpg-preset-passphrase)
260+ sudo apt-get update && sudo apt-get install -y gnupg2 || true
261+
259262 # Create GPG directory
260263 mkdir -p ~/.gnupg
261264 chmod 700 ~/.gnupg
262265
263- # Configure GPG for non-interactive use with passphrase
264- echo "use-agent" >> ~/.gnupg/gpg.conf
266+ # Configure GPG for non-interactive use
267+ # Note: allow-loopback-pinentry is a gpg-agent option, not gpg.conf option
268+ echo "use-agent" > ~/.gnupg/gpg.conf
265269 echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf
266- echo "allow-loopback-pinentry" >> ~/.gnupg/gpg.conf
270+
271+ # Configure gpg-agent for loopback pinentry
272+ echo "allow-loopback-pinentry" > ~/.gnupg/gpg-agent.conf
273+ chmod 600 ~/.gnupg/gpg-agent.conf
267274
268275 # Start gpg-agent with loopback pinentry (ignore error if already running)
269276 gpg-agent --daemon --allow-loopback-pinentry 2>&1 || true
@@ -273,39 +280,22 @@ jobs:
273280 KEY_FILE=$(mktemp)
274281 echo "$GPG_PRIVATE_KEY" > "$KEY_FILE"
275282
276- # Get keygrip from the key without importing (dry-run with import-show)
277- IMPORT_OUTPUT=$(gpg --batch --with-colons --import-options import-show --dry-run --import "$KEY_FILE" 2>&1 || true)
278- KEYGRIP=$(echo "$IMPORT_OUTPUT" | grep -E "^grp:" | cut -d: -f10 | head -1)
279-
280- # If we found a keygrip, preset the passphrase in gpg-agent (passphrase never touches disk)
281- # gpg-preset-passphrase communicates directly with gpg-agent via socket
282- if [ -n "$KEYGRIP" ]; then
283- echo "$GPG_PASSPHRASE" | gpg-preset-passphrase --preset "$KEYGRIP" 2>&1 || true
284- fi
285-
286- # Now import the key (passphrase is cached in gpg-agent if keygrip was found)
287- # If keygrip wasn't found, use passphrase-fd (passphrase from env var, not disk)
288- if [ -n "$KEYGRIP" ]; then
289- gpg --batch --yes --import "$KEY_FILE"
290- else
291- # Fallback: passphrase comes from environment variable via stdin, never written to disk
292- echo "$GPG_PASSPHRASE" | gpg --batch --yes --pinentry-mode loopback --passphrase-fd 0 --import "$KEY_FILE"
293- fi
283+ # Import the key with passphrase from stdin (never written to disk)
284+ echo "$GPG_PASSPHRASE" | gpg --batch --yes --pinentry-mode loopback --passphrase-fd 0 --import "$KEY_FILE"
294285
295286 # Clean up temp file (only contains key data, not passphrase)
296287 rm -f "$KEY_FILE"
297288
298289 # Trust the key (required for signing)
290+ # Format: fingerprint:trust-level:
299291 # Use ultimate trust (6) for the subkey
300292 echo "$GPG_FINGERPRINT:6:" | gpg --import-ownertrust
301293
302- # Verify key is available and can sign
294+ # Verify key is available
303295 gpg --list-secret-keys --keyid-format LONG
304296
305- # Test signing capability
306- # Passphrase should be cached in gpg-agent from preset-passphrase above
307- # If not cached, this will fail and we'll know import didn't work
308- echo "test" | gpg --batch --pinentry-mode loopback --sign --armor > /dev/null 2>&1 && echo "✓ GPG signing test successful" || echo "⚠ GPG signing test failed - passphrase may not be cached"
297+ # Test signing capability with passphrase from stdin
298+ echo "$GPG_PASSPHRASE" | gpg --batch --yes --pinentry-mode loopback --passphrase-fd 0 --local-user "$GPG_FINGERPRINT" --sign --armor <<< "test" > /dev/null 2>&1 && echo "✓ GPG signing test successful" || echo "⚠ GPG signing test failed"
309299
310300 - name : Run GoReleaser
311301 uses : goreleaser/goreleaser-action@v6
0 commit comments