gpg vs gpg2: GnuPG 2.x Behavior in CI
On modern systems gpg is GnuPG 2.x, which always uses the gpg-agent and pinentry; gpg2 was the transitional name.
Knowing which GnuPG you have explains the CI behavior. GnuPG 2.x routes every passphrase through the agent, which is exactly why loopback mode exists.
What it does
GnuPG 1.x handled passphrases in-process. GnuPG 2.x split that out: gpg now delegates to gpg-agent, which launches pinentry. On older distros the 2.x binary was named gpg2 while gpg meant 1.x; on current systems gpg is 2.x and gpg2 is often just a symlink or absent.
Common usage
gpg --version # check the major version (2.x vs 1.x)
which gpg gpg2 # see which binaries exist
# on systems where gpg is still 1.x, 2.x may be gpg2
gpg2 --versionOptions
| Aspect | GnuPG 1.x vs 2.x |
|---|---|
| Passphrase handling | 1.x in-process; 2.x via gpg-agent + pinentry |
| Loopback pinentry | Only relevant to 2.x (--pinentry-mode loopback) |
| Binary name | 2.x may be gpg or gpg2 depending on the distro |
| gpg --version | Confirms the major version you actually run |
| Default keyring | 2.1+ uses keyboxd/pubring.kbx, not the old pubring.gpg |
In CI
Assume GnuPG 2.x on any modern runner, which means the agent is always in play and bare --passphrase needs --pinentry-mode loopback. If a script targets gpg2 explicitly, make sure that binary exists or call gpg. Check gpg --version at the start of a job when behavior differs across runner images.
Common errors in CI
"gpg2: command not found" means only gpg exists (it is already 2.x); call gpg. "gpg: setting pinentry mode 'loopback' failed: Not supported" only happens on 2.x and means the agent forbids loopback. A script written for 1.x that pipes the passphrase to stdin fails on 2.x because 2.x ignores it without loopback mode.