Documentation

Put the version in your build

Give every release a version and build number, pass them into the build, and let Coroid confirm what each environment runs.

People who use your software need to see which version they run. Coroid gives every release a version and a build number, passes both to the pipeline that builds it, and checks afterwards that the environment runs the release you deployed.

1. Coroid names it

Release

1.4.1

Build 12

From Coroid, a file in your repository, or your pipeline.

2. Your pipeline builds it

Your CI/CD

COROID_VERSION=1.4.1

COROID_BUILD_NUMBER=12

COROID_COMMIT_SHA=3da015d…

The values arrive as variables or workflow inputs.

3. People see it

About

Version 1.4.1 (12)

Shown in the app and written to release.json.

4. Coroid confirms it

GET /version.json

Verified

Pipeline reported 1.4.1, build 12

After a deployment, Coroid reads the version URL.

The version travels with the release into your build, and Coroid checks what the environment actually runs.

Everything on this page is set per project in Releases → Release settings → Versioning.

Where the version comes from

Choose one source per project:

  • Coroid assigns it (the default): Coroid suggests the next version when you prepare a release. It raises the last number of the highest version the project has released, so 1.4.0 is followed by 1.4.1. The first release is 0.1.0. Type a different version whenever you need one.
  • Read it from the repository: Coroid reads the version your code declares at the release commit. It looks in VERSION, package.json, app.json (Expo), pubspec.yaml, the Android Gradle file, Cargo.toml, pyproject.toml and the Xcode project, or only in the file you name. If the file still has a version an earlier release used, Coroid asks you to raise it first.
  • My pipeline assigns it: your CI/CD picks the version, for example with semantic-release or from a tag, and reports it with the deployment.

Every release also gets a build number. Build numbers only go up and are never reused within a project, which is what app stores require from iOS CFBundleVersion and Android versionCode.

What the build receives

When Coroid starts a GitHub Actions workflow or a GitLab CI/CD pipeline for a release, it passes these values:

GitLab variableGitHub inputValue
COROID_VERSIONcoroid_versionThe release version
COROID_BUILD_NUMBERcoroid_build_numberThe build number
COROID_RELEASE_NAMEcoroid_release_nameThe release name
COROID_COMMIT_SHAcoroid_commit_shaThe full commit SHA
COROID_ENVIRONMENTcoroid_environmentThe environment key
COROID_RELEASE_IDcoroid_release_idThe Coroid release ID
COROID_ATTEMPT_IDcoroid_attempt_idThe deployment attempt

GitHub rejects inputs a workflow does not declare. Coroid therefore sends coroid_version, coroid_build_number and coroid_release_name only to a workflow that lists them. Declare them as optional:

on:
  workflow_dispatch:
    inputs:
      coroid_release_id: { required: true }
      coroid_attempt_id: { required: true }
      coroid_commit_sha: { required: true }
      coroid_environment: { required: true }
      coroid_version: { required: false }
      coroid_build_number: { required: false }
      coroid_release_name: { required: false }

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      APP_VERSION: ${{ inputs.coroid_version || '0.0.0-dev' }}
      APP_BUILD_NUMBER: ${{ inputs.coroid_build_number || '0' }}
      APP_COMMIT: ${{ inputs.coroid_commit_sha || github.sha }}

GitLab passes the values as variables, so no declaration is needed:

deploy:
  script:
    - export APP_VERSION="${COROID_VERSION:-0.0.0-dev}"
    - export APP_BUILD_NUMBER="${COROID_BUILD_NUMBER:-0}"
    - export APP_COMMIT="${COROID_COMMIT_SHA:-$CI_COMMIT_SHA}"

A pipeline that runs on its own can use its own values. Report the version you deployed, as described below, so the release shows it.

Write a release manifest

The simplest approach that works on every platform is to write one small file during the build and read it wherever the version is shown:

cat > release.json <<EOF
{
  "version": "$APP_VERSION",
  "buildNumber": "$APP_BUILD_NUMBER",
  "commitSha": "$APP_COMMIT",
  "releaseName": "${COROID_RELEASE_NAME:-}",
  "environment": "${COROID_ENVIRONMENT:-local}"
}
EOF

For a web app or a service, serve the file at /version.json. That also gives Coroid a URL to check (see below).

