fix: pre-start gpg-agent for headless CI integration tests#1058
Conversation
On headless CI (Ubuntu, macOS) gpg subprocesses hang waiting for a PIN dialog or for gpg-agent to start, causing all ImitatePass tests to time out at 15 s each. Fix by writing gpg-agent.conf / gpg.conf to the temp GNUPGHOME before key generation and explicitly launching the agent via gpgconf: - allow-loopback-pinentry / pinentry-mode loopback: prevents blocking on pinentry when no GUI is available - gpgconf --launch gpg-agent: ensures the agent is running before any GPG subprocess is spawned Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
CodeAnt AI is reviewing your PR. |
📝 WalkthroughWalkthroughTests and CI now prepare a headless, CI-friendly GPG environment: tests write gpg config into a temp GNUPGHOME, pre-launch gpg-agent via gpgconf, import ownertrust for generated keys, and capture Pass::processErrorExit for richer test diagnostics; CI installs pinentry/pass on runners when building. Changes
Sequence Diagram(s)sequenceDiagram
participant Test as TestHarness
participant FS as Filesystem
participant GConf as gpgconf
participant GAgent as gpg-agent
participant GPG as gpg CLI
participant App as PassApp
Test->>FS: write gpg-agent.conf, gpg.conf into GNUPGHOME
Test->>GConf: gpgconf --homedir <GNUPGHOME> --launch gpg-agent
GAgent-->>Test: started / ready (exit code)
Test->>GPG: generate key / read status (captures `fpr:` line)
GPG-->>Test: emits `fpr:` fingerprint
Test->>GPG: gpg --import-ownertrust <fingerprint>:6:
GPG-->>Test: import exit status
Test->>App: run insert flows (ImitatePass / RealPass)
App-->>Test: emits finishedInsert or Pass::processErrorExit
Test->>Test: QSignalSpy reads processErrorExit and includes message in assertions
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
CodeAnt AI finished reviewing your PR. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/auto/integration/tst_integration.cpp`:
- Around line 176-178: The call to agentLaunch.start("gpgconf", {"--homedir",
m_gnupgHome.path(), "--launch", "gpg-agent"}) and the subsequent
agentLaunch.waitForFinished(10000) is not being validated, so failures silently
proceed into generateTestKey(); update the test to assert success by first
checking agentLaunch.waitForStarted(...) returned true, then that
waitForFinished(10000) returned true, and verify the QProcess::exitStatus() is
Normal and exitCode() == 0 before calling generateTestKey(); use QVERIFY2() (or
similar) and include the process output
(readAllStandardOutput()/readAllStandardError()) in the failure message to aid
debugging, referencing agentLaunch, waitForStarted, waitForFinished, exitStatus,
exitCode, and generateTestKey().
- Around line 162-167: The test currently ignores failures when creating/writing
GPG config files (QFile agentConf/gpgConf), so update the block that opens and
writes to agentConf and gpgConf to fail fast: check the result of
agentConf.open(...) and agentConf.write(...), and likewise gpgConf.open(...) and
gpgConf.write(...); if any of those return false or a negative/zero write
length, report the error and abort the test (e.g., QFAIL or throw) with a clear
message mentioning which file failed and the QFile::errorString(), so the test
does not continue silently without loopback pinentry configured.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: d3d04294-1e29-4df0-8777-17b0a1d78ad2
📒 Files selected for processing (1)
tests/auto/integration/tst_integration.cpp
❌ 6 Tests Failed:
View the top 3 failed test(s) by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
- QVERIFY2 on QFile::open/write for gpg-agent.conf and gpg.conf so a permission or path failure surfaces immediately with errorString() - QVERIFY2 on waitForStarted, waitForFinished, and exit code for the gpgconf --launch gpg-agent step, including stderr in the failure message Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
tests/auto/integration/tst_integration.cpp (1)
161-176:⚠️ Potential issue | 🟡 Minor
write() > 0accepts short writes — prefer comparing against the payload size.
QIODevice::write()returns-1on error or the number of bytes actually written, so> 0correctly catches hard errors but silently accepts a truncated config (e.g.1byte written out of40). If only a prefix like"a"lands ingpg-agent.conf, the test proceeds withoutallow-loopback-pinentryand reintroduces the exact hang this PR fixes — only harder to diagnose. Payloads here are tiny and buffered, so in practice this is very unlikely to bite, but the assertion should encode the invariant you actually want.Same concern applies to both
agentConf.write(...)andgpgConf.write(...).♻️ Proposed fix
- QFile agentConf(m_gnupgHome.path() + "/gpg-agent.conf"); - QVERIFY2(agentConf.open(QIODevice::WriteOnly | QIODevice::Text), + const QByteArray agentConfig("allow-loopback-pinentry\ndefault-cache-ttl 300\n"); + QFile agentConf(m_gnupgHome.path() + "/gpg-agent.conf"); + QVERIFY2(agentConf.open(QIODevice::WriteOnly | QIODevice::Text | + QIODevice::Truncate), qPrintable("Cannot open gpg-agent.conf: " + agentConf.errorString())); - QVERIFY2( - agentConf.write("allow-loopback-pinentry\ndefault-cache-ttl 300\n") > - 0, - qPrintable("Cannot write gpg-agent.conf: " + agentConf.errorString())); - QFile gpgConf(m_gnupgHome.path() + "/gpg.conf"); - QVERIFY2(gpgConf.open(QIODevice::WriteOnly | QIODevice::Text), + QVERIFY2(agentConf.write(agentConfig) == agentConfig.size(), + qPrintable("Cannot write gpg-agent.conf: " + agentConf.errorString())); + + const QByteArray gpgConfig("pinentry-mode loopback\nbatch\nno-tty\n"); + QFile gpgConf(m_gnupgHome.path() + "/gpg.conf"); + QVERIFY2(gpgConf.open(QIODevice::WriteOnly | QIODevice::Text | + QIODevice::Truncate), qPrintable("Cannot open gpg.conf: " + gpgConf.errorString())); - QVERIFY2( - gpgConf.write("pinentry-mode loopback\nbatch\nno-tty\n") > 0, - qPrintable("Cannot write gpg.conf: " + gpgConf.errorString())); + QVERIFY2(gpgConf.write(gpgConfig) == gpgConfig.size(), + qPrintable("Cannot write gpg.conf: " + gpgConf.errorString()));🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/auto/integration/tst_integration.cpp` around lines 161 - 176, The tests currently assert agentConf.write(...) > 0 and gpgConf.write(...) > 0 which allows truncated writes to pass; instead capture each payload into a variable (e.g. QByteArray/QString payloadAgent and payloadGpg) and assert that the return value of agentConf.write(payloadAgent) and gpgConf.write(payloadGpg) equals payloadAgent.size()/payloadGpg.size() respectively (i.e. full write), failing the test on any short write or error; update the two write call sites around QFile agentConf and QFile gpgConf to use payload variables and compare against payload.size().
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@tests/auto/integration/tst_integration.cpp`:
- Around line 161-176: The tests currently assert agentConf.write(...) > 0 and
gpgConf.write(...) > 0 which allows truncated writes to pass; instead capture
each payload into a variable (e.g. QByteArray/QString payloadAgent and
payloadGpg) and assert that the return value of agentConf.write(payloadAgent)
and gpgConf.write(payloadGpg) equals payloadAgent.size()/payloadGpg.size()
respectively (i.e. full write), failing the test on any short write or error;
update the two write call sites around QFile agentConf and QFile gpgConf to use
payload variables and compare against payload.size().
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: c533d5e5-68a4-4fe9-a224-5979a43defda
📒 Files selected for processing (1)
tests/auto/integration/tst_integration.cpp
- generateTestKey: explicitly set ownertrust to ultimate (level 6) via --import-ownertrust; some GPG versions don't auto-assign it from --gen-key --batch, causing encryption to refuse the key silently - initTestCase: capture config payloads into QByteArray variables and assert write() == payload.size() for full-write verification - All ImitatePass Insert tests: add processErrorExit spy alongside insertSpy so failures report the actual GPG error instead of just "finishedInsert not emitted" Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/auto/integration/tst_integration.cpp`:
- Around line 106-110: The ownertrust import call in generateTestKey ignores
runGpg()'s exit code so it may return a fingerprint even when trust import
failed; modify generateTestKey to capture the result/exit code of
runGpg(gnupgHome, {"--batch", "--import-ownertrust"}, fingerprint + ":6:\n") and
if it indicates failure, fail the setup immediately (e.g., return an error/empty
fingerprint or throw), and log a clear error mentioning the fingerprint and that
ownertrust import failed so downstream tests don't proceed with an untrusted
key.
- Around line 137-144: The function gpgInsertErrorMsg should use a trailing
return type to satisfy the Clang rule: change its signature from "static
QByteArray gpgInsertErrorMsg(const QSignalSpy &errorSpy)" to use "auto
gpgInsertErrorMsg(const QSignalSpy &errorSpy) -> QByteArray" and leave the
function body unchanged (keep the static specifier and the const QSignalSpy&
parameter and the current return logic).
- Around line 183-191: The new QFile constructions use string concatenation with
m_gnupgHome.path() which can produce non-normalized paths; normalize the paths
before creating QFile by calling QDir::cleanPath() on the combined path (e.g.,
for the gpg-agent.conf and gpg.conf paths used to construct agentConf and
gpgConf), ensuring you build the filename string with m_gnupgHome.path() +
"/gpg-agent.conf" and m_gnupgHome.path() + "/gpg.conf" then pass those cleaned
results into QFile so the tests are cross-platform consistent.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: 9c9df591-4019-4500-b143-945b655289d4
📒 Files selected for processing (1)
tests/auto/integration/tst_integration.cpp
- Add pinentry-tty to CI workflow for GPG in headless environments - Check ownertrust import exit code in generateTestKey - Use trailing return type for gpgInsertErrorMsg - Use QDir::cleanPath() for GPG config file paths
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/ccpp.yml:
- Around line 96-101: The "Install dependencies (Linux)" step currently only
checks runner.os == 'Linux' and should also be gated on the build decision to
avoid unnecessary apt runs; update the step (named "Install dependencies
(Linux)") to add the run_build condition so its if becomes something like
runner.os == 'Linux' && steps.need_build.outputs.run_build == 'true', ensuring
the apt-get update/install only runs when steps.need_build indicates a build.
In `@tests/auto/integration/tst_integration.cpp`:
- Around line 141-148: Replace the generic "finishedInsert not emitted" messages
in the RealPass tests with the new helper gpgInsertErrorMsg(const QSignalSpy
&errorSpy) -> QByteArray so you get the same detailed diagnostics as
ImitatePass; specifically, update realPass_insertAndShow and
realPass_insertAndGrep to call gpgInsertErrorMsg(errorSpy) when the
finished-insert signal isn't observed and use its returned QByteArray in the
test failure/assert message (the helper matches the trailing-return signature
and expects a QSignalSpy, and the emitted Pass::processErrorExit comes from the
same code path).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: a935f964-c85f-47b4-91e4-747d66e13d2f
📒 Files selected for processing (2)
.github/workflows/ccpp.ymltests/auto/integration/tst_integration.cpp
…r RealPass - Add QtPassSettings::setPassSigningKey(QString()) in initTestCase to clear the signing key - Configure gpg-agent to use pinentry-tty for headless passphrase - Update CI to only install dependencies when build is needed - Use gpgInsertErrorMsg in RealPass tests for consistent error diagnostics
…Linux, pass-otp on macOS)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
nogeenharrie
left a comment
There was a problem hiding this comment.
All tests pass (183 passed). The integration tests now work in headless CI environments. Great work!
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
tests/auto/integration/tst_integration.cpp (1)
539-543: 🧹 Nitpick | 🔵 TrivialUse the captured RealPass error for the second insert too.
Line 540 clears
insertErrorSpy, but Line 543 still reports only"insert 2 not emitted", so the second RealPass insert loses the GPG stderr/return-code diagnostics this PR added elsewhere.Proposed fix
insertErrorSpy.clear(); pass.Insert(QStringLiteral("email/outlook"), QStringLiteral("outlookpass\nurl: outlook.com\n"), false); - QVERIFY2(waitForSignal(insertSpy, 20000), "insert 2 not emitted"); + QVERIFY2(waitForSignal(insertSpy, 20000), gpgInsertErrorMsg(insertErrorSpy));🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/auto/integration/tst_integration.cpp` around lines 539 - 543, The second RealPass insert is losing diagnostic info because insertErrorSpy is cleared before the insert but the QVERIFY2 check only uses the static message "insert 2 not emitted"; instead keep or capture the insertErrorSpy output for the second insert and include it in the QVERIFY2 failure message (i.e., don't clear insertErrorSpy immediately before calling pass.Insert(...) or read its last/error output after the insert) so the waitForSignal(insertSpy, 20000) assertion can report the RealPass stderr/return-code details from insertErrorSpy if the signal isn't emitted; update the assertion to reference insertErrorSpy's captured value when constructing the failure string.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/auto/integration/tst_integration.cpp`:
- Around line 185-187: The test currently hardcodes "/usr/bin/pinentry-tty" into
the agent config via the agentPayload string in tst_integration.cpp which breaks
macOS CI; update the agentPayload generation to avoid a hardcoded
pinentry-program (either omit the "pinentry-program" line entirely and rely on
loopback or detect the correct pinentry binary at runtime and insert its path)
so gpg-agent.conf no longer includes a platform-specific path and tests run on
macOS and Linux.
---
Duplicate comments:
In `@tests/auto/integration/tst_integration.cpp`:
- Around line 539-543: The second RealPass insert is losing diagnostic info
because insertErrorSpy is cleared before the insert but the QVERIFY2 check only
uses the static message "insert 2 not emitted"; instead keep or capture the
insertErrorSpy output for the second insert and include it in the QVERIFY2
failure message (i.e., don't clear insertErrorSpy immediately before calling
pass.Insert(...) or read its last/error output after the insert) so the
waitForSignal(insertSpy, 20000) assertion can report the RealPass
stderr/return-code details from insertErrorSpy if the signal isn't emitted;
update the assertion to reference insertErrorSpy's captured value when
constructing the failure string.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: aee77018-c030-462a-b4db-c2864edcc76d
📒 Files selected for processing (52)
.github/workflows/ccpp.ymllocalization/localization_af_ZA.tslocalization/localization_ar_MA.tslocalization/localization_bg_BG.tslocalization/localization_ca_ES.tslocalization/localization_cs_CZ.tslocalization/localization_cy_GB.tslocalization/localization_da_DK.tslocalization/localization_de_DE.tslocalization/localization_de_LU.tslocalization/localization_el_GR.tslocalization/localization_en_GB.tslocalization/localization_en_US.tslocalization/localization_es_AR.tslocalization/localization_es_EC.tslocalization/localization_es_ES.tslocalization/localization_es_MX.tslocalization/localization_es_UY.tslocalization/localization_et_EE.tslocalization/localization_fi_FI.tslocalization/localization_fr_BE.tslocalization/localization_fr_FR.tslocalization/localization_fr_LU.tslocalization/localization_gl_ES.tslocalization/localization_he_IL.tslocalization/localization_hr_HR.tslocalization/localization_hu_HU.tslocalization/localization_it_IT.tslocalization/localization_ja_JP.tslocalization/localization_ko_KR.tslocalization/localization_lb_LU.tslocalization/localization_nb_NO.tslocalization/localization_nl_BE.tslocalization/localization_nl_NL.tslocalization/localization_pl_PL.tslocalization/localization_pt_BR.tslocalization/localization_pt_PT.tslocalization/localization_ro_RO.tslocalization/localization_ru_RU.tslocalization/localization_si_LK.tslocalization/localization_sk_SK.tslocalization/localization_sq_AL.tslocalization/localization_sr_Cyrl.tslocalization/localization_sr_RS.tslocalization/localization_sv_SE.tslocalization/localization_ta_IN.tslocalization/localization_tr_TR.tslocalization/localization_uk_UA.tslocalization/localization_zh_CN.tslocalization/localization_zh_Hant.tstests/auto/integration/tst_integrationtests/auto/integration/tst_integration.cpp
- Only add pinentry-program for Linux, not macOS - Keep insertErrorSpy for second RealPass insert to capture diagnostics
|
CodeAnt AI is running the review. |
Sequence DiagramThis PR changes the integration tests to configure a temporary GPG home for headless CI, pre-start the GPG agent, and use that environment so pass-style backends can encrypt secrets without hanging. sequenceDiagram
participant CI
participant IntegrationTests
participant GPGAgent
participant GPG
participant PassBackend
CI->>IntegrationTests: Run GPG integration test suite
IntegrationTests->>GPGAgent: Write gpg-agent and gpg config with loopback pinentry
IntegrationTests->>GPGAgent: Launch agent via gpgconf in temp GNUPGHOME
IntegrationTests->>GPG: Generate test key and set owner trust in temp keyring
IntegrationTests->>PassBackend: Configure pass with test GNUPGHOME and key fingerprint
PassBackend->>GPG: Encrypt secret during Insert
GPG-->>PassBackend: Return encryption result
PassBackend-->>IntegrationTests: Emit finishedInsert signal for the test
Generated by CodeAnt AI |
|
CodeAnt AI finished running the review. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/auto/integration/tst_integration.cpp`:
- Around line 535-544: The insertErrorSpy (QSignalSpy insertErrorSpy) is not
cleared between the two pass.Insert calls so a stale error from the first insert
can be reported by gpgInsertErrorMsg() on the second timeout; before performing
the second pass.Insert call, clear insertErrorSpy (similar to insertSpy.clear())
so that waitForSignal(insertSpy, ...) and gpgInsertErrorMsg(insertErrorSpy)
reflect only signals from the second operation.
- Line 234: The test currently calls
QtPassSettings::setPassSigningKey(QString()) which overwrites the user's
persisted signing key; to fix, capture the original key at test setup by calling
QtPassSettings::getPassSigningKey() and store it in a test-scoped variable, then
in cleanupTestCase() restore it by calling
QtPassSettings::setPassSigningKey(originalKey); ensure the stored variable is
accessible to cleanupTestCase() and that restore happens unconditionally even if
the test fails.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: 27675a61-336f-4f4e-82cd-f6ec36728c4b
📒 Files selected for processing (53)
.github/workflows/ccpp.yml.gitignorelocalization/localization_af_ZA.tslocalization/localization_ar_MA.tslocalization/localization_bg_BG.tslocalization/localization_ca_ES.tslocalization/localization_cs_CZ.tslocalization/localization_cy_GB.tslocalization/localization_da_DK.tslocalization/localization_de_DE.tslocalization/localization_de_LU.tslocalization/localization_el_GR.tslocalization/localization_en_GB.tslocalization/localization_en_US.tslocalization/localization_es_AR.tslocalization/localization_es_EC.tslocalization/localization_es_ES.tslocalization/localization_es_MX.tslocalization/localization_es_UY.tslocalization/localization_et_EE.tslocalization/localization_fi_FI.tslocalization/localization_fr_BE.tslocalization/localization_fr_FR.tslocalization/localization_fr_LU.tslocalization/localization_gl_ES.tslocalization/localization_he_IL.tslocalization/localization_hr_HR.tslocalization/localization_hu_HU.tslocalization/localization_it_IT.tslocalization/localization_ja_JP.tslocalization/localization_ko_KR.tslocalization/localization_lb_LU.tslocalization/localization_nb_NO.tslocalization/localization_nl_BE.tslocalization/localization_nl_NL.tslocalization/localization_pl_PL.tslocalization/localization_pt_BR.tslocalization/localization_pt_PT.tslocalization/localization_ro_RO.tslocalization/localization_ru_RU.tslocalization/localization_si_LK.tslocalization/localization_sk_SK.tslocalization/localization_sq_AL.tslocalization/localization_sr_Cyrl.tslocalization/localization_sr_RS.tslocalization/localization_sv_SE.tslocalization/localization_ta_IN.tslocalization/localization_tr_TR.tslocalization/localization_uk_UA.tslocalization/localization_zh_CN.tslocalization/localization_zh_Hant.tstests/auto/integration/tst_integrationtests/auto/integration/tst_integration.cpp
- Add findGpgconf() and skip tests if gpgconf not found - Store original passSigningKey and restore in cleanupTestCase - Clear insertErrorSpy before second RealPass insert
|
CodeAnt AI is running Incremental review |
|
CodeAnt AI Incremental review completed. |
There was a problem hiding this comment.
Actionable comments posted: 9
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@localization/localization_de_DE.ts`:
- Around line 1318-1337: You committed manual edits into
localization/localization_de_DE.ts (e.g. translation entries for "Encryption
failed: GPG key has expired." / "Encryption failed: GPG key has been revoked." /
"Encryption failed: recipient GPG key not found or invalid..."), which violates
the guideline to not edit .ts files by hand; revert those manual changes, update
translations via the project translation flow (Weblate) for those source
strings, then regenerate the .ts file using the project's sync step (run qmake6
as required) so the .ts entries and <location> tags are produced automatically.
In `@localization/localization_es_EC.ts`:
- Around line 1308-1327: The localization_es_EC.ts file was edited directly
(including <location> metadata) — revert these manual edits and regenerate the
translation file using the Weblate/translation tooling, then run qmake6/qmake
sync to update .ts metadata; specifically restore changes around the messages
with source texts "Encryption failed: GPG key has expired. Please renew or
replace it.", "Encryption failed: GPG key has been revoked.", and "Encryption
failed: recipient GPG key not found or invalid. Check that the key ID in .gpg-id
is correct and imported." (also revert the similar edits noted at the other
block) so that translations and <location> entries are produced by the tooling
rather than edited by hand.
In `@localization/localization_fr_BE.ts`:
- Around line 1319-1338: Revert the manual edits made to the translation file
(undo any changes to the translation metadata and message entries such as the
"Encryption failed: recipient GPG key not found or invalid. Check that the key
ID in .gpg-id is correct and imported." entry and the nearby entries), then
update translations via the translation tooling/Weblate (do not hand-edit .ts
files) and synchronize the .ts from Weblate; after syncing, run qmake6 to
regenerate and update the .ts/.qm artifacts so the correct metadata and
translations are restored and no direct .ts edits remain in the PR.
In `@localization/localization_gl_ES.ts`:
- Around line 1316-1335: This change manually edited the .ts translation file
(localization_gl_ES.ts); revert the direct edits and instead add the
translations via the Weblate translation platform (or the project's translation
workflow), then regenerate the .ts metadata by running qmake6 so the .ts is
produced by the supported pipeline; ensure you update the same message keys (the
strings from src/pass.cpp such as the "Encryption failed: GPG key has
expired..." / "has been revoked." / "recipient GPG key not found or invalid..."
entries) through Weblate and not by committing manual edits to
localization_gl_ES.ts.
In `@localization/localization_it_IT.ts`:
- Around line 1402-1421: The changes in localization_it_IT.ts (the edited
<message> entries for strings coming from src/pass.cpp like "Encryption failed:
GPG key has expired..." / "GPG key has been revoked." / "recipient GPG key not
found...") were made directly in the .ts file; revert those manual edits and
instead add/update translations through Weblate for the Italian locale, then run
qmake6 to regenerate the .ts artifacts so the updated translations are produced
correctly from the source (src/pass.cpp) and included in the build.
In `@localization/localization_ta_IN.ts`:
- Around line 1391-1410: The .ts translation entries were edited directly
instead of using the localization pipeline; revert the manual edits to
localization_ta_IN.ts and instead add or update the corresponding source strings
via the project's translation workflow (push the source changes so Weblate can
ingest them), perform the translations in Weblate, then regenerate the
translation artifacts by running qmake6 to produce updated .ts/.qm files; ensure
the specific messages like "Encryption failed: GPG key has expired. Please renew
or replace it.", "Encryption failed: GPG key has been revoked.", and "Encryption
failed: recipient GPG key not found or invalid. Check that the key ID in .gpg-id
is correct and imported." are handled through Weblate rather than edited in-PR.
In `@localization/localization_zh_CN.ts`:
- Around line 1350-1369: The commit contains manual edits to the Chinese
translation file for the error messages like "Encryption failed: GPG key has
expired. Please renew or replace it.", "Encryption failed: GPG key has been
revoked.", and "Encryption failed: recipient GPG key not found or invalid. Check
that the key ID in .gpg-id is correct and imported." — revert those direct
changes in localization_zh_CN.ts, instead push translations through Weblate
(update the corresponding entries there) and then regenerate the .ts files by
running qmake6 so the location remaps from the source (pass.cpp) are applied
automatically.
In `@tests/auto/integration/tst_integration.cpp`:
- Around line 50-56: The function findGpgconf() uses a traditional return type
and should be rewritten with a trailing return type to satisfy the
modernize-use-trailing-return-type rule; change its signature from "QString
findGpgconf()" to "auto findGpgconf() -> QString" (leave the body unchanged) so
the function name findGpgconf and its returns (QFile::exists and
QStandardPaths::findExecutable) remain intact.
- Around line 247-256: The test captures the original signing key too late
(m_originalPassSigningKey = QtPassSettings::getPassSigningKey()) so
cleanupTestCase() may restore an empty key if init failed early; move the
capture to a guaranteed-executed point (e.g., the tst_integration constructor or
the very top of initTestCase() before any QSKIP/QVERIFY calls) and set a boolean
flag (e.g., m_hasOriginalPassSigningKey) when captured, then change
cleanupTestCase() to only call
QtPassSettings::setPassSigningKey(m_originalPassSigningKey) if that flag is
true; update member declarations to include the flag and initialize it
appropriately.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4a8dd04b-b8f5-40ff-8148-d372a53bfd1f
📒 Files selected for processing (53)
.github/workflows/ccpp.yml.gitignorelocalization/localization_af_ZA.tslocalization/localization_ar_MA.tslocalization/localization_bg_BG.tslocalization/localization_ca_ES.tslocalization/localization_cs_CZ.tslocalization/localization_cy_GB.tslocalization/localization_da_DK.tslocalization/localization_de_DE.tslocalization/localization_de_LU.tslocalization/localization_el_GR.tslocalization/localization_en_GB.tslocalization/localization_en_US.tslocalization/localization_es_AR.tslocalization/localization_es_EC.tslocalization/localization_es_ES.tslocalization/localization_es_MX.tslocalization/localization_es_UY.tslocalization/localization_et_EE.tslocalization/localization_fi_FI.tslocalization/localization_fr_BE.tslocalization/localization_fr_FR.tslocalization/localization_fr_LU.tslocalization/localization_gl_ES.tslocalization/localization_he_IL.tslocalization/localization_hr_HR.tslocalization/localization_hu_HU.tslocalization/localization_it_IT.tslocalization/localization_ja_JP.tslocalization/localization_ko_KR.tslocalization/localization_lb_LU.tslocalization/localization_nb_NO.tslocalization/localization_nl_BE.tslocalization/localization_nl_NL.tslocalization/localization_pl_PL.tslocalization/localization_pt_BR.tslocalization/localization_pt_PT.tslocalization/localization_ro_RO.tslocalization/localization_ru_RU.tslocalization/localization_si_LK.tslocalization/localization_sk_SK.tslocalization/localization_sq_AL.tslocalization/localization_sr_Cyrl.tslocalization/localization_sr_RS.tslocalization/localization_sv_SE.tslocalization/localization_ta_IN.tslocalization/localization_tr_TR.tslocalization/localization_uk_UA.tslocalization/localization_zh_CN.tslocalization/localization_zh_Hant.tstests/auto/integration/tst_integrationtests/auto/integration/tst_integration.cpp
User description
Summary
gpg-agent.conf(allow-loopback-pinentry) andgpg.conf(pinentry-mode loopback) to the temp GNUPGHOME before any key operationsgpg-agentviagpgconf --launchso all subsequent GPG subprocesses connect immediately instead of hangingTest plan
🤖 Generated with Claude Code
CodeAnt-AI Description
Prevent GPG integration tests from hanging in headless CI
What Changed
Impact
✅ Fewer CI test timeouts✅ Reliable headless GPG test runs✅ Clearer integration test failures🔄 Retrigger CodeAnt AI Review
Details
💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.
Summary by CodeRabbit
Tests
Chores
Documentation / Localization