You are here: Home > App Distribution > Distribute > Progressive Deployment with Tags

Rolling out Builds gradually with deployment rings

Release Builds gradually to your organization using deployment rings — map each ring to a Publication filtered by tags and promote a single Build from pilot to production.

8 min read

TL;DR

Create one Publication per ring with Build selection set to Tags, assign each ring its own Groups or Audiences, then promote a release by adding the next ring's tag to the same Build.

Releasing a new version to everyone at once means that if something is wrong, everyone finds out at the same time. Progressive deployment — also called a staged or ring-based rollout — avoids that by releasing to a small group first and widening the audience only once the version has proven itself.

Applivery has no dedicated "rings" feature. You build them out of two things you already have: tags on Builds and Publications that select Builds by tag. The whole model fits in one sentence:

A ring is a Publication that serves Builds carrying a specific tag. Promoting a release means adding the next ring's tag to the same Build.

How rings map to Applivery

A typical setup uses three rings, though you can use as many as you need:

Ring

Who it reaches

Purpose

Pilot

A handful of people — QA, early adopters

Catch obvious breakage before anyone else sees it

Rollout

One or two departments

Validate against real day-to-day usage

Production

Everyone

General availability

Each ring needs two pieces:

  • A tag that identifies the ring, set on the Publication's Build selection.

  • An access rule — the User Groups or Audiences allowed to reach that Publication.

The Build itself carries no notion of a ring. It just carries tags, and the Publications decide what to do with them.

Tip

When you upload a Build, tags are sent as a comma-separated list, so a comma inside a tag name splits it into two tags. Use hyphens instead: ring-pilot, ring-rollout, ring-production. Pick a convention and stick to it — the tag is what wires everything together.

Create a ring

A ring is an ordinary Publication with Build selection set to Tags. Create one per ring.

From the Dashboard

1
Open your App and go to Published Apps

Create a new Publication.

2
Set Build selection to Tags

Enter the tag for this ring, for example ring-pilot. The Publication will serve any Build carrying that tag.

3
Set Visibility and Security

For internal rings, Active visibility with Private security is the usual combination — people sign in with their Applivery account or your Workspace SSO. Use Unlisted if you would rather share the ring by direct URL only.

4
Restrict access

In Access control, add the User Groups or Audiences allowed into this ring. See Choosing who gets each ring below.

5
Give it a recognizable slug

For example myapp-pilot. The resulting URL is yourworkspace.applivery.com/{slug}.

You end up with one Publication and one URL per ring, each listening for its own tag.

For the full list of Publication settings, see Distribute Apps.

From the API

The key parameter is filter.type set to tag, with filter.value holding the ring's tag. Full reference: POST – Create a Publication.

Integrations API — scoped to a single App, authenticated with an App API Token:

curl 'https://api.applivery.io/v1/integrations/distributions' \
  -X POST \
  -H 'Authorization: Bearer YOUR_APP_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "slug": "myapp-pilot",
    "security": "logged",
    "visibility": "active",
    "filter": {
      "type": "tag",
      "value": "ring-pilot"
    },
    "groups": [["qa-team"]],
    "showHistory": true
  }'

Workspace API — Workspace-level, authenticated with a Service Account token:

curl 'https://api.applivery.io/v1/organizations/ORG_ID/stores/STORE_ID/pubApps' \
  -X POST \
  -H 'Authorization: Bearer YOUR_SERVICE_ACCOUNT_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "slug": "myapp-production",
    "security": "logged",
    "visibility": "active",
    "filter": {
      "type": "tag",
      "value": "ring-production"
    },
    "activateUserAudiences": true,
    "userAudienceMap": [
      { "id": "AUDIENCE_ID", "notifyNewBuildsProcessed": true }
    ]
  }'

security accepts public, password or logged. visibility accepts active, inactive or unlisted.

Choosing who gets each ring

Access to a ring is controlled by the Publication's Access control, using either User Groups or Audiences.

  • User Groups are hand-picked collections of people. Best for a pilot ring, where you want to name the exact testers.

  • Audiences are defined by rules and update on their own as people join or leave. Best for wider rings, where maintaining a manual list would be a chore.

A reasonable starting point:

Ring

Typical access

ring-pilot

User Group — QA team, early adopters

ring-rollout

Audience — a department such as IT or Support

ring-production

Audience — everyone in the Workspace

Via the API, groups supports AND/OR logic: each inner array is an AND clause and each outer element is an OR clause, so [["group1","group2"],["group3"]] means group1 AND group2, OR group3. It only applies when security is logged. For Audiences, set activateUserAudiences to true and list them in userAudienceMap.