Recipes

Web apps (Next.js, Vite)

Values the browser needs must be set when the bundle is built:

NEXT_PUBLIC_APP_VERSION="$APP_VERSION" NEXT_PUBLIC_APP_COMMIT="$APP_COMMIT" npm run build
VITE_APP_VERSION="$APP_VERSION" npm run build

Show process.env.NEXT_PUBLIC_APP_VERSION or import.meta.env.VITE_APP_VERSION in the footer or an About screen, and copy release.json into the public folder before the build.

Servers and APIs

Read the values at start-up and answer on a version endpoint:

app.get('/version.json', (_request, response) => {
  response.json({
    version: process.env.APP_VERSION,
    buildNumber: process.env.APP_BUILD_NUMBER,
    commitSha: process.env.APP_COMMIT,
  });
});

Docker images

Pass the values as build arguments and label the image, so the running container and the registry both know the version:

ARG APP_VERSION=0.0.0-dev
ARG APP_COMMIT=unknown
ENV APP_VERSION=$APP_VERSION APP_COMMIT=$APP_COMMIT
LABEL org.opencontainers.image.version=$APP_VERSION \
      org.opencontainers.image.revision=$APP_COMMIT
docker build --build-arg APP_VERSION="$APP_VERSION" --build-arg APP_COMMIT="$APP_COMMIT" .

iOS

Xcode reads the version shown in the App Store from MARKETING_VERSION and the build number from CURRENT_PROJECT_VERSION:

xcodebuild -scheme App -configuration Release archive \
  MARKETING_VERSION="$APP_VERSION" \
  CURRENT_PROJECT_VERSION="$APP_BUILD_NUMBER"

With fastlane, use increment_version_number(version_number: ENV["APP_VERSION"]) and increment_build_number(build_number: ENV["APP_BUILD_NUMBER"]).

Android

Read the values in app/build.gradle.kts:

android {
    defaultConfig {
        versionName = System.getenv("APP_VERSION") ?: "0.0.0-dev"
        versionCode = (System.getenv("APP_BUILD_NUMBER") ?: "1").toInt()
    }
}

BuildConfig.VERSION_NAME then shows the version in the app.

Flutter

flutter build appbundle --build-name="$APP_VERSION" --build-number="$APP_BUILD_NUMBER"
flutter build ipa --build-name="$APP_VERSION" --build-number="$APP_BUILD_NUMBER"

Expo and React Native

Read the values in app.config.js:

export default {
  expo: {
    version: process.env.APP_VERSION ?? '0.0.0-dev',
    ios: { buildNumber: process.env.APP_BUILD_NUMBER ?? '1' },
    android: { versionCode: Number(process.env.APP_BUILD_NUMBER ?? 1) },
  },
};

Report the version you deployed

A deployment event can say which version and build it deployed. Add version and buildNumber to the event your pipeline already sends:

{
  "schemaVersion": 1,
  "eventId": "ci:run-812:production:succeeded",
  "providerRunId": "run-812",
  "projectId": "<project-uuid>",
  "environmentKey": "production",
  "repository": "owner/repository",
  "commitSha": "0123456789abcdef0123456789abcdef01234567",
  "status": "succeeded",
  "occurredAt": "2026-09-28T12:00:00Z",
  "version": "1.4.0",
  "buildNumber": "42"
}

If the project's pipeline assigns versions, the release takes the reported version. Otherwise the release page shows the reported version and points out when it differs from the release. For a project hosted on Coroid, set repository to the project ID. Deployment events and CI setup describes the rest of the event.

Check what's running

Give each environment a version URL, such as https://app.example.com/version.json. After a deployment succeeds, Coroid opens the URL and looks for the commit SHA or the version. A reported commit must match the release commit; otherwise the version must match. Coroid keeps checking for ten minutes while the rollout finishes, then shows Verified, Different version or Not reachable under What's running on the release page.

The URL must use HTTPS and a public address. Coroid does not follow redirects and reads at most 64 KB.

Let Coroid set it up

Set up version stamping on the Versioning screen opens New Work with a request written for the project's detected stack. An agent reads the values above at build time, shows the version in the app, writes release.json, declares the workflow inputs and documents it in the README. Review the request, then continue as with any other work.