* [AI] Submit App Store releases automatically and move TestFlight uploads to nightly
On a published release both the iOS and Mac App Store workflows now wait for
Apple to process the uploaded build, attach it to the App Store version for
the release, fill in the release notes and submit it for review with
automatic release after approval. The TestFlight uploads run on a nightly
schedule instead of on every master push.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* [AI] Publish App Store builds with the Codemagic App Store Connect CLI
Replace the hand-written submission script and the altool upload with
`app-store-connect publish`, which uploads the build, waits for processing
and submits it for review in one step. The iOS export now writes the .ipa
locally so the CLI can upload it, matching the Mac flow.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* [AI] Run the App Store Connect CLI through pipx instead of a virtualenv
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* [AI] Share the App Store Connect publish step between the iOS and Mac workflows
Move the upload and review submission into one composite action so the CLI
version and submission flags live in a single place, drop step outputs that
nothing read, clean up signing material right after signing instead of after
the processing wait, and remove export options that were already defaults.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* [AI] Do not submit prereleases for App Store review
Prereleases still upload to TestFlight; only full releases are submitted.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* [AI] Send TestFlight builds to the external beta testers group
Every uploaded build is now added to the "Beta testers" TestFlight group and
submitted for Beta App Review, so external testers get the nightly builds
without a manual step. The FAQ links to the public TestFlight invite.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* [AI] Wait for the uploaded build to appear before the processing wait
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* [AI] Add a sandboxed Mac App Store build and publish it from CI
The Mac App Store build of Electron must run inside the App Sandbox with an
app-group entitlement, otherwise it aborts on launch. Configure the mas and
mas-dev targets with the required entitlements, add a release script that
uploads the signed package, and run it from CI on every master push and
release.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* [AI] Fix the Mac App Store build number and package path
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* [AI] Require an Admin App Store Connect key for iOS publishing
The export step needs cloud signing, which Apple only allows for API keys
with the Admin role. Document that so the secret is regenerated correctly.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* [AI] Add release note for the iOS publishing key requirement
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* [AI] Publish the iOS app to App Store Connect from CI
Add a publish-ios workflow that archives and uploads the Capacitor iOS
app on every master push (TestFlight), on published releases, and on
manual dispatch for a tag. It imports the signing identities into a
temporary keychain, authenticates xcodebuild with an App Store Connect
API key via the release:ios script's XCODEBUILD_AUTH_ARGS pass-through,
and writes the uploaded version and build number to the job summary.
Submission for App Store review stays a manual step.
Secrets (release environment): APPLE_TEAM_ID, APPLE_SIGNING_P12_BASE64,
APPLE_SIGNING_P12_PASSWORD, APP_STORE_CONNECT_API_KEY_P8,
APP_STORE_CONNECT_API_KEY_ID, APP_STORE_CONNECT_API_ISSUER_ID.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* [AI] Address review feedback on the iOS publish workflow
Queue pending runs instead of replacing them, pick the dispatch ref from the
workflow selector so it always matches the release environment policy, and
skip cache restore like the other release jobs.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* [AI] Document iOS publish secrets and build before importing certificates
Explain how each App Store Connect secret is regenerated, skip builds for
packages outside the mobile bundle, and run the web build before any signing
material is placed on the runner.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Michael ClarkGitHubautofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* whats new experimental feature
* pointing preview builds at preview docs and fixing some niggles
* notification bell and fixing some bits
* moving the number down a bit
* update release notification
* optional feature flag so users can turn it off if they dont want it
* cleanup
* add discord link to page for more news
* feedback
* feedback
* filter all posts by a tag to ensure only the ones we tag are announcement
* feed should be served from github instead of docusaurus
* remove advertising rules in discord cause they're not app related
* [autofix.ci] apply automated fixes
* release pipeline update so the news is updated in the release pr
* fail instead of skip
* fix edge case where slugs are bad or no date
* remove experimental
* notifications intead of whats new
* adding hr styling
* docs
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #8802
* Add in_app_notification flag to release blog post
* [autofix.ci] apply automated fixes
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* upgrade electron to 43
* [AI] Use noble Playwright image for desktop jobs to compile against Electron 43 headers
Electron 43's V8 headers expand to 'class [[deprecated(...)]] __attribute__((visibility("default")))'
when node-gyp defines USING_V8_SHARED and V8_DEPRECATION_WARNINGS. gcc 11 and 12 (jammy) cannot
parse a GNU attribute after a standard attribute in a class-head; gcc 13 (noble) can. Verified by
compiling the headers with g++-11/12 (fail) and g++-13/14 (pass) in Ubuntu 22.04/24.04 containers.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* glboal setup for playwright due to new download behaviour
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #8769
* upgrading runner
* add exit codes back
* build for arm64
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
The /update-vrt workflow always runs from the default branch, so this
container fix must land there for the desktop shard to build native modules
against Electron 43's V8 headers, which gcc 11/12 (jammy) cannot parse.
Matches the change to the functional-desktop-app job in e2e-test.yml on the
Electron 43 upgrade branch (#8769).
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* Pin bundle comparisons to the base commit
* Organize bundle run resolver files
* Pin resolver checkout to the trusted base
* Resolve bundle baselines from the merge base
* Pair bundle baselines with the PR base
* Strengthen bundle workflow regression coverage
* Delete packages/ci-actions/src/build-runs/size-compare-workflow.test.ts
* [AI] Fix feature-request automation to use the Feature issue type instead of the feature label
GitHub issues migrated feature requests from a 'feature' label to a
'Feature' issue type, which silently broke the auto-close workflow, the
help-wanted cleanup workflow, and the feature-implemented handler.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* note
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* [AI] ci: support parallel e2e shards with per-shard port
- Add 'Set E2E port' step to functional and vrt jobs (E2E_PORT = 3000 + shard)
- Use vars.E2E_SHARD_TOTAL (with fallback '3') for shard denominator in job
names and test commands; pass --var E2E_SHARD_TOTAL=1 to run full suite in
a single local shard without relaunching
- Add .actrc with depot runner image mappings
* [AI] fix(ci): address review feedback on e2e shard guard/injection
* [AI] Enforce append-only migration files in CI
Shipped migrations are append-only: existing installs never re-run
them, so editing one silently forks the database schema across the user
base, and deleting one breaks the migration check for every existing
budget file. The CI migration check now diffs blob hashes against the
merge base to reject edits/deletions, keeps the existing
timestamp-ordering rule, emits advisory PR annotations for migrations
containing DROP/RENAME statements, and fails loudly when git commands
fail instead of passing on empty output.
First of a series that makes clients on different app versions sync
safely against the same budget file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Derive the newest upstream migration id with an explicit max
The ls-tree listing is alphabetical, so taking the last entry only
worked while every migration id has the same digit count.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Post advisory migration warnings as a PR comment
The risky-SQL warnings were only visible as job annotations, and since
the job passes there was no prompt to look at them. The migrations job
now uploads its findings as an artifact, and a new workflow_run workflow
(trusted base-repo context, so it also works for fork PRs whose tokens
are read-only) validates the artifact against a fixed allowlist and
posts/updates a PR comment — removing it again once the warnings are
resolved.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Align overview numbering with the inline check comments
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Adds the knip tool with a monorepo-tuned config (knip.json) and a CI gate
in check.yml, plus the dead-code and dependency cleanup it surfaced. The
unused-export/type/duplicate rules are disabled so exporting an unused
symbol is allowed.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 22:11:48 +00:00
Matt FiddamanGitHubautofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* [AI] api: add browser build
Continuation of #7545 (and #8143, which moved the browser Web Worker
bootstrap into loot-core). This adds the browser-compatible build of
@actual-app/api: the full loot-core stack runs inside a Web Worker and a
thin main-thread facade exposes the same public surface as the Node entry.
loot-core:
- Add platform/client/backend-worker.ts: createBackendWorker(worker)
centralizes absurd-sql's main-thread initBackend + __absurd:* message
filtering, and is exported for the api to reuse.
- Refactor browser-preload's start.ts and worker-bridge.ts to route through
it (drops the duplicated __absurd:* filtering; terminate() now also clears
listeners). Behavior is preserved.
api:
- browser-worker.ts: Web Worker entry owning real loot-core, speaking
loot-core's {id,name,args} backend protocol; wraps fetch to map the
.js -> .js.data migration names.
- index.browser.ts: main-thread facade that spawns the worker.
- browser/rpc.ts: main-thread <-> worker RPC bridge (uses createBackendWorker).
- browser/lib-stub.ts: stubs lib.send so methods.ts routes over postMessage.
- vite.browser.config.mts / vite.browser-worker.config.mts and asset bundling
in vite.config.mts (sql-wasm.wasm + data/ + data-file-index.txt); package.json
build chain, browser export, and absurd-sql/npm-run-all/vite-plugin-node-polyfills deps.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] Rename release note to match PR number 8166
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] api: move browser worker plumbing into loot-core
Address review feedback: the browser worker logic shouldn't live in the api
package since it's generic "loot-core as a browser npm package" plumbing, not
api-specific. Resolve it via loot-core's existing conditional-export system
instead of a vite alias.
- loot-core: add server/main.api-browser.ts (worker-routing `lib` that
delegates to the existing platform/client/connection), selected via a new
`api-browser` export condition on "./server/main". Move the worker entry to
server/api-browser-worker.ts.
- api: the facade (index.browser.ts) now reuses loot-core's client connection
via a minimal global.Actual.getServerSocket shim and spawns the worker built
from loot-core's entry. Deletes browser-worker.ts, browser/rpc.ts and
browser/lib-stub.ts (~270 lines) in favor of the shared loot-core code.
- The facade build selects the impl with resolve.conditions: ['api-browser']
instead of resolve.alias, removing the enforce-boundaries lint exception.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] api: simplify browser build cleanups
Post-review cleanups (no behavior change):
- backend-worker.ts: fix stale doc comment referencing the removed
packages/api/browser/rpc.ts (the consumer is now index.browser.ts).
- api-browser-worker.ts: drop the redundant `endsWith('/data-file-index.txt')`
disjunct (subsumed by `endsWith('data-file-index.txt')`) and the no-op
`input as RequestInfo | URL` re-casts on the fetch pass-throughs.
- index.browser.ts: replace the single-field `state` holder with a plain
module-level `let backend`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] api: drop the createBackendWorker wrapper, revert browser-preload churn
Now that the facade rides on loot-core's platform/client/connection (which
already ignores absurd-sql's `__`-prefixed internal messages), the only thing
the main thread still needs is absurd's one-line initBackend. So:
- Replace the 60-line createBackendWorker wrapper (onMessage/postMessage/
terminate/listener filtering) with a tiny initBrowserBackend(worker) helper.
- Revert browser-preload/start.ts and worker-bridge.ts to their merged state —
they keep importing absurd's initBackend directly, so this PR no longer
refactors just-merged files and the loot-core change is purely additive.
- Facade holds a plain Worker handle and calls worker.terminate() on shutdown.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] api: trim verbose comments in the browser build
Keep only the load-bearing "why" notes (the absurd-sql init, the fetch/.js.data
workaround, the global.Actual shim, the api-browser condition); drop protocol
diagrams, usage examples, and restated context. No code/behavior change.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] api: drop redundant absurd-sql dependency
No api source imports absurd-sql; it's reached only through @actual-app/core
(the facade's initBrowserBackend and the bundled worker), which declares it.
It's bundled into the build output, so it isn't a runtime dependency of the
published package either. Bundles are byte-for-byte unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] api: drop the api-browser condition, inject the worker into the connection
Review feedback: the api-browser export condition fought loot-core's idiom
(browser IS the default platform; node/"api" is the override) and hid a bug —
the condition-swapped lib only had `send`, so api.utils.amountToInteger was
silently undefined in the browser build.
Replace the condition with a plain transport seam:
- methods.ts no longer imports server/main; it sends through api/send.ts,
which the Node entry wires to in-process lib.send and the browser entry
wires to loot-core's client connection. utils.ts re-exports
amountToInteger/integerToAmount from shared/util directly (fixes the bug).
- loot-core's client connection init() now accepts an optional injected
socket; connectBackendWorker(worker) installs absurd-sql's bridge and
connects in one call. This removes the forged global.Actual shim and the
facade's `define: { global: 'globalThis' }` workaround. Desktop's argless
init() path is unchanged.
- Delete main.api-browser.ts, the "./server/main" conditional export, and
the facade's resolve.conditions.
The 4 loot-core snapshot failures (main.test.ts / transfer.test.ts) are
pre-existing on the branch without these changes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] api: route methods through the client connection, slim the facade
Review feedback: get rid of the _setSend seam and move the worker init logic
into loot-core.
- methods.ts now imports `send` from loot-core's client connection. The node
build resolves it via the existing `api` condition to a new in-process
implementation (platform/client/connection/index.api.ts — previously a dead
re-export of the electron client), matching the platform idiom: browser is
the default, node/"api" overrides. api/send.ts is deleted and the node
entry (index.ts) reverts to master byte-for-byte.
- loot-core's startBackendWorker(worker, config, assetsBaseUrl) now owns the
whole worker boot (absurd-sql bridge + connection.init + server init RPC),
so the browser entry just spawns the worker and calls it.
- Trims: single chained build script (drops the npm-run-all dep), copyFileSync
instead of the linkOrCopy helper, drop the worker entry's error listeners
(browsers already log worker uncaughts to DevTools).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] api: trim prose comments to the essential ones
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] fix client connection stalling when no sends are queued at connect
Found while smoke-testing the browser api build in a real consumer app: the
client connection only nulled messageQueue (switching from queueing to direct
postMessage) when the queue was non-empty at 'connect'. The desktop app always
has queued sends by then, so it never hits this; the api facade connects
before sending anything, so every later send queued forever and init() hung.
Drop the queue on connect unconditionally.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] fix client connection dropping api/* error replies
Found via the browser smoke test: opening an e2e-encrypted budget without the
key surfaced as "undefined is not an object" instead of an error. The server
connection forwards api/* handler failures as {type:'reply', id, error}, but
the web client connection only read `result`, silently resolving undefined for
every failed api/* call. Reject when the reply carries an error, matching the
server's envelope (and the old api rpc behavior). The electron client has the
same latent gap; left untouched here.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] api: move the worker entry back into the api package
Review feedback: browser-worker.ts is the api package's build entry, not
generic loot-core code — move it back (it now imports loot-core through the
public @actual-app/core exports instead of #-subpaths).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] api: drop the manifest rewrite, align shutdown, trim comments
The data-file-index.txt manifest now lists migrations under their real .js
names (the worker's fetch shim already redirects those to the .js.data files
on disk), so the manifest-rewriting half of the shim is gone. The worker init
payload carries config and assetsBaseUrl as separate fields instead of
smuggling a private key into the config object, browser shutdown() mirrors
the node facade, and the client connection's queue flush drops a redundant
branch.
* [AI] fix rejected handler promises poisoning close-budget
runHandler only removed a method's promise from runningMethods when it
fulfilled, so any handler rejection left a stale promise in the set. The next
close-budget then failed: flushRunningMethods' Promise.all rejected with that
old, unrelated error before closeBudget even ran. Remove settled promises on
rejection too, and flush with Promise.allSettled since rejected methods
already reported their error to their caller.
* [AI] api: add a browser e2e test
A Playwright test loads the built browser bundle in chromium from a static
COOP/COEP server and exercises the full stack: worker boot, the rejected-error
contract, budget import, transaction read-back, and IndexedDB persistence
across a page reload. A dedicated workflow runs it in CI on api/loot-core
changes.
* [AI] api: drop the worker fetch shim; strip .data names in loot-core fs
The .js.data scheme was spread across three coordinated pieces: the build
renamed migrations on disk, the manifest listed names that didn't exist, and
a global fetch monkey-patch in the worker un-lied at runtime. Now the
manifest lists the true on-disk names and populateDefaultFilesystem (the only
fetcher of these files) strips the .data suffix when naming the virtual file
— the fetch patch is gone and the suffix becomes a small documented fs
convention. Also: e2e static server uses a single stat and drops a dead MIME
entry.
* [AI] fix electron client connection dropping api/* error replies
Both server connection variants post api/* handler failures as
{type: 'reply', id, error}, but only the web client rejected on it
(778ed25cf); the electron renderer client still resolved undefined. Mirror
the check so the wire contract is implemented uniformly.
* [AI] api: exclude the playwright e2e from vitest; review polish
vitest's default include matched e2e/browser.test.ts and failed CI - a
playwright test file defines no vitest tests. Exclude e2e/ from the unit-test
run (it has its own yarn e2e script). Also from review: the browser exports
condition now carries its own declaration file (the browser init's return
type differs from the node facade), and a failed init terminates the worker
it just spawned before rethrowing instead of leaving it running.
* [AI] api: trim code comments to the essentials
* [AI] api: always terminate the worker when browser shutdown fails
Review feedback: a rejected close-budget left the worker running. Terminate
in a finally block so cleanup is guaranteed while the failure still reaches
the caller.
* [AI] docs: document experimental browser support in the api package
* [AI] docs: drop the CORS note from the api browser section
* [AI] docs: trim the api browser section to the basics
* [AI] api: drop the import comment in methods.ts
* [AI] Run API browser test on depot runner
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* [AI] Align api vite-plugin-node-polyfills to 0.28.0
The api workspace was pinned to ^0.27.0 (left over from an earlier merge
conflict resolution) while loot-core uses ^0.28.0. This both tripped the
workspace version-consistency constraint and broke the browser worker build:
under vite 8.0.16 the 0.27 process shim no longer round-trips runtime writes
to process.env.PUBLIC_URL, so sql-wasm.wasm was fetched from
/dist/undefinedsql-wasm.wasm (404) and api.init() failed in the browser e2e.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 06:32:26 +00:00
Matt FiddamanGitHubcoderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* [AI] Migrate remaining workflows to depot action runners
Switch all remaining GitHub-hosted runners over to their depot
equivalents:
- ubuntu-latest -> depot-ubuntu-latest in the VRT-related jobs
(e2e-test vrt/merge-vrt, e2e-vrt-comment, vrt-update-generate,
vrt-update-apply)
- windows-2022/windows-latest -> depot-windows-2022 in the electron
build matrices (electron-pr, electron-master, publish-nightly-electron)
and publish-microsoft-store
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013dQEH47R5kTkPCvhC2cpoB
* [AI] Add release note for depot runner migration
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013dQEH47R5kTkPCvhC2cpoB
---------
Co-authored-by: Claude <noreply@anthropic.com>
* [AI] Replace archived check-spelling action with typos for docs spell-check
The check-spelling/check-spelling action was archived upstream and shipped a
self-disabling "secpoll" kill-switch after a maintainer-account compromise
(2026-06-16), causing the Check Spelling (Docs) workflow to fail fatally with
a security-advisory error. There is no patched release to bump to.
Replace it with crate-ci/typos, which is actively maintained and runs entirely
from the checked-out tree (no PR-comment or bot-apply machinery, so the workflow
only needs contents: read):
- Rewrite .github/workflows/docs-spelling.yml to run crate-ci/typos, dropping
the check-spelling comment/apply jobs and the pull_request_target trigger.
- Replace the check-spelling config files with typos.toml: scope to
packages/docs, exclude auto-generated release notes and binary assets, and
allowlist words typos otherwise mis-flags (HSA, Lage/lage, BA).
- Fix genuine typos surfaced in current docs (schedules.md, paying-in-full.md).
- Update the contributing guide and docs-writing skill to describe the new
allowlist location.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DstzjPjGYdWMCG4jsrH6a1
* [AI] Add docs-spelling release note and format README
Fix the remaining CI checks on the spell-check migration:
- Add upcoming-release-notes/8249.md (Maintenance) so the "Release notes"
check passes.
- Reformat .github/actions/docs-spelling/README.md with oxfmt so the lint
("Test") and autofix.ci checks pass (autofix.ci is not permitted to modify
files under .github, so the formatting has to be committed directly).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DstzjPjGYdWMCG4jsrH6a1
* [AI] Disable credential persistence in docs-spelling checkout
Address the code-scanning (zizmor) and CodeRabbit review finding: the
read-only spell-check job performs no authenticated git operations, so set
persist-credentials: false on actions/checkout as a hardening measure.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DstzjPjGYdWMCG4jsrH6a1
---------
Co-authored-by: Claude <noreply@anthropic.com>
* [AI] Migrate CI workflows to Depot-managed runners
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Rename release notes to match PR number
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Empty commit to trigger CI
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Keep VRT jobs on GitHub-hosted runners
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Use 4-vCPU Depot Windows runners for Electron builds
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Use 4-vCPU Depot Ubuntu runners for Electron builds
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Use 4-vCPU Depot runners for functional e2e tests
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Scale Electron build runners to 8 vCPUs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Scale Ubuntu Electron builds to 4 vCPUs and move Windows builds back to GitHub runners
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Move Microsoft Store publish back to GitHub Windows runner
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Add actionlint config for Depot runner labels
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* fix desktop app workflow for windows builds
* release notes
* append variable to github env so its available in other steps
* pin to 2022
* release notes
* [AI] Drop ACTIONS_UPDATE_TOKEN from release workflows
Replace the implicit push-triggers-workflow link (which relied on the ACTIONS_UPDATE_TOKEN PAT) with an explicit workflow_run chain from "Cut release branch" to "Release notes", falling back to the built-in GITHUB_TOKEN. The PAT stays in vrt-update-apply.yml, which genuinely needs it to push to contributor forks and re-trigger their PR CI.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] Add release note for ACTIONS_UPDATE_TOKEN removal
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Update 8142.md
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [AI] Surface anti-slop and self-review expectations at PR time
Drive-by, LLM-generated PRs (often many at once from one author) burn
maintainer review time. The repo's AI usage policy already covers this,
but contributors never see it in the PR flow.
- Strengthen the fork-PR welcome comment to ask for a human self-review
confirmation, a plain-language testing note, and AI disclosure, plus a
note discouraging opening many PRs at once.
- Add a "Quality Over Quantity" section to the AI usage policy naming the
volume pattern and its consequences.
- Add an AI-disclosure prompt and tighten the self-review item in the PR
template.
No mechanical CI gates on PR body content: those are trivially satisfied
by the same tools that generate the slop, so the change relies on human
accountability and a linkable policy instead.
* [AI] Point welcome comment at the PR template instead of inline asks
Replace the three "reply on this PR with" bullets with a single checklist
item asking contributors to use the PR template and fill in its checkboxes,
keeping the welcome comment short.
* [AI] Add AI disclosure checklist item to fork PR welcome comment
---------
Co-authored-by: Claude <noreply@anthropic.com>
* [AI] Run do-not-merge check on merge_group events
The block-do-not-merge workflow only triggered on pull_request events, so
it never ran in the merge queue and could not be made a required check.
Adding the merge_group trigger lets the job run and pass in the queue
context (where pull_request labels are absent), allowing it to be required.
* [AI] Add release notes for merge queue do-not-merge fix
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Remove environment from release notes workflow
Removed the environment specification from the release notes workflow.
* Update release-notes CI job configuration
Removed the unnecessary 'environment' from the release-notes CI job.
* [AI] Add CI job that fails when 'do not merge' label is set
* [AI] Rename do not merge check job to "Block PRs with do not merge label"
* [AI] Rename do not merge workflow to "Block PRs with do not merge label"
* [AI] Add release notes for do not merge CI check
* Update 8090.md
---------
Co-authored-by: Claude <noreply@anthropic.com>
* [AI] Relax release-notes filename convention
Allow descriptive filenames (e.g. add-payee-autocomplete.md) for
upcoming release notes instead of requiring {PR_NUMBER}.md.
The PR number was only used to build the [#1234](.../pull/1234) link in
the generated changelog. The generation script now resolves the PR per
file by finding the commit that added it (git log --diff-filter=A
--follow) and querying GitHub's commits/{sha}/pulls endpoint. Numeric
filenames remain valid via a fast path.
Also retires the CodeRabbit/OpenAI-triggered auto-creator workflow,
which existed to guess summaries and stamp the PR-numbered filename;
neither is needed once contributors can pick a slug up front.
* Add release notes for PR #7963
* [AI] Use execFile to look up release-note add-commits
resolvePrNumber() interpolated a path from fs.readdir into a shell-
evaluated `git log` command. Switch to execFile with an argv array so
filenames containing shell metacharacters can't break out of the
intended command.
* [AI] Drop duplicate release note added by the to-be-removed auto-creator
The CodeRabbit-triggered workflow ran one last time from master before
this PR removes it, and committed upcoming-release-notes/7963.md
duplicating the existing relax-release-notes-filenames.md entry. Keep
the slug-named note since it exercises the new flexible-filename code
introduced in this PR.
* [AI] Don't fail release-notes generation on transient API errors
fetchPrForCommit() handled non-OK HTTP responses but let fetch() and
res.json() exceptions propagate, so a single network blip or malformed
response would abort the whole release-notes generation. Wrap them in a
try/catch that logs and returns null, matching the pattern already used
in resolvePrNumber for execFile errors.
* [AI] Address CodeRabbit full-review nits
- bin/release-note-generator.ts: tighten slug regex to reject trailing
and consecutive dashes (matching slugify output), and make slugify
fall back to "untitled" so an all-non-alphanumeric input can't
produce a hidden ".md" filename.
- packages/ci-actions/bin/release-notes-check.mjs: switch to execFile
for git fetch/diff, matching release-notes-generate.mjs and removing
shell interpolation of BASE_REF.
- packages/ci-actions/bin/release-notes-generate.mjs: explicitly check
GITHUB_REPOSITORY before splitting, consistent with the other env
var guards a few lines below.
- upcoming-release-notes/relax-release-notes-filenames.md: fix author
casing (matiss -> MatissJanis) so changelog attribution is correct.
* [AI] Reject empty release-note bodies
content.trim().split('\n').length === 1 is true for the empty string
(''.split('\n') returns [''] of length 1), so blank notes slipped past
the single-line check. Reject empty trimmed content explicitly.
* [AI] Resolve PR numbers from commit subjects instead of GitHub's API
parseReleaseNotes was doing one GitHub API round-trip per non-numeric
release-note file. That scales badly for release generation, and the
docs site's generate-upcoming-release-notes.mjs runs on every docs
build — so contributors were hitting the GitHub API (or failing 401
without a token) every time they previewed docs locally.
actualbudget squash-merges every PR through the GitHub UI, which
appends "(#NNNN)" to the resulting commit subject. So:
git log -1 --format=%s -- <path>
plus a /\(#(\d+)\)\s*$/ match recovers the PR number without touching
the network, and works offline / without a GITHUB_TOKEN.
Side effect: switched from "first commit that added this file" to
"most recent commit touching this file", which is what we actually
want — when a file is renamed (e.g. 7907.md -> 7954.md when a wrong
PR number is corrected), the changelog should point at the rename PR,
not the original add. The SHA->PR cache and fetchPrForCommit go away;
no longer needed.
If a file's subject doesn't match (direct push to master, manually
rewritten subject), the entry still emits without a PR-link prefix —
same graceful degradation as before.
* [AI] Pin PR-number lookup to each note's add commit
resolvePrNumber was using git log -1 with no diff filter, returning
the latest commit that touched the file. That's fine until someone
edits an existing release note in a follow-up PR (typo fix, author
correction) — at which point the changelog entry would suddenly
point at the wrong PR.
Add --diff-filter=A so the lookup pins to the commit that originally
added the path. Empirically verified against this repo: renames keep
working (git records a rename as A at the new path when --follow
isn't used), and the edit case now correctly returns the original
add commit instead of the most recent touch.
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* [AI] Address zizmor findings on workflows
Replace actions-ecosystem/action-add-labels and action-remove-labels
with `gh` CLI calls (superfluous-actions). Silence the six
dangerous-triggers findings on pull_request_target/workflow_run
workflows with inline `# zizmor: ignore[dangerous-triggers]` and a
short rationale — each workflow already follows GitHub's documented
safe pattern (no PR code checkout, or validated artifacts only).
* [AI] Add release note for zizmor workflow fixes
---------
Co-authored-by: Claude <noreply@anthropic.com>
* split release into two branches
* update docs to match the new process
* note
* zizmor comment
* Update check-spelling metadata
* use single long lived release branch
* coderabbit
* jfdoming suggestions