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.
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
Create a new Publication.
Enter the tag for this ring, for example ring-pilot. The Publication will serve any Build carrying that tag.
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.
In Access control, add the User Groups or Audiences allowed into this ring. See Choosing who gets each ring below.
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 |
|---|---|
| User Group — QA team, early adopters |
| Audience — a department such as IT or Support |
| 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
Go to Builds in your App and select the Build you want to promote.
Edit its Tags and add the tag for the next ring.
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.
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.
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.