Workflow Gatekeeping
Every major workflow can be disabled centrally throughtuturuuu.ts.
The reusable workflow
ci-check.yml
reads that config and emits should_run, which downstream jobs use before doing
real work.
For Vercel deployments, ci-check.yml also performs affected-app gating before
any install, build, or deploy step starts. It checks the current GitHub event’s
changed files against Vercel app metadata and workspace dependency closures from
tuturuuu.ts.
The changed-file resolver must evaluate the full effective change range:
- Manual
workflow_dispatchruns bypass affected-app gating when the workflow is enabled. - Vercel production push workflows first look for the latest successful GitHub
Deployment marker for the same workflow and branch, then diff that marker SHA
to the current
GITHUB_SHA. - If no marker is available, push events use the GitHub event payload’s complete commit file list instead of falling back to only the latest commit.
- Pull request events diff the PR base SHA to the PR head SHA.
- If the resolver cannot prove the full range, it leaves changed-file state unavailable so Vercel gating defaults open.
apps/<app>/**runs that app’s preview or production Vercel workflow.packages/<package>/**runs every Vercel app whose transitiveworkspace:*dependency closure includes that package.apps/*/package.jsonandpackages/*/package.jsonare dependency changes for their owning workspaces.bun.lock, rootpackage.json,turbo.json,tuturuuu.ts, and.github/workflows/ci-check.ymlrun every Vercel app workflow.- A Vercel workflow file change, such as
.github/workflows/vercel-preview-calendar.yaml, runs that specific workflow. - If changed files cannot be computed, the Vercel gate defaults open.
bun.lock-only changes intentionally run all Vercel app deploys because ownership
is ambiguous without a manifest or source path.
Pull Request Close Cancellation
cancel-pr-runs-on-close.yaml runs on the pull_request_target closed event
and cancels active GitHub Actions runs that still belong to the closed pull
request. It exists to stop queued or long-running checks after a PR is closed
without adding closed triggers to every CI workflow.
Because pull_request_target runs with base-repository privileges, keep this
workflow narrow:
- Do not checkout or execute pull request head code.
- Checkout only the trusted default branch, with persisted credentials disabled.
- Pin GitHub-owned actions to full commit SHAs.
- Grant only
actions: writeandcontents: readto the cancellation job. - Do not pass repository secrets other than the short-lived
GITHUB_TOKEN.
main or production push runs. Runs in contributor forks are
outside the base repository token’s authority and are not cancelled by this
workflow. The same trusted job paginates through Actions cache entries and
deletes only entries whose ref equals the closed pull request’s merge ref
(refs/pull/<number>/merge). It never deletes default-branch cache entries.
Main Workflow Groups
Hosted web build and deployment checks
vercel-preview-platform.yamlvercel-preview-apps.yamlvercel-preview-calendar.yamlvercel-preview-chat.yamlvercel-preview-cms.yamlvercel-preview-drive.yamlvercel-preview-finance.yamlvercel-preview-inventory.yamlvercel-preview-infrastructure.yamlvercel-preview-learn.yamlvercel-preview-mail.yamlvercel-preview-meet.yamlvercel-preview-mind.yamlvercel-preview-nova.yamlvercel-preview-qr.yamlvercel-preview-rewise.yamlvercel-preview-shortener.yamlvercel-preview-storefront.yamlvercel-preview-tasks.yamlvercel-preview-teach.yamlvercel-preview-track.yaml- A matching
vercel-production-*.yamlworkflow exists for each app above
.github/workflows/vercel-preview-*.yaml and
.github/workflows/vercel-production-*.yaml as the authoritative source.
CMS uses the same Vercel deployment pattern as the other satellite apps:
- preview workflow:
vercel-preview-cms.yaml - production workflow:
vercel-production-cms.yaml - project secret:
VERCEL_CMS_PROJECT_ID - environments:
vercel-preview-cmsandvercel-production-cms
- preview workflow:
vercel-preview-apps.yaml - production workflow:
vercel-production-apps.yaml - project secret:
VERCEL_APPS_PROJECT_ID - environments:
vercel-preview-appsandvercel-production-apps
- preview workflow:
vercel-preview-qr.yaml - production workflow:
vercel-production-qr.yaml - project secret:
VERCEL_QR_PROJECT_ID - environments:
vercel-preview-qrandvercel-production-qr
- preview workflow:
vercel-preview-infrastructure.yaml - production workflow:
vercel-production-infrastructure.yaml - project secret:
VERCEL_INFRASTRUCTURE_PROJECT_ID - environments:
vercel-preview-infrastructureandvercel-production-infrastructure
- preview workflow:
vercel-preview-mail.yaml - production workflow:
vercel-production-mail.yaml - project secret:
VERCEL_MAIL_PROJECT_ID - environments:
vercel-preview-mailandvercel-production-mail
- run with default
contents: readpermissions - bind deploy jobs to
vercel-preview-<app>orvercel-production-<app>GitHub Environments - run preview workflows only through manual dispatch from
main, with a requiredpreview_refinput and an actor present in theTRUSTED_PREVIEW_DEPLOY_ACTORSrepository variable;vercel-preview-platform.yamlis the exception and also runs on protectedmainpushes so Supabase staging migrations keep their same-SHA prerequisite signal - reject production manual dispatches from non-production branches before install/build/deploy work starts
- install Bun with
.github/actions/setup-bun-with-retry, pinned to the rootpackageManagerBun version and retried with exponential backoff - install dependencies through
scripts/ci/run-with-backoff.shso transient Bun tarball or cache failures retry after cache cleanup - build selected shared workspace dependencies before Vercel resolves package exports:
@tuturuuu/types,@tuturuuu/supabase, and@tuturuuu/internal-api - run
vercel pull - run
vercel build - deploy prebuilt artifacts for satellite apps and the hosted platform production workflow
- treat
vercel-preview-platform.yamlas platform build validation only; self-hosted machines own their own Dockerapps/webruntime deployment - skip production push work when a newer commit already exists on the target branch
- record non-blocking GitHub Deployment markers after successful Vercel preview builds and production deploys so the next production push can evaluate every change since the last successful run
Database automation
supabase-staging.yamlsupabase-production.yaml
.github/actions/setup-supabase-cli-with-retry after checkout. The local action
passes github.token through to supabase/setup-cli@v2, leaves version empty
so the repo-pinned Supabase CLI version is used instead of the anonymous
latest release lookup, and retries failed setup attempts with bounded
exponential backoff.
Docker automation
docker-setup-check.yamlrust-backend.yml
docker-setup-check.yaml is the workflow to watch whenever Docker files,
compose files, or Docker helper scripts change. rust-backend.yml owns the
apps/backend Rust service checks and the migration Cloudflare checks:
formatting, locked dependency fetch, Clippy, tests, Cloudflare Worker target
validation, smoke reporter unit tests, native binary build, Docker image build,
apps/tanstack-web type-check/test validation, and the TanStack route-tree
generator/formatter unit test. Keep scripts/generate-tanstack-route-tree.*
in this workflow’s path filters so route-tree generation changes run before
TanStack/Rust deployment handoff.
TanStack/Rust Cloudflare deployment
rust-backend.yml is also the manually dispatched Cloudflare preview deployment
workflow for the migration pair:
- Rust backend Worker:
apps/backend/wrangler.jsonc, Worker nametuturuuu-backend. - TanStack Start Worker:
apps/tanstack-web/wrangler.jsonc, Worker nametuturuuu-tanstack-web.
rust-backend.yml entry in
tuturuuu.ts. Pull request and push runs are validation-only and use
contents: read; they do not require Cloudflare secrets just to type-check,
test, lint config, build the Rust Worker bundle, or build the backend Docker
image.
Manual dispatch inputs:
deploy_target:none,backend,tanstack-web, orall.deployment_mode:dry-runordeploy. Keep the defaultdry-runfor the first run in a new account or environment.
rust-backend.yml from main for Cloudflare deployments. The deployment
preflight requires the dispatch ref to be refs/heads/main and github.actor
to be listed in the comma-delimited TRUSTED_CLOUDFLARE_DEPLOY_ACTORS
repository variable before it loads CLOUDFLARE_API_TOKEN. Keep that allowlist
limited to maintainers who can approve secret-backed Worker deployments.
Cloudflare deploy credentials must not be exposed to arbitrary branch code;
review or merge deployment changes before dispatching a secret-backed run.
The deploy jobs are bound to the cloudflare-workers-preview GitHub
Environment. Configure these GitHub values there before expecting deployment
jobs to run:
If either value is missing, the workflow emits a
Cloudflare deployment skipped warning, records setup guidance in the job
summary, and skips deploy jobs after CI validation has completed. The warning
names only the missing GitHub Environment keys, not their values. A non-empty
but invalid or under-scoped token normally surfaces as a Worker secret preflight
skip or a Wrangler failure before upload.
Worker runtime secrets live in Cloudflare, not GitHub. After the GitHub
credential preflight passes, a dedicated Worker secret preflight checks the
selected Workers with wrangler secret list.
It reads only secret names, never secret values. If Wrangler cannot list names,
or if any required name is
missing, the workflow emits a warning, writes setup commands to the job summary,
and skips the selected deploy job instead of failing later inside a deploy
step. Missing-secret warnings use the Missing Worker secrets wording and list
only secret names plus bun wrangler secret put ... commands; they never print
or infer secret values.
Bootstrap missing Worker secrets from a trusted local shell with Wrangler:
deploy_target is not all.
The TanStack Worker has a BACKEND service binding to tuturuuu-backend, so a
frontend-only deployment assumes the backend Worker and its secrets already
exist. When deploy_target=all, a skipped backend deployment also keeps the
TanStack deployment skipped, even if the TanStack Worker secrets are present.
deployment_mode=dry-run compiles and runs Wrangler checks without uploading,
but it still uses the same Cloudflare account, token, Worker name, and secret
name preflights as deployment_mode=deploy. Treat a dry-run skip as a setup
gap, not as a deploy failure. deployment_mode=deploy uploads the selected
Worker version only after those preflights pass.
When deploy_target=all and deployment_mode=deploy, the
post-deploy-smoke job runs only after both Worker deploy jobs succeed. It
requires BACKEND_WORKER_ORIGIN, TANSTACK_WEB_WORKER_ORIGIN, and
CLOUDFLARE_SMOKE_BACKEND_INTERNAL_TOKEN; missing values fail the full deploy
workflow with a warning, an error, and setup guidance in the step summary
instead of silently skipping runtime verification. The warning title is
Cloudflare smoke inputs missing, and the error title is
Cloudflare smoke verification blocked. The job runs:
tmp/benchmarks/web-migration/<run-id>-<attempt>/cloudflare-smoke.json,
uploaded as the cloudflare-smoke-<run-id>-<attempt> workflow artifact, and
summarized in the GitHub step summary. The report must come from the deployed
backend and TanStack Worker origins; do not point these variables at local
Wrangler or Docker origins in the cloudflare-workers-preview Environment.
Quality and security
type-check.yamlturbo-unit-tests.yamlbiome-check.yamlcodeql.ymlcodecov.yamli18n-check.yamlcheck-migrations.ymlcheck-migration-timestamps.ymlbranch-name-check.yaml
turbo-unit-tests.yaml and codecov.yaml) run bun setup
through scripts/ci/run-with-backoff.sh before executing tests so dependency
installation and workspace package builds match the local setup path while
surviving transient tarball extraction failures. The Codecov coverage test run
also uses the helper with a two-attempt cap so transient runner interruptions
such as exit code 130 retry once without masking deterministic test failures.
Vercel workflows should invoke Turborepo through bun turbo:local ... after the
retried bun install so CI uses the pinned repo dependency instead of resolving
a global or downloaded Turbo binary. Cacheable builds, type checks, and tests
must be executed through .github/actions/run-with-turbo-remote-cache; trusted
jobs pass the dedicated repository TURBO_TOKEN and TURBO_TEAM variable,
while pull-request and Dependabot jobs leave both inputs empty and use the
task-family local fallback cache.
Vercel deploy credentials must stay environment-scoped. Do not put
${{ secrets.* }} values in a Vercel workflow-level env: block, and do not
export production Supabase, encryption, or provider secrets from GitHub
Actions. Store app runtime and build-time configuration in the Vercel project
environment. Remote-cache identity is the narrow exception: it is passed only
to the wrapped vercel build step and never written to GITHUB_ENV or a
workflow/job environment. The regression test
bun test scripts/ci/release-workflows.test.js enforces this for every
vercel-preview-*.yaml and vercel-production-*.yaml workflow.
Cache and artifact resources
actions-storage-report.yaml runs weekly and can be dispatched manually. It
is read-only: it queries the repository’s live Actions cache policy and current
cache/artifact inventories, groups cache bytes by key prefix, and summarizes
artifact count, size, age, and largest workflow families. Cache status is
informational at 80% of the configured limit, warning at 90%, and critical at
100%. The report does not assume a fixed artifact byte entitlement and does not
require an organization billing token.
The July 10, 2026 audit found a 10 GB cache maximum and 7-day retention. Target
steady-state usage below 9 GB so GitHub does not continuously evict and recreate
high-reuse entries. Prefer Bun downloads, package-manager data, task-family
Turbo state, native dependencies, shared Rust state, and service-scoped
BuildKit layers over final application binaries. Leave managed uv and CodeQL
caching to their official actions.
All upload-artifact steps must set retention-days and
if-no-files-found. Optional failure diagnostics may warn; release and deploy
handoffs must fail when absent. E2E diagnostics are failure-only and retained 7
days, package tarballs are retained 1 day, development mobile deliverables 7
days, and production store deliverables 14 days.
Preview deploy credentials must not be exposed to arbitrary branch push code.
Most preview Vercel workflows are manual-only: run the workflow from main,
provide the branch, tag, or SHA in preview_ref, and keep
TRUSTED_PREVIEW_DEPLOY_ACTORS limited to maintainers who can approve
secret-backed preview builds. The workflow still checks out and builds the
requested preview_ref, so reviewers should treat that ref as code that can
execute during install/build.
Cloudflare Worker manual deployments follow the same trust boundary: run
rust-backend.yml from main, keep TRUSTED_CLOUDFLARE_DEPLOY_ACTORS limited
to trusted maintainers, and avoid exposing CLOUDFLARE_API_TOKEN to unreviewed
branch code. The workflow checks the protected dispatch ref and actor allowlist
before loading Cloudflare credentials or running Worker deploy steps.
vercel-preview-platform.yaml also runs on protected main pushes. Keep that
exception narrow: supabase-staging.yaml is triggered by the platform preview
build workflow and production migration requires a successful main staging
migration for the same SHA before it can run supabase db push --include-all.
Other delivery surfaces
discord-modal-deploy.ymlmobile-build-android.yamlmobile-build-ios.yamlmobile-build-macos.yamlmobile-build-windows.yamlmobile-deploy-stores.yamlrelease-*.yamlpackage publishing workflows
Operational Rules
Manual dispatch
Useworkflow_dispatch when:
- you need to rerun a deployment intentionally
- you need to promote a migration outside the normal trigger timing
- you need to recover from a failed but otherwise understood automation path
tuturuuu.ts. Disabled ci entries still skip, even for manual dispatch.
For preview Vercel deployments, dispatch the workflow from main, set
preview_ref to the branch, tag, or SHA to deploy, and confirm the actor is in
TRUSTED_PREVIEW_DEPLOY_ACTORS. Do not reintroduce preview push triggers for
secret-backed Vercel workflows.
Package release workflows that expose production secrets or trusted publishing
authority must add their own ref guard before dependency installation or publish
jobs. Release Please is the only workflow that generates monorepo version and
changelog PRs. It runs from production, uses
secrets.RELEASE_PLEASE_TOKEN so generated PRs and releases can trigger
downstream workflows, and falls back to github.token only to keep the job from
failing when the bot token is not provisioned. The github.token fallback does
not trigger downstream workflow runs from generated release PRs. Release Please
rejects non-production manual dispatches before the write-capable release job.
Package publish workflows consume release-please version bumps on production;
they must not recreate checksum or PR-title version bump automation. Package
release workflows use npm trusted publishing: build and artifact-pack work runs
before any OIDC permission is granted, then the publish-npm job downloads one
tarball, verifies its package name and version, and runs npm publish without
NPM_TOKEN. Each publish job is bound to its package release environment, and
the matching npm trusted publisher must use this repository, the workflow
filename, and that environment. Manual dispatch is only valid with the branch
selector set to production; non-production refs are rejected before the package
or publish jobs can start. Every workflow-published package manifest must also
declare repository.type: "git",
repository.url: "https://github.com/tutur3u/platform", and
repository.directory matching the package path. npm validates those fields
against GitHub Actions provenance and rejects publishes with E422 when the
packed manifest has an empty or mismatched repository URL. The tarball handoff
uses required-file behavior, one-day retention, and compression level 0 because
.tgz is already compressed. Preparation runs any package lifecycle build
through root Turbo first, then calls npm pack --ignore-scripts so prepack
cannot bypass the shared cache wrapper.
Release Please can move an oversized generated pull request body into
release-notes.md on a companion
release-please--branches--<branch>--release-notes branch. The workflow runs
node scripts/ci/release-please-overflow-recovery.js --target-branch production
before googleapis/release-please-action@v5; when a merged pending release PR
still points at a missing overflow file, the script recreates the branch and
file from the merged manifest bump and current production changelogs, then the
normal Release Please action can create the releases. If the script reports
skipped, inspect the pending labels and merged release PR body before retrying.
Keep internal Tuturuuu dependencies as workspace:* in source package
manifests so local builds always use the checked-out workspace. Package release
workflows must first run
node scripts/ci/package-release-readiness.js gate-package-release packages/<name>
in a short pre-build gate. The gate checks the package version and publishable
Tuturuuu workspace dependencies once, dispatches missing dependency workflows,
and exits green without build, pack, or publish work while dependencies are
pending. If a dependency workflow for the same production SHA already failed,
completed successfully without npm visibility, or cannot be inspected, the gate
fails immediately. When the gate outputs should_publish == true and
dependencies_ready == true, the workflow can build and rewrite the checked-out
manifest immediately before npm pack with
node scripts/ci/prepare-npm-package-manifest.js packages/<name>. That
temporary rewrite replaces workspace: protocol ranges with the current
workspace package versions so npm consumers can install the tarball. It must
preserve package-included file: tarball dependencies, such as @tuturuuu/ui’s
vendored SheetJS tarball, instead of rewriting them to mutable external tarball
URLs. After
npm publish, the publish job polls npm view for the exact published version
before it reports success, then a separate non-OIDC job dispatches direct
dependent package workflows without checking out the repo or carrying publish
authority. The internal
node scripts/ci/package-release-readiness.js dispatch-dependent-workflows packages/<name>
command is available for direct/manual dispatches that can read the checkout.
If npm returns first-publish or permission errors, fix the npm package access and
trusted publisher setup instead of skipping the package. If a published package
depends on another release-please-managed Tuturuuu package, that dependency also
needs its own
release-*-package.yaml workflow and matching tuturuuu.ts entry.
The platform production Vercel workflow also runs
node scripts/ci/package-release-readiness.js gate-changed-package-versions
before installing dependencies. Release-please package bumps therefore publish
and become visible on npm before the normal production platform deployment
continues. The helper intentionally checks only the checked-out latest commit,
not the whole push event payload, so package changes from earlier commits in a
multi-commit push are not bound to an unrelated newer SHA. If the latest commit
does change package manifests, the deploy job grants actions: write because
the helper may dispatch missing package release workflows for that same
production SHA. When related package releases are queued or running, the helper
sets packages_ready=false; the platform build skips successfully instead of
polling npm until the runner times out. npm publish authority remains isolated to
package publish-npm jobs. A skipped package gate must not count as production
deployment for database migrations: supabase-production.yaml requires the
successful vercel-production-platform deployment marker for the same SHA
before it can run production migrations.
Filtered production Docker installs only include the selected app and the
dependencies that app needs. Workspace packages with direct tsc build scripts
must declare typescript in their own devDependencies; do not
rely on the root devDependency for production Docker builds. Programmatic
compiler API consumers must stay on the active TypeScript 7 toolchain instead
of carrying legacy compiler compatibility packages.
Next.js production apps also declare @typescript/native-preview in their own
devDependencies while the repo uses the TypeScript 7 native compiler package.
The TS7 typescript package does not ship the legacy
typescript/lib/typescript.js API file that Next checks during build-time
TypeScript setup; the native-preview marker makes Next use its supported TS7
native compiler path instead of trying to auto-install classic TypeScript.
Newer-commit guards
Production Vercel push workflows intentionally skip if the branch already has a newer commit than the current run. A skipped deployment may be correct rather than broken. The deployment marker closes the gap created by these stale-run skips. When a later push reaches the latest commit, affected-app gating compares against the last successful marker rather than only the newest push payload, so app changes from skipped intermediate runs still queue the correct Vercel workflow.Prerequisite guards
supabase-staging.yamlrequires a successfulmainplatform preview build trigger unless manually dispatched.- Its deploy step links the staging project and runs
supabase db push --include-all. supabase-production.yamlruns after production platform deployment and also re-evaluates after a matchingmainstaging migration succeeds. It still checks both the latest production platform workflow result, a successful production deployment marker, and a completed successful staging migration for the same commit before runningsupabase db push --include-all.
Mobile iOS native assets
Mobile workflows cache the Flutter SDK/pub downloads through the Flutter setup action. Android workflows also use the toolchain-aware Gradle cache, and iOS or macOS workflows cache CocoaPods downloads plus the trunk repository. They do not cacheapps/mobile/build, final APK/AAB/IPA/app bundles, Pods, or
apps/mobile/.dart_tool. Flutter native asset hook outputs can become stale
across simulator/device builds and SDK updates; a stale .dart_tool cache can
leave NativeAssetsManifest.json referencing objective_c while
build/native_assets/ios/ is missing the generated framework.
Every workflow still runs flutter pub get and its platform build on every run.
Development deliverables are retained for 7 days and production store
deliverables for 14 days. Archive directory-based app bundles before upload,
disable redundant artifact compression for already-compressed archives and
mobile packages, and fail if a required deliverable is missing.
The workflow explicitly runs flutter config --no-enable-swift-package-manager
after Flutter setup. Keep the iOS CI path on CocoaPods while image_cropper and
dkimagepickercontroller resolve incompatible TOCropViewController Swift
package ranges; otherwise Flutter 3.44+ can fail before the simulator build
with an Xcode package dependency resolution error.
Root bun check runs scripts/check-mobile-dependencies.js to catch mobile
dependency versions known to fail Apple CI before the native build starts. While
the iOS/macOS build workflows use Xcode 16.4, keep connectivity_plus pinned to
7.0.0 because 7.1.1 references NWPath.isUltraConstrained, and keep
device_info_plus pinned to 12.3.0 because 12.4.0 references
NSProcessInfo.isiOSAppOnVision; those symbols are not available in that CI SDK.
Mobile store beta deployment
mobile-deploy-stores.yaml runs automatically on production pushes that touch
apps/mobile/**, scripts/mobile-deployment/**, the workflow file,
ci-check.yml, or tuturuuu.ts. It is a beta-store workflow only:
- Android builds the production flavor AAB from
apps/mobile/.env.githuband publishes it to the Google Playinternaltrack. - iOS builds the production flavor IPA from
apps/mobile/.env.githuband uploads it to TestFlight. - CI requests a signed GitHub OIDC token for the
tuturuuu-mobile-deploymentaudience, then fetches an Android or iOS bundle fromhttps://tuturuuu.com/api/v1/mobile-deployment/bundlewith the issuedMOBILE_DEPLOYMENT_CI_TOKEN. - If
MOBILE_DEPLOYMENT_CI_TOKENis not configured in themobile-store-betaGitHub Environment yet, the credentials preflight emits a notice and skips the Android and iOS publish jobs instead of failing the workflow. A non-empty but invalid token still fails during the bundle fetch. - The apps/web mobile deployment vault verifies the CI token, GitHub OIDC
issuer, audience, repository,
productionref, workflow file, andmobile-store-betaenvironment before returning any plaintext. - CI hydrates ignored Firebase, signing, store, and
.env.githubfiles into fixed paths underapps/mobileand$RUNNER_TEMPwithumask 077, validates plaintext SHA-256 hashes, masks secret values, and deletes generated files inalways()cleanup steps. - The workflow rejects any Google Play track other than
internal, uploads only the AAB/IPA build artifacts, and uses TestFlight-only iOS upload. - Release Please owns mobile version and build-number bumps. Duplicate store build numbers should fail in CI instead of being bumped by this workflow.
mobile-store-beta GitHub Environment. Keep that
environment restricted to the production branch and store only
MOBILE_DEPLOYMENT_CI_TOKEN there. Mobile signing, Firebase, store API, and
build-time secrets live in the root workspace mobile deployment vault at
/internal/mobile-deployment on the infra app and require
manage_mobile_deployment_vault. Manage non-file values in the vault’s
Secrets panel, then use the vault’s Verify action before activating the draft. Legacy
base64 file payload env keys are intentionally blocked; Firebase, signing, and
store credential payloads must be uploaded as file resources.
Local release-build verification should run before relying on the workflow:
xcodebuild -version reports that Command Line Tools are selected, switch to
full Xcode before claiming the iOS archive has been verified locally.
Fast Triage Checklist
- Check whether
ci-check.ymldisabled the workflow throughtuturuuu.ts. - For Vercel workflows, inspect the
ci-check.ymldecision reason and matched paths. - Inspect the changed-file source, base SHA, head SHA, and path count emitted by
resolve-changed-files.ts. - Check whether the workflow was skipped because a newer commit exists.
- Check whether the prior successful GitHub Deployment marker exists for that Vercel workflow and branch.
- Check path filters to confirm GitHub should have started the lightweight workflow.
- For database workflows, inspect the prerequisite evaluation job before the deploy job.
- For Docker changes, verify
docker-setup-check.yamlspecifically.
When You Add New Automation
- Add the workflow file under
.github/workflows/. - Add its key to
tuturuuu.tsunless you intentionally want it always on by default. - Document the workflow in
apps/docs. - If it changes a docs-visible page, add that page to
apps/docs/docs.json.