CI/CD

Xcode build phase

Pull the latest text on every build, from a script phase that runs before Compile Sources.

What you get

The latest text in every build, without anyone remembering.

  • Scriptable from the CLI

    Push, pull and sync from a terminal, a build phase or a coding agent's shell, with a token in the environment.

    The CLI
  • Runs in CI

    Push the source language on merge and pull every language before the release build, on any CI that can run a shell.

    CI pipelines
  • Updates over the air

    Publish the verified strings and let the running app fetch them, so a fixed translation reaches users without a store release.

    Over-the-air delivery
  • AI drafts, a person verifies

    Every language is drafted against your glossary and each key's length limit. A draft never ships until someone has verified it.

Set it up

From nothing to every language.

  1. Step 1: Vendor the CLI

    Commit the script so the version is pinned with the project. Keep anylocale in the file name; that name is what selects the product.

    shell
    curl -fsSL https://anylocale.com/anylocale.sh -o Scripts/anylocale
    chmod +x Scripts/anylocale
  2. Step 2: Add a Run Script phase

    Above Compile Sources, with the token read from the environment rather than a stored login, which the build user may not have. List the written files under Output Files so Xcode does not rerun the phase on every incremental build.

    One pull replaces the catalog in place.

    Run Script
    # Pull the latest text before compiling
    export ANYLOCALE_TOKEN="${ANYLOCALE_TOKEN:?set in the scheme or CI}"
    "$SRCROOT/Scripts/anylocale" pull --project my-app --locale en \
        --format xcstrings --platform ios --out "$SRCROOT/Localizable.xcstrings"
  3. Step 3: Give the scheme the token

    Locally through the scheme's environment variables, in CI through a secret. The token needs the read scope only.

Good to know

  • Files land in place only when they arrived complete, so an interrupted build never leaves a half-written .strings file.
  • The phase exits non-zero when a locale failed to download, which fails the build rather than shipping stale text unnoticed.

Questions

Can an interrupted build leave a half-written file?
No. Each file lands in place only when it arrived complete, so a build cancelled mid-download keeps the previous .strings file.
Which scope does the token need?
read only. Keep the token in the scheme's environment locally and in a secret in CI; the phase never needs push or manage.
Why vendor the script instead of installing the CLI?
So the version is pinned with the project and every machine that builds it runs the same one, including a CI runner with no Homebrew.
Do I get unverified text when I pull?
Yes. A pull carries the current text of every key, verified or not, so a build always has something to show. Only over-the-air delivery is limited to verified strings.

Start with the file your app already ships.

After checkout, import one strings file and read the first drafts within minutes.

Nothing to connect and nothing to install. The CLI is optional.