Promote a Build through the rings

Promotion does not involve rebuilding or re-uploading anything. It is the same Build gaining tags:

Build #A (v2.0)
  1) tags: ring-pilot                              → visible in pilot only
  2) tags: ring-pilot, ring-rollout                → now also in rollout
  3) tags: ring-pilot, ring-rollout, ring-production → now also in production

From the Dashboard

1
Open the Build

Go to Builds in your App and select the Build you want to promote.

2
Add the next ring's tag

Edit its Tags and add the tag for the next ring.

3
Remove the tag from the previous Build

If an older Build still carries that ring's tag, remove it so the ring serves exactly one Build.

The Build appears in that ring's Publication as soon as you save.

From the API

Use PUT – Update a Build.

Warning

The tags field replaces the entire array. Include every tag the Build should keep — if you send only the new tag, all the others are dropped.

curl 'https://api.applivery.io/v1/integrations/builds/BUILD_ID' \
  -X PUT \
  -H 'Authorization: Bearer YOUR_APP_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "tags": ["ring-pilot", "ring-rollout"]
  }'

The Workspace API equivalent is PUT https://api.applivery.io/v1/organizations/ORG_ID/apps/APP_ID/builds/BUILD_ID with a Service Account token.

Tip

Keep each ring's tag on one Build at a time. When you promote a new Build into a ring, remove the tag from the previous one. That way the version each ring is serving is never ambiguous.

One Build for all rings, or one Build per ring?

Prefer one Build promoted across rings.

Approach

What it means

Recommendation

One Build → several rings

Compile and upload once; the same binary moves forward by gaining tags

Preferred

One Build per ring

Compile and upload a separate Build for each ring

Only for specific cases

The single-Build approach wins for three reasons:

  • You ship what you tested. The exact binary your pilot group validated is the one production receives — no rebuild in between to introduce differences.

  • Version metadata stays consistent. Applivery reads version information from the package itself, so one Build means one set of version values across every ring.

  • Traceability is simple. One release equals one Build equals one history.

Uploading a distinct Build per ring only makes sense when the rings genuinely need different binaries — different build configurations, different endpoints baked in at compile time, and similar. Otherwise, promote by tag.

Setting the initial tag at upload time

You can save yourself a step by tagging a Build into the first ring as you upload it. This is the natural fit for a CI pipeline, which uploads and drops the result straight into pilot:

curl 'https://upload.applivery.io/v1/integrations/builds' \
  -X POST \
  -H 'Authorization: Bearer YOUR_APP_TOKEN' \
  -F '[email protected]' \
  -F 'versionName=v2.0' \
  -F 'tags=ring-pilot' \
  -F 'changelog=Sprint 42 release'

The response includes the Build id, which you will need to re-tag it later. See POST – Upload a Build for the full parameter list.

Checklist

  • One Publication per ring, each with Build selection = Tags.

  • A tag naming convention agreed and written down, with no commas.

  • Access control set per ring — Groups for the pilot, Audiences for the wider rings.

  • CI uploads new Builds already tagged into the first ring.

  • Promotion means adding the next ring's tag to the same Build, and removing it from the previous one.

Key Takeaways

  • One ring equals one Publication whose Build selection is set to Tags.
  • Promoting a Build means adding the next ring's tag — no rebuild required.
  • The `tags` field in the API replaces the whole array, so send every tag you want to keep.
  • Use Groups for small pilot rings and Audiences for wider rings.

A deployment ring is a group of people who receive a new version before the next group does. Instead of releasing to everyone at once, you release to a small pilot group first, then widen the audience as confidence grows.

Create one Publication per ring and set its Build selection to Tags, pointing at that ring's tag. Then use Access control to decide which User Groups or Audiences can reach it.

No. The recommended approach is to upload one Build and promote it by adding the next ring's tag to it. The same binary that passed your pilot is the one that reaches production.

Add the next ring's tag to the Build, either from the Build details in the Dashboard or with the Update a Build endpoint. The Publication for that ring picks it up automatically.

Yes. The `tags` field replaces the entire array, so include every tag you want the Build to keep. Sending only the new tag will drop all the others.

Yes. A Build carrying both `ring-pilot` and `ring-rollout` appears in both Publications. This is normal during a promotion.

Use User Groups for small, hand-picked rings like a pilot. Use Audiences for wider rings, since they update automatically as people join or leave the matching criteria.

No. When you upload a Build, tags are sent as a comma-separated list, so a comma inside a tag splits it into two. Use hyphens instead, as in `ring-pilot`.

Prefer one Build promoted across rings .

Read full answer
Was this page helpful?

Last updated: July 30, 2026