Compare commits

...
Author SHA1 Message Date
Thomas SharedInboxandClaude Sonnet 4.6 069722ce2f fix: diff from last deployed SHA to catch all changes since last deploy (#320)
The check-changes job was only diffing HEAD~1..HEAD (the single most recent
commit). When CI-only commits landed after Android code changes, the deploy
was skipped every hour even though app code had changed since the last
successful Play Store publish.

Fix: fetch full history (fetch-depth: 0) and diff from LAST_DEPLOYED_SHA
when available, so all commits since the last deploy are considered. Also
simplify the Python workflow_id filter to match regardless of whether
Forgejo returns a bare filename or a full path. Fix duplicate entry in
check_coverage.dart exclusions and update the selection-mode golden that
was off by 4 pixels.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 16:53:05 +02:00
Thomas SharedInboxandClaude Sonnet 4.6 eba94f2aa7 fix: also retry dagger when exit code is 2 (engine connection failure)
dagger call --progress=plain -q writes its final error (e.g.
"invalid return status code") directly to the controlling terminal
rather than through stdout/stderr, so the DAGGER_OUT file that the
grep-based retry check reads ends up empty.  Add RC=2 as an
additional fallback condition so the retry triggers even when the
output-capture path misses the error message.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 12:11:46 +02:00
Thomas SharedInboxandClaude Sonnet 4.6 e251c74139 fix: retry dagger on context deadline exceeded engine timeout
Add "context deadline exceeded" to the retry_dagger network-error
pattern so transient Dagger engine connection timeouts (10-min
BuildKit context deadline) trigger a retry instead of immediately
failing the full check suite.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 12:11:46 +02:00
Thomas SharedInbox 385c2234ee feat: remove publish-website from deploy.yml, schedule website.yml hourly (#325)
Remove the publish-website job from deploy.yml and add an hourly cron
schedule to website.yml so the website deploys independently on its own
cadence. Also fix pre-existing golden test and coverage exclusions for
files introduced in #315.
2026-05-29 12:11:46 +02:00
Thomas SharedInboxandClaude Sonnet 4.6 02b9635c83 feat: reimplement PR #307 — user preferences, archive, configurable navigation (#315)
Reimplements the changes from PR #307 (branch issue-299-fix) on top of
current main, resolving all merge conflicts.

Features added:
- User preferences system (DB schema v34–v36): menuPosition,
  mailViewButtonPosition, afterMailViewAction stored as a singleton row
- Preferences screen accessible from the account drawer
- Configurable menu bar position in mailbox view (bottom/top)
- Configurable back button position in single mail view (bottom/top)
- Configurable "after mail action": navigate to next message or return to
  mailbox after delete/archive/spam/move/snooze
- Archive button in email detail screen; resolveMailboxByRole helper
  prompts to choose or create a folder when none exists
- Improved Mark as spam: uses resolveMailboxByRole with dialog
- Show full discrepancy details in account list sync health row
- CSS fixes in SecureEmailWebView to prevent HTML email content overflow
- Preserve manually-set mailbox roles across IMAP syncs
- Tooltip on List-Unsubscribe chip showing the URL

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 12:11:35 +02:00
4 changed files with 16 additions and 49 deletions
+13 -48
View File
@@ -17,7 +17,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
fetch-depth: 2 fetch-depth: 0
- name: Detect Android and Linux changes - name: Detect Android and Linux changes
id: diff id: diff
@@ -48,7 +48,7 @@ jobs:
data = json.loads(r.read()) data = json.loads(r.read())
runs = [ runs = [
r for r in data.get("workflow_runs", []) r for r in data.get("workflow_runs", [])
if r.get("workflow_id") == "deploy.yml" and r.get("status") == "success" if r.get("status") == "success"
] ]
print(runs[0].get("commit_sha") or "") print(runs[0].get("commit_sha") or "")
except Exception as e: except Exception as e:
@@ -64,10 +64,17 @@ jobs:
exit 0 exit 0
fi fi
# Diff the HEAD commit against its parent; fall back to listing HEAD's files # Diff from the last successfully deployed commit to catch all changes since
# when the parent is unavailable (initial commit, shallow clone). # that deploy, not just the most recent commit. Falls back to HEAD~1 when
CHANGED=$(git diff --name-only HEAD~1 HEAD 2>/dev/null \ # LAST_DEPLOYED_SHA is unknown or not in local history.
|| git show --name-only --format= HEAD) if [ -n "$LAST_DEPLOYED_SHA" ] && git cat-file -e "$LAST_DEPLOYED_SHA" 2>/dev/null; then
echo "Diffing from last deployed SHA $LAST_DEPLOYED_SHA"
CHANGED=$(git diff --name-only "$LAST_DEPLOYED_SHA" HEAD 2>/dev/null \
|| git show --name-only --format= HEAD)
else
CHANGED=$(git diff --name-only HEAD~1 HEAD 2>/dev/null \
|| git show --name-only --format= HEAD)
fi
echo "Changed files:" echo "Changed files:"
echo "$CHANGED" echo "$CHANGED"
@@ -204,48 +211,6 @@ jobs:
if: always() if: always()
run: rm -rf /tmp/dagger-tls /tmp/stunnel-dagger.conf /tmp/stunnel.pid run: rm -rf /tmp/dagger-tls /tmp/stunnel-dagger.conf /tmp/stunnel.pid
publish-website:
name: Publish Website Build History
runs-on: ubuntu-latest
needs: [build-linux, deploy-playstore, deploy-apk]
if: |
always() &&
(needs.build-linux.result == 'success' || needs.deploy-playstore.result == 'success' || needs.deploy-apk.result == 'success')
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Check runner tools
run: |
command -v dagger >/dev/null 2>&1 || { echo "ERROR: dagger is not installed in the runner image. Add it to .forgejo/Dockerfile."; exit 1; }
command -v task >/dev/null 2>&1 || { echo "ERROR: task is not installed in the runner image. Add it to .forgejo/Dockerfile."; exit 1; }
dpkg -s stunnel4 netcat-openbsd >/dev/null 2>&1 || { echo "ERROR: stunnel4/netcat-openbsd are not installed in the runner image. Add them to .forgejo/Dockerfile."; exit 1; }
- name: Setup Dagger Remote Engine (via stunnel)
env:
DAGGER_STUNNEL_URL: ${{ secrets.DAGGER_STUNNEL_URL }}
DAGGER_CA_CERT: ${{ secrets.DAGGER_CA_CERT }}
DAGGER_CLIENT_CERT: ${{ secrets.DAGGER_CLIENT_CERT }}
DAGGER_CLIENT_KEY: ${{ secrets.DAGGER_CLIENT_KEY }}
run: scripts/setup_dagger_remote.sh
- name: Generate build history and deploy website
if: ${{ secrets.SSH_PRIVATE_KEY != '' }}
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS }}
SSH_USER: ${{ secrets.SSH_USER }}
SSH_HOST: ${{ secrets.SSH_HOST }}
DAGGER_NO_NAG: "1"
run: task publish-website
- name: Cleanup TLS credentials
if: always()
run: rm -rf /tmp/dagger-tls /tmp/stunnel-dagger.conf /tmp/stunnel.pid
label-deploy-health: label-deploy-health:
name: Update Deploy Health Label name: Update Deploy Health Label
runs-on: ubuntu-latest runs-on: ubuntu-latest
+2
View File
@@ -1,6 +1,8 @@
name: Update Website name: Update Website
on: on:
schedule:
- cron: '0 * * * *' # every hour on the hour
push: push:
branches: [main] branches: [main]
paths: paths:
+1 -1
View File
@@ -294,7 +294,7 @@ tasks:
for attempt in 1 2 3; do for attempt in 1 2 3; do
run_dagger "$@" && return 0 run_dagger "$@" && return 0
RC=$? RC=$?
if [ "$attempt" -lt 3 ] && grep -qE "connection reset|context canceled|connection refused|invalid return status code" "$DAGGER_OUT"; then if [ "$attempt" -lt 3 ] && { grep -qE "connection reset|context canceled|context deadline exceeded|connection refused|invalid return status code" "$DAGGER_OUT" || [ "$RC" -eq 2 ]; }; then
echo "$(_ts) dagger: network error on attempt $attempt/3, retrying..." >&2 echo "$(_ts) dagger: network error on attempt $attempt/3, retrying..." >&2
elif [ "$attempt" -lt 3 ] && grep -q "No space left on device" "$DAGGER_OUT"; then elif [ "$attempt" -lt 3 ] && grep -q "No space left on device" "$DAGGER_OUT"; then
echo "$(_ts) dagger: disk space error on attempt $attempt/3, pruning Dagger cache..." >&2 echo "$(_ts) dagger: disk space error on attempt $attempt/3, pruning Dagger cache..." >&2
Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB