* feat(desktop): scaffold Tauri 2 macOS shell with empty window
* feat(desktop): server store, URL normalization, and health-check helpers
* feat(desktop): IPC commands for server list/add/remove/health + active-server state
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* feat(desktop): native onboarding server picker with health check and remembered servers
* feat(desktop): vibrancy background, overlay titlebar, and inset traffic lights
* feat(desktop): native menu bar with standard shortcuts and menu events
* feat(desktop): webview→Rust bridge with native notifications
* fix(desktop): gate bridge injection on PageLoadEvent::Finished
Prevents double-injecting the bridge IIFE (once on Started, once on
Finished), which was duplicating every native notification.
* feat(desktop): Dock badge driven by webview attention count
* feat(desktop): launch-at-login autostart commands
* feat(desktop): sure:// deep link scheme with parse tests and navigation
* feat(desktop): preferences window with server switcher and launch-at-login
* docs(desktop): README for dev, release, signing/notarization, and deferred widget
* fix(desktop): remove dead New Window menu item
* fix(desktop): correct login route to /sessions/new
Rails uses `resources :sessions` (plural), so the login page is
/sessions/new, not the /session/new the plan assumed. Fixes an
immediate 404 when connecting to a server.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* feat(desktop): Sure-styled onboarding, draggable titlebar, and app content offset
- Restyle onboarding + prefs to match Sure's auth page: solid surface
background, centered logomark, .form-field-style inputs, inverse primary
button; theme-aware via prefers-color-scheme (design-system tokens).
- Add a draggable titlebar strip on bundled pages and inject one into the
remote page so the window drags from the top everywhere.
- Inject a top offset on the logged-in app-layout root so the sidebar logo
clears the macOS traffic lights.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* fix(desktop): de-dupe login navigation to prevent CSRF token/session race
connect() navigated to /sessions/new directly AND via the
active-server-changed event, which is also handled by a second listener
injected into the page by bridge.js. One connect fired multiple concurrent
GET /sessions/new requests, each minting a fresh session + CSRF token; the
form shown and the _sure_session finally stored could come from different
GETs, so the login POST failed 'Can't verify CSRF token authenticity'
intermittently. Route all navigation through a single window-level guard so
only the first request per server wins.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* fix(desktop): enable window drag permission; offset only the icon rail
- Add core:window:allow-start-dragging (+ show/set-focus, event emit/listen) to
capabilities so data-tauri-drag-region actually drags the window on macOS.
- Offset only the 84px left icon rail (logomark) to clear the traffic lights
instead of pushing the entire app-layout down; keep main content full-height.
- Drag strip z-index lowered below Sure's sticky headers so its controls stay
clickable.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* feat(desktop): persist active server and resume session on launch
- Persist the active server to the Keychain in set_active_server; active_server
falls back to it so a relaunch knows where to go.
- On launch, auto-resume straight to the last server instead of showing the
picker every time.
- Navigate to the server root (not /sessions/new): Rails serves the dashboard
when the session cookie is still valid, or redirects to login when not — so a
persisted session no longer forces a re-login.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* feat: desktop SSO via system browser with PKCE code exchange
Passkeys/WebAuthn don't work in an embedded WKWebView, so SSO now runs in
the system browser and hands a session back to the app securely.
Server (Rails):
- GET /auth/desktop/:provider — stashes a PKCE S256 challenge, hands off to
OmniAuth (reusing the mobile auto-submit form). Passkeys work (real browser).
- openid_connect — for a linked identity in a desktop flow, mints a single-use,
2-min, PKCE-bound one-time code and redirects to sure://sso/callback?code=...
(unlinked identities are sent back with an error).
- GET /sessions/desktop_exchange — verifies the code + PKCE verifier
(secure_compare), single-use (cache delete), then create_session_for; MFA is
enforced at exchange time. Sets the normal web session cookie in the webview.
- Tests: happy path + single-use, wrong-verifier rejection, missing challenge.
Desktop (Tauri):
- start_sso command: generates PKCE, opens the browser, stores the verifier.
- sure://sso/callback deep link -> webview navigates to desktop_exchange with
the verifier (never sent through the deep link, so an intercepted code is
useless).
- bridge.ts intercepts SSO provider form submits and routes them to start_sso;
password login stays in the webview.
- remote.json capability: minimal IPC (drag, event bridge, prefs window,
start_sso) for the remote Sure origin — no fs/shell/http.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* fix(desktop): correct remote IPC capability + handle menu in Rust + drag fallback
Root cause of prefs/switch-server/SSO/drag doing nothing on the logged-in
page: the remote-bridge capability's remote.urls ('https://*') did not match
the server origin, so all IPC (event listen, invoke, drag command) was denied.
Per Tauri v2, window.__TAURI__ is injected on remote pages only with
withGlobalTauri (set) AND a matching remote.urls; patterns need a path
wildcard.
- remote.json: urls -> https://*/**, http://*/** (+ bare host) so any server
origin matches.
- menu.rs: Preferences and Switch Server now show the prefs window directly in
Rust (no dependency on remote-page IPC); Switch Server moved from Window to
the App menu.
- bridge.ts: drops the menu-event listeners (Rust owns them), adds a
startDragging mousedown fallback for the drag strip, logs diagnostics, and
reports start_sso success/failure to the console.
- main.ts: drops the now-unused menu listeners.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* fix(desktop): SSO via event (remote can't invoke commands), disk-backed server store
Diagnostics confirmed window.__TAURI__ + IPC work on the remote page, but a
remote origin cannot invoke custom commands ('start_sso not allowed. Plugin
not found'). Events are permitted, so SSO now goes through an event.
- SSO: bridge emits 'sure://start-sso'; Rust listens and runs begin_sso
(opens the system browser). start_sso command kept for local use.
- servers: mirror the server list + active server to a JSON file in
Application Support as a fallback — Keychain items don't persist for
unsigned builds, which was wiping the saved server on relaunch.
- remote.json: add notification:default (Sure's PWA was requesting it and
erroring).
- menu: log whether the prefs window is present when Preferences/Switch
Server fire, to diagnose the no-op.
- main: log the persisted active server on boot.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* fix(desktop): drag the top band on every page via mousedown, not a z-indexed strip
The fixed drag strip sat below Sure's sticky headers (z-10) so it worked only
on pages without a top header. Replace it with a document-level mousedown in the
top ~34px that starts a window drag unless the target is an interactive element
— so dragging works on all pages, Sure's titlebar controls stay clickable, and
main content isn't pushed down.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* ci(desktop): tag-triggered GitHub Actions release for universal unsigned .dmg
- .github/workflows/desktop-release.yml: on a 'desktop-v*' tag, build the
universal (Apple Silicon + Intel) .dmg on a macOS runner via tauri-action and
publish it to a GitHub Release with unsigned-install instructions.
- README: universal build command, the tag-based release process, and the
Gatekeeper 'Open Anyway' / xattr steps for end users.
- Drop the unused iOS/Android icon sets (macOS build only needs icon.icns).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* ci(desktop): rolling desktop-latest build on desktop/ changes, not manual tags
Replaces the manual desktop-v* tag release with a path-filtered workflow that
builds only when desktop/ changes on main and publishes to a single rolling
'desktop-latest' prerelease with a stable Sure.dmg filename — one permanent
download URL, and the file changes only when the desktop code does.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* ci(desktop): tag-driven versioned releases; tag is the single source of version
Revert to manual version tags (desktop-v*) for explicit version control, but
derive the app/.dmg version from the tag so package.json + tauri.conf.json are
synced automatically in CI — no manual version-file edits. Each tag produces its
own versioned GitHub Release with the universal unsigned .dmg.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* ci(desktop): release entirely from GitHub via workflow_dispatch version input
Make the GitHub Action the single tool to version + deploy the desktop app:
Run workflow -> enter a version -> it syncs the version, builds the universal
unsigned .dmg, and creates the desktop-v<version> tag + Release. Refuses to
re-release an existing version; marks pre-release versions accordingly. Tag
push (desktop-v*) still works as a secondary trigger.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* ci(desktop): publish releases with make_latest:false so they don't hijack the repo's Latest badge
Desktop is a secondary artifact, not the main product. Build with tauri-action,
then publish via action-gh-release with make_latest:false so the repo's 'Latest
release' badge stays on the main app's v* release. Separate desktop-v* tag
namespace already keeps it out of the v* publish workflow.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* fix(desktop): address PR review feedback (security + correctness)
Security:
- workflow: pass workflow_dispatch version via env (no shell injection); pin all
third-party actions to commit SHAs.
- SSO: gate deep-link navigation and begin_sso to servers the user has saved
(is_known_server), so a rogue page/deep link can't drive them.
- desktop_exchange is now POST (verifier in body, not URL/logs); CSRF skipped
since the single-use PKCE code is the protection.
- desktop_sso_start validates the code_challenge is a 43-char base64url digest.
- desktop_exchange claims the one-time code atomically (delete-and-check) to
close the read/delete TOCTOU.
- failure: return desktop SSO errors to the app via sure://sso/callback?error.
Correctness / stability:
- prefs window hides on close instead of being destroyed, so the menu can
reopen it.
- servers.rs: on-disk store is authoritative (file-first read), atomic writes
(temp + rename).
- main.ts/prefs.ts: try/catch around add/set/remove/active_server and boot; add
a shared serverErrorMessage helper (no duplicated substring checks).
- vite.config.ts: derive dir from import.meta.url (ESM has no __dirname).
- bridge.ts: coalesce MutationObserver scans to one per frame.
- README: notarization example uses the universal .dmg name.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* fix(desktop): scope remote IPC to server origins at runtime, drop wildcard capability
Resolves the remaining security finding: the static remote.json granted Tauri
IPC to any http(s) origin (https://*). Remove it and instead add a capability
scoped to each server's exact origin at runtime (CapabilityBuilder +
add_capability), granting only the minimal permissions the bridge needs, for
saved/active servers on startup and for the target in set_active_server. No
origin outside the user's configured servers can access IPC.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* fix(desktop): add runtime per-origin IPC capability (grant_server_capability)
Implements the runtime-scoped capability that replaces the removed wildcard
remote.json: CapabilityBuilder scoped to each server's exact origin, added via
add_capability for saved/active servers at startup and in set_active_server.
(Split from the previous commit, which only recorded the remote.json removal.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* ci(desktop): harden release workflow (no shared caches, environment gate)
Address two release-workflow security findings:
- Remove cache: npm and the swatinem/rust-cache step so a poisoned Actions
cache written by another workflow can't flow into a published .dmg (P0).
- Add 'environment: release' to the build job so publishing can require manual
approval and scope secrets to release runs (P1).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nno38ujctqiqSoY8eFRhaf
* fix(desktop): remove transparency code and fix relaunch behavior
* fix(desktop): fix PR review findings; adjust app notarization path, use Sure theme tokens instead of hardcoding values
* ci(desktop): switch release from independant versioning to using Sure's publishing workflow, releasing and versioning with every main app release
* fix(desktop): restrict CSP as much as possible while maintaining functionality; allow bundled scripts, Tauri IPC, inline styles; deny wildcards
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* Bump version to next iteration after v0.7.3-alpha.4 release
* Use GitHub token for automated version bump PRs
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* Bump version to next iteration after v0.7.3-alpha.3 release
* Fix automated version bump pull requests
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* Fix prerelease version bump workflow
* Fix prerelease version-bump job: add PR fallback for protected branches
### Motivation
- The prerelease version bump job was failing when it could not push to protected release branches, causing the workflow to error instead of progressing.
- The job needs permission and robust push logic so prerelease automation can update `.sure-version` and `charts/sure/Chart.yaml` even when direct pushes are blocked.
### Description
- Grant the `bump-pre_release-version` job `pull-requests: write` permission so it may open an automated PR when direct pushes are disallowed.
- Harden the bump step: enable `set -euo pipefail`, pass `GH_TOKEN` into the job environment, and use fully-qualified branch refs for pushes.
- Add retry + rebase logic for direct pushes and a fallback path that pushes the changes to an `automation/bump-version-after-...` branch and opens a PR with `gh pr create` when direct push attempts fail.
- Preserve existing validations that ensure `.sure-version` and `charts/sure/Chart.yaml` exist and the prerelease portion is parsed before writing the bump.
### Testing
- Verified workflow YAML parses with `ruby -e 'require "yaml"; YAML.load_file(".github/workflows/publish.yml"); puts "YAML OK"'` and it succeeded.
- Confirmed the bump job has the expected permission with `ruby -e 'require "yaml"; workflow=YAML.load_file(".github/workflows/publish.yml"); abort("missing bump job") unless workflow.dig("jobs", "bump-pre_release-version", "permissions", "pull-requests") == "write"; puts "bump permissions OK"'` and it succeeded.
- Ran ActionLint via `go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.8 .github/workflows/publish.yml` and received no actionable errors.
- Ran `git diff --check` to ensure no whitespace/format issues and it succeeded.
* Harden pre-release bump job: validation, retries and PR fallback
### Motivation
- Make the `bump-pre_release-version` job more robust by validating prerelease version formats and failing early on unexpected inputs.
- Handle protected branches gracefully by attempting direct pushes with retries and falling back to creating a pull request when direct push is blocked.
- Ensure the workflow has the permissions required to open PRs when needed.
### Description
- Added `pull-requests: write` to the job `permissions` so the workflow can create PRs when required.
- Hardened the bump script with `set -euo pipefail` and a strict regex that validates and extracts `BASE_VERSION`, prerelease tag, and number using `BASH_REMATCH` before incrementing the prerelease counter.
- Simplified and made file reads safer by using input redirection for `tr` and improved error messages for missing or malformed version files.
- Reworked commit/push logic to set a commit message variable, attempt direct pushes with exponential backoff and detection of branch-protection errors, and when rejected create a dedicated bump branch and open a PR via `gh pr create`.
### Testing
- Validated the modified workflow YAML with a YAML linter; no syntax errors were reported.
- Executed the updated bump logic in a CI dry-run (workflow syntax validation on GitHub Actions) and the workflow file was accepted by the Actions syntax checks.
* Add manual workflow triggers and robust pre-release bump with protected-branch fallback
### Motivation
- Allow manual invocation of PR and chart CI workflows via `workflow_dispatch` for on-demand runs.
- Make the pre-release version bump process more robust and reliable when `refs/tags/v*` releases are published.
- Ensure the bump can proceed even when the target branch is protected by creating an automated pull request and running PR checks.
### Description
- Added `workflow_dispatch` to `.github/workflows/pr.yml` and `.github/workflows/chart-ci.yml` to support manual runs.
- Extended `bump-pre_release-version` job in `.github/workflows/publish.yml` to request `actions: write` and `pull-requests: write` permissions.
- Rewrote the bump script to use `set -euo pipefail` and a single regex validation to parse and increment prerelease versions (e.g. `1.2.3-alpha.4`), update `.sure-version`, and update `charts/sure/Chart.yaml` reliably.
- Improved commit and push flow by adding `GH_TOKEN`, using a consistent commit message variable, attempting direct pushes with retry and rebase, detecting branch-protection failures, and falling back to creating a bumped branch and an automated PR via `gh pr create`; the workflow also dispatches `pr.yml` and `chart-ci.yml` runs for the created branch.
### Testing
- No automated tests were run as part of this change; behavior will be exercised when the workflow creates a bump PR or when workflows are manually triggered via the new `workflow_dispatch` events.
* chore(ci): pin GitHub Actions to commit SHAs (#1811)
Follow-up to #1810. The Node-24 upgrade left every workflow on mutable
tag refs (`actions/checkout@v5`, `actions/download-artifact@v7`, etc.)
which superagent-security[bot] flagged on the ci.yml + publish.yml
reviews.
Pin all 18 external actions to the commit SHA they currently resolve to
and add a trailing `# vMAJOR.MINOR.PATCH` comment so reviewers can see
the version. Local reusable-workflow refs (`uses: ./.github/...`) are
left alone — pinning those would defeat the point.
Closes#1811
* chore(ci): address review — persist-credentials + setup-node consistency (#1811)
Two pieces of follow-up feedback on the SHA-pinning PR:
- @coderabbitai (P1 nitpicks) + @JSONbored: add 'persist-credentials:
false' to checkout steps in jobs that don't perform authenticated git
operations. Adds the line to 17 read-only checkouts across 9
workflows (chart-ci, ci, flutter-build, helm-publish, ios-testflight,
llm-evals, preview-cleanup, preview-deploy, publish:build).
Checkouts inside jobs that 'git push' (chart-release, mobile-build,
mobile-release, helm-publish:second-checkout, publish:bump-pre_release)
are intentionally left alone so they keep their token.
- @jjmata: preview-deploy.yml was the only workflow on
actions/setup-node v6.4.0; everywhere else pinned v5.0.0. Standardise
on v5.0.0 to match.
Dependabot config already has a github-actions ecosystem entry with a
weekly schedule, so no addition needed for that point.
* chore(ci): document intentional setup-node v6→5 normalization (#1811)
@superagent-security flagged the v6.4.0 -> v5.0.0 change in
preview-deploy.yml as a possible unintended downgrade. The downgrade
was deliberate, per @jjmata's review request to normalize setup-node
across all workflows. Add an inline YAML comment next to the line so
future scans don't re-flag it.
---------
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: jeffrey701 <jeffrey701@users.noreply.github.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
* Extract version to .sure-version file and add Sentry release tracking
Move the hardcoded version string to a `.sure-version` file at the repo
root so it can be read by both the Rails version initializer and other
tooling. Configure `config.release` in the Sentry initializer to tag
errors with the app version.
https://claude.ai/code/session_01KfUgF42B3exoU2vpErqJyW
* Use .sure-version as single source of truth in Helm CI workflows
Update chart-ci, chart-release, and publish workflows to read the app
version from .sure-version instead of regex-parsing version.rb. The
pre-release bump job now writes directly to .sure-version and stages it
for commit.
https://claude.ai/code/session_01KfUgF42B3exoU2vpErqJyW
* Guard empty .sure-version fallback
* fix: sync Helm chart version with .sure-version
* Moving on to `v0.7.1-alpha.*` with this
* Defensive rescue
* Getting fancy with versions now
---------
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: SureBot <sure-bot@we-promise.com>
Co-authored-by: sure-admin <sure-admin@splashblot.com>
* Unify release workflows and add chart/mobile wrappers
* Update chart CI to kube 1.25
* Fetch tagged commit before pushing release branch
* Old `azure/setup-helm`
* Base chart dispatch version on existing chart tags
* `grep` failure with `pipefail` bypasses the user-friendly error message
* `gh-pages` push lacks retry logic
* Auto-incremented chart tag collision
* `grep -Ev` pipeline will crash
* Missed one
* fix: locale-dependent category duplication bug
* fix: use family locale for investment contributions category to prevent duplicates and handle legacy data
* Remove v* tag trigger from flutter-build to fix double-runs
publish.yml already calls flutter-build via workflow_call on v* tags,
so the direct push trigger was causing duplicate workflow runs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Refactor mobile release asset flow
* fix: category uniqueness and workflow issues
* fix: fix test issue
* fix: solve test issue
* fix: resolve legacy problem
* fix: solve lint test issue
* fix: revert unrelated changes
---------
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The bump-pre_release-version job was hardcoded to push to main, which
caused version bumps to land on main even when tags were created from
release branches (e.g., v0.6.7-rc.2).
This fix:
- Adds a step to detect which branch contains the tagged commit
- Prefers non-main branches (release branches) over main
- Checks out and pushes to the detected source branch
https://claude.ai/code/session_01XsxnhP8ZaGbWUMsQwA5F5V
Co-authored-by: Claude <noreply@anthropic.com>
* Update chart version in pre-release bump
Keep Helm chart version and appVersion aligned with app releases.
* Publish Helm chart with releases
Package the Helm chart on tag releases, upload it to GitHub Pages, and attach it to the GitHub Release assets.
* Move Helm chart release to helm workflow
Publish Helm chart packages from the helm-release workflow on tags and keep publish.yml focused on app release assets.
* Derive nightly chart version from latest release
Use the most recent v* tag as the base for nightly Helm chart versions.
* Generalize pre-release bump workflow
Handle alpha, beta, and rc tags when incrementing the version.
* Change commit message for version bump in workflow
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
---------
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Added debugging information to list downloaded artifacts and check for mobile and iOS build directories.
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
* Add debug mobile artifacts to GitHub releases
- Modify flutter-build.yml to trigger on version tags (v*) and support
workflow_call for use by other workflows
- Add mobile job to publish.yml that calls flutter-build workflow
- Add release job that creates GitHub release with debug APK and
unsigned iOS build when a version tag is pushed
- Auto-detect debug vs release APK and name appropriately
- Mark alpha/beta/rc versions as pre-releases
* Add automatic alpha version bump after release
When an alpha tag (e.g., v0.6.7-alpha.3) is published and the Docker
image is built, automatically bump the alpha number in version.rb
(e.g., alpha.3 -> alpha.4) and push to main branch.
* Fix APK copying to include both debug and release builds
Change if/elif to separate if statements so both app-debug.apk and
app-release.apk are copied to release assets when both exist.
* Rename artifact names in publish workflow
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
* Revert rename of artifact names
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
* Enhance version bump process in publish.yml
Refactor version bump script to ensure version file exists and improve error handling.
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
---------
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
* feat(ci): add OCI annotations and metadata to multi-arch images
- Include created, source, revision, ref-name, vendor & license
- Add title and description for Sure Rails app multi-arch image
- Dynamically annotate version when tag builds are triggered
* chore(ci): add nightly tag with weekday pattern to tag config
* fix(ci): allow publish workflow to push images from main branch
- Update conditional checks to include refs/heads/main
- Reflect new condition in workflow comments for clarity
* fix(ci): set image version label only for tag builds in metadata
* fix(ci): avoid quotations being passed as CLI argument
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Himank Dave <93311724+steadyfall@users.noreply.github.com>
* refactor(ci): remove deprecated `::set-output` command
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Himank Dave <93311724+steadyfall@users.noreply.github.com>
---------
Signed-off-by: Himank Dave <93311724+steadyfall@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* chore: update Docker image description to 'Sure'
* chore: adjust Docker metadata tags in publish workflow
- Disable automatic 'latest' tag generation
- Add 'nightly' tag for scheduled builds
* feat: add optional 'push' input to control image publishing
- Allow toggling push behavior via workflow input
- Allow push to 'ghcr.io' on tags, scheduled events, or when
input is true
* chore: switch Docker cache to use registry-based build cache
* feat(ci): add multi-arch matrix image build & manifest merge
- Build and push images for amd64 and arm64 with platform-specific cache
- Export and upload image digests for each platform
- Merge digests into multi-arch manifest with retry logic
- Remove QEMU setup, use platform-specific runners
- Dynamic tag configuration for nightly, stable, and SHA tags
* chore(deps): pin external actions to specific minor versions
* Bump actions/checkout to v4.2.0
* Bump docker/setup-buildx-action to v3.10.0
* Bump docker/login-action to v3.3.0
* Bump docker/metadata-action to v5.6.0
* Bump docker/build-push-action to v6.16.0
* chore(ci): improve publish workflow robustness
- Set artifact upload to error if no files found & limit retention to 1 day
* chore(ci): enable OCI media types in Docker build outputs
* feat(ci): add scheduled nightly publish at 01:30 UTC
* chore(ci): refine image publish workflow and clarify multi-arch steps
- Add reference and conditions for push in workflow comments
- Rename build step for clarity on published platform target
- Ensure oci-mediatypes is preserved for annotations to show
- Rename merge job to indicate pushing multi-arch manifest tag
linux/arm/v7 is not compatible with the latest Tailwind package + takes a significant amount of time when using buildx. Most Raspberry Pi OS now run on 64 bit ARM architecture, so we should still have significant coverage with linux/amd + linux/arm builds.
Signed-off-by: Zach Gollwitzer <zach@maybe.co>