App in PlayStore was not updated #361
Closed
opened 2026-06-03 13:53:26 +00:00 by guettli
·
2 comments
No Branch/Tag Specified
main
issue-563-agentloop-validation
dummy-pr-test
issue-560-fix-firebase-run-url
issue-539-stable-imap-uid
issue-533-shared-email-list
plan-issue-555
drop-nix
plan-issue-484
plan-issue-539
plan-issue-535
plan-issue-474
plan-issue-533
fix-dagger-engineless-precommit
issue-521-fix-deploy-yml-wait-time-api
issue-502-fix-email-id-collision-mailbox
issue-492-eliminate-duplicate-build-runner
issue-494-website-change-detection
issue-491-parallelize-check
issue-478-fix-stalwart-dual-stack-bind
issue-475-allowed-addresses-glob
issue-473-search-result-reorder
issue-453-update-agentloop-defaults
issue-466-structured-search
issue-505-exclude-chaos-monkey-from-regular-ci
issue-509-fix-search-result-sorting
fix-ink-sparkle-remaining-tests
issue-506-fix-search-emails-tests
issue-504-runner-wait-time
issue-488-search-notes
issue-472-changelog-issue-links
issue-501-folder-search-local-sqlite
issue-486-fix-stale-test-shader-mismatch
fix/prevent-settled-search-rerun-473
issue-467-fix-search-stale-results
issue-446-installed-versions-in-changelog
issue-462-fix-pr
issue-448-chaos-monkey-test
issue-436-notes-on-emails
issue-429-unify-mail-display
issue-422-move-to-folder-create-new
issue-414-ensure-not-run-as-root
issue-424-unify-email-list-views
issue-419-trusted-senders-page
issue-425-fix-prs
test-foo
issue-421-bug-report
issue-383-fix-ci
issue-394-fix-deploy-flutter-version
issue-391-fix-ci-double-trigger
issue-376-combined-inbox-v2
issue-376-combined-inbox
issue-384-fix-open-prs
sops-migrate
issue-339-safe-first-on-imap-fetch
issue-340-try-catch-measure-height
issue-342-pin-intl-version
issue-341-guard-threademails-last
issue-335-agentloop-code-test
issue-329-fix
issue-315-fix
issue-320-fix
issue-325-fix
issue-312-fix
issue-311-fix
issue-305-fix
issue-304-fix
issue-299-fix
issue-300-fix
issue-298-fix
issue-296-fix
issue-294-fix
issue-289-fix
issue-288-fix
issue-287-fix
issue-286-fix
issue-277-fix
issue-282-fix
issue-280-fix
issue-272-fix
issue-268-fix
issue-267-fix
issue-266-fix
issue-258-fix
issue-260-fix
issue-257-fix
issue-253-fix
issue-216-fix
issue-251-fix
issue-249-fix
issue-question-fixes
issue-235-fix
issue-236-fix-v2
issue-237-fix
issue-236-fix
issue-228-fix
issue-217-fix
issue-214-fix
issue-213-fix
issue-208-fix
issue-205-fix
issue-204-fix
issue-203-fix
issue-202-fix
issue-129-fix
issue-161-fix
issue-160-fix
issue-201-fix
issue-210-fix
issue-198-fix
issue-200-fix
issue-144-fix
issue-199-fix
fix/playstore-upload-use-requests
issue-193-fix
issue-186-fix
issue-185-fix
issue-192-fix
issue-183-fix
issue-175-fix
issue-172-fix
issue-171-fix
issue-167-fix
issue-136-fix
issue-162-fix
issue-179-fix
issue-155-fix
issue-154-fix
issue-152-fix
issue-151-fix
issue-141-fix
issue-150-fix
issue-164-fix
migrate-to-dagger
task/d1-ci-matrix
task/a4-typeconverter-json
task/u7-onboarding-walkthrough
task/d3-sync-doc
task/a5-layer-boundary-lint
task/t5-golden-tests
task/p5-date-cache
task/s4-link-handling
task/p3-html-parse-isolate
task/u8-mark-all-read
task/u3-recent-searches
task/a3-jmap-injectable-http-client
task/r5-tls-error-handling
fix/playstore-redirect-retry
task/t3-repository-contract-tests
task/p2-email-list-pagination
task/p1-fts5-search
fix/playstore-upload-timeout
task/a1-email-detail-notifier
fix/upgrade-workmanager-0.9
fix/android-core-library-desugaring
task/p4-db-indexes
task/r3-html-error-boundary
task/d2-check-coverage
task/a2-email-tile
task/t4-migration-tests
task/t2-widget-tests
task/t1-email-repo-coverage
task/u6-connection-status
task/u4-push-notifications
task/u2-draft-sync
task/u1-list-unsubscribe
task/s2-hostname-validation
task/r6-reliability-fuzz-tests
task/r4-sync-error-banner
task/r2-force-resync
task/r1-undo-history-persistence
No results found.
Labels
Clear labels
NeedSupervisor
State/InProgress
State/Later
State/Planned
automerge
ci-failure
do-not-merge
loop/code
loop/code-ci-pending
loop/code-done
loop/code-in-process
loop/merge
loop/merge-done
loop/merge-in-process
loop/plan
loop/plan-done
loop/plan-in-process
Issue escalated to a human supervisor; agentloop will skip it until cleared.
Eligible for automatic merge by CI
Issue opened by agentloop to track a failing CI workflow; used for deduplication.
Plan PR — review only, do not merge.
Add to run the built-in "code" prompt; override at prompts/code.md.
Prompt "code" finished; waiting for the PR's CI to pass before advancing.
Prompt "code" finished successfully.
Agent for the "code" prompt is currently running on this issue.
Managed by agentloop
Managed by agentloop
Managed by agentloop
Add to run the built-in "plan" prompt; override at prompts/plan.md.
Prompt "plan" finished successfully.
Agent for the "plan" prompt is currently running on this issue.
No labels
loop/code-done
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: guettli/sharedinbox#361
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
do plan in below comment.
Let me read the relevant project files to understand the CI/CD setup before writing a plan.Let me look at the deploy scripts and Taskfile to understand the full picture.Now I have all the context I need to write the plan.Now I have everything I need. Here is the complete plan to post as a comment on issue #361.
Implementation Plan: Fix silent deploy failures in deploy.yml
Root cause analysis
The workflow shows green while the app is not deployed due to three compounding bugs:
Bug 1 (Critical): Wrong JSON field —
commit_shainstead ofhead_shaIn
check-changes, the Python snippet that determinesLAST_DEPLOYED_SHAreads:Forgejo's API returns this field as
head_sha(following GitHub's convention).commit_shais alwaysNone, soLAST_DEPLOYED_SHA = ""on every run. The fallback diff is alwaysHEAD~1..HEAD— only the single most recent commit's file changes are checked.Consequence: If android changes landed in commit A and the deploy failed (workflow=failure), and then a non-android commit B lands,
diff(A, B)shows no android changes →android=false→ deploy skipped → workflow=success. The failure at A is silently abandoned and never retried.Bug 2: Silent exception swallowing makes API failures invisible
The error goes to stderr only — not surfaced as a CI annotation.
LAST_DEPLOYED_SHAsilently becomes"", and the CI step continues as if nothing went wrong.Bug 3: "All-skipped" workflow runs count as "successfully deployed"
When
android=false, all deploy jobs areskipped. The overall workflow run still hasstatus=success. Once Bug 1 is fixed andLAST_DEPLOYED_SHAis correctly populated, it will be set to the SHA of this skipped run. If a deploy then fails at a later commit and no further android commits land, the skipped run's SHA becomes the reference — and a diff from a "skipped" SHA may fail to detect that a deploy is still outstanding.Changes to
.forgejo/workflows/deploy.ymlStep 1 — Fix
commit_sha→head_shaIn the
LAST_DEPLOYED_SHAPython block:Also verify whether Forgejo uses
statusorconclusionfor run completion state. Ifr.get("status") == "success"never matches, change tor.get("conclusion") == "success"and update the URL parameterstatus=success→conclusion=success.Step 2 — Make the exception a visible CI annotation
The
::error::prefix causes Forgejo Actions to surface this as a check annotation visible in the PR/run UI, not just a buried stderr line.Additionally, change the fallback strategy: when
LAST_DEPLOYED_SHA = ""due to an API failure, default toandroid=true(force-deploy) rather thanHEAD~1..HEAD. This ensures no deploy is silently skipped because the detection machinery broke.Step 3 — Only treat "actually deployed" runs as the last deployed SHA
The
status=successfilter includes runs where all deploy jobs wereskipped. After fixing Bug 1, this becomes the primary source of incorrect "last deployed" detection.Fix: after retrieving the candidate runs, check each run's job results via
/api/v1/repos/{repo}/actions/runs/{run_id}/jobsand select only the first run where thedeploy-playstorejob hasresult == "success"(not"skipped").Step 4 — Add a post-deploy verification step in
deploy-playstoreAfter
task publish-androidsucceeds, add a new step that queries the Play Store API to confirm the new version code is present on the internal track. If it is not, fail loudly. The verification logic can reusescripts/deploy_playstore.py's authentication pattern. A new scriptscripts/verify_playstore_deploy.pyshould:This catches the case where
dagger call publish-androidexits 0 despite an internal Play Store API failure.Step 5 — Add explicit
::notice::annotations when skippingIn
check-changes, when outputtingandroid=false, add an annotation so the skip reason is visible in the Actions UI:For the "already deployed" early exit:
Summary of changes
.forgejo/workflows/deploy.ymlcommit_sha→head_sha;::error::on API exception; fallback toandroid=trueon lookup failure; filterLAST_DEPLOYED_SHAto runs wheredeploy-playstoreactually succeeded; add::notice::skip annotations.forgejo/workflows/deploy.ymltask publish-android: runscripts/verify_playstore_deploy.pyscripts/verify_playstore_deploy.pyPLAY_STORE_CONFIG_JSON, query internal track, fail if expected version code absentLet me read the issue details and project files to understand what needs to be done.Let me check the Forgejo runner Dockerfile and the recent git history to understand the issue better.Let me check a few more files for context on the issue plan.Let me try using the
fgjtool to get the issue comments since the plan should be in a comment.Now I have the full plan from the issue comment. Let me implement the fixes:commit_sha→head_sha(the primary bug)deploy-playstoreactually succeeded (not just skipped)::error::annotation::notice::annotations for skip/trigger messagesdeploy.yml:Now add the verify step after thePublish Android to Play Storestep:Now create theverify_playstore_deploy.pyscript:Now let me also add a test forverify_playstore_deploy.py. Let me check if there are existing tests for similar scripts:Now let me verify the deploy.yml looks correct after the edits:I need to also installrequestsalongsidegoogle-authsinceAuthorizedSessiondepends on it:Now let me run the existing unit tests to make sure nothing is broken:All tests pass. Now let me commit the changes and push:Good. Let me now commit:The PR is open at https://codeberg.org/guettli/sharedinbox/pulls/364.Here's what was done for issue #361 ("App in PlayStore was not updated"):
Root cause (from the issue plan comment): Three compounding bugs in
.forgejo/workflows/deploy.ymlcaused the Play Store to silently fall behind.Bug 1 —
commit_sha→head_sha(primary bug)Forgejo's API returns
head_sha;commit_shais alwaysNone. SoLAST_DEPLOYED_SHAwas always empty and the diff fell back toHEAD~1..HEAD— only the single most recent commit. Android changes in earlier commits were silently missed.Bug 2 — Skipped runs counted as "deployed"
A workflow run where
deploy-playstorewas skipped (android=false) still hasstatus=successoverall. The code now queries each run's job results via the jobs API and only uses a run where the "Build & Deploy to Play Store" job's ownconclusion=success.Bug 3 — Narrow fallback when SHA unknown
When
LAST_DEPLOYED_SHAcouldn't be determined, the fallbackHEAD~1..HEADdiff was dangerously narrow. Now it defaults toandroid=true / linux=true(deploy everything) as the safe default.Additional changes:
::error::/::warning::/::notice::workflow annotations so skip/failure reasons appear in the Actions UIscripts/verify_playstore_deploy.py: new post-deploy script that queries the internal track and fails if the latest version code is >1 hour old (version codes are Unix timestamps perci/main.go)scripts/test_verify_playstore_deploy.py: 5 unit tests (all passing)