Repository navigation
Implement ADR 0002: trunk-based automated release process #21597
Description
Context
ADR 0002 defines the target release process for wire-webapp:
mainbecomes the trunk branch.- Every merge to
maindeploys to Edge. - Release branches use
release/YYYY-MM-DD.N. - Release branch updates deploy to Beta.
- Successful Beta deployments create
YYYY-MM-DD.N-beta.Mtags. - Production waits for GitHub Environment approval.
- Production promotes the Beta-tested artifact and does not rebuild from source.
- Successful Production deployments create
YYYY-MM-DD.N-productiontags. - Production tags are immutable release history.
- Rollback is handled by a dedicated GitHub Actions workflow.
- On-premises maintenance releases are handled separately from the normal cloud release flow.
ADR:
docs/decision-records/0002-trunk-based-automated-release-process.md
Goal
Implement ADR 0002 in small, reviewable, low-risk steps.
The final release process should be GitHub-driven, auditable, and safe:
- build once
- deploy to Beta
- validate on Beta
- approve Production through GitHub Environment approval
- promote the same artifact to Production
- create the Production tag only after successful Production deployment
- keep rollback explicit and auditable
Non-goals for the first phase
The first phase should not try to do everything at once.
Out of scope initially:
- Deleting
dev. - Deleting or renaming
master. - Removing all old release triggers immediately.
- Full on-premises maintenance release automation.
- Perfect durable artifact storage for rollback.
- Full feature flag governance automation.
- Large workflow rewrites without intermediate compatibility.
Progress checklist
- Inspect the current release implementation.
- Add release metadata helpers.
- Prepare reusable E2E / Testiny support.
- Add Edge deployment from trunk.
- Add release branch to Beta workflow.
- Add Production approval and artifact promotion.
- Add release branch creation workflow.
- Add first-class Production rollback workflow.
- Cut over branch model from
dev/mastertomain. - Retire old tag-driven release path.
- Add maintenance release automation separately.
Phase 1: Inspect the current release implementation
Create an implementation inventory before changing code.
The inventory should cover:
- existing workflows for build, deploy, release, E2E, rollback, Docker, Helm, and notifications
- existing scripts for release tagging and changelog generation
- current branch assumptions
- current tag assumptions
- current deployment targets and environment names
- Testiny integration
- Wire / Deployoholics notification integration
- conflicts between the current implementation and ADR 0002
- a proposed PR sequence with small, reviewable steps
Acceptance criteria:
- No files are changed.
- No branch is created.
- No PR is opened.
- The current implementation is documented well enough to plan the first implementation PR.
Phase 2: Add release metadata helpers
Add small deterministic helpers for release metadata.
Required behavior:
- validate release branch names matching
release/YYYY-MM-DD.N - extract the release identifier
YYYY-MM-DD.N - compute the next Beta tag from existing tags matching
YYYY-MM-DD.N-beta.M - compute the Production tag
YYYY-MM-DD.N-production - detect whether the Production tag already exists
- detect whether an existing Production tag points to the current release commit
- never move, delete, or force-push tags
- add tests for the pure release metadata logic
Acceptance criteria:
- Release naming rules are test-covered.
- Tag selection behavior is deterministic.
- No workflow behavior changes yet.
Phase 3: Prepare reusable E2E / Testiny support
Prepare .github/workflows/e2e-tests.yml so it can be called by the future release workflow.
Required behavior:
- support
testinyRunNamethroughworkflow_call - support
TESTINY_API_KEYthroughworkflow_callsecrets - keep existing manual dispatch behavior unchanged
- keep Playwright sharding and report generation unchanged
Acceptance criteria:
- A caller workflow can run E2E against a provided webapp URL.
- A caller workflow can upload the result to a named Testiny run.
- Existing manual E2E usage still works.
Phase 4: Add Edge deployment from trunk
Add a dedicated Edge deployment workflow.
Required behavior:
- trigger on pushes to
main - during transition, support the current branch setup only if needed
- build/package the webapp
- deploy to Edge
- do not require GitHub Environment approval
- use concurrency so superseded Edge runs can be cancelled
Acceptance criteria:
- Edge follows trunk.
- Edge deployment is separate from the old release/tag-driven Production flow.
- Existing Production release behavior is not changed in this phase.
Phase 5: Add release branch to Beta workflow
Add the first version of the cloud release workflow.
Required behavior:
- trigger on pushes to
release/** - validate the branch name as
release/YYYY-MM-DD.N - build the release artifact once
- deploy the artifact to Beta
- create
YYYY-MM-DD.N-beta.Monly after successful Beta deployment - fetch tags before computing the next Beta tag
- fail if a concurrent workflow created the same Beta tag
- never force-push tags
- run E2E against Beta
- report E2E results to Testiny
- add a GitHub step summary with release identifier, commit SHA, artifact checksum, Beta tag, Beta URL, E2E result, and Testiny run name
- notify the release channel / Deployoholics on failure
Acceptance criteria:
- Pushing to a valid release branch automatically deploys Beta.
- Beta tags are created only after successful Beta deployment.
- E2E and Testiny are part of the release branch workflow.
- No Production deployment is added yet.
Phase 6: Add Production approval and promotion
Extend the release workflow with the Production part.
Required behavior:
- Production waits for GitHub Environment approval.
- Production deploys the same artifact that was deployed to Beta.
- Production does not rebuild from source.
- Production deployment is serialized across the repository.
- Production deployments are not cancelled automatically.
- Before deploying, check whether
YYYY-MM-DD.N-productionalready exists. - If the Production tag already points to the same commit, skip redeployment.
- If the Production tag exists and points to a different commit, fail.
- Create
YYYY-MM-DD.N-productiononly after successful Production deployment. - Never move, delete, or force-push Production tags.
- Notify the release channel / Deployoholics on failure.
Acceptance criteria:
- Beta-tested artifact is promoted to Production.
- Production tag represents a successful Production deployment.
- Existing Production tags remain immutable.
- Re-running the workflow does not redeploy a commit that already has the matching Production tag.
Phase 7: Add release branch creation workflow
Add a manual workflow for creating release branches from GitHub Actions.
Required behavior:
- use
workflow_dispatch - input:
release_identifierin formatYYYY-MM-DD.N - input:
source_ref, defaulting tomain - input: confirmation boolean
- create
release/YYYY-MM-DD.N - fail if the branch already exists
- do not create tags
- do not deploy directly; the pushed branch should trigger the release workflow
Acceptance criteria:
- Release branches can be created without local machine release operations.
- Branch creation is auditable in GitHub Actions.
Phase 8: Add first-class rollback workflow
Add or adapt a dedicated Production rollback workflow.
Required behavior:
- use
workflow_dispatch - input: previous known-good Production tag
- input: rollback reason
- input: optional incident reference
- input: confirmation boolean
- validate the tag exists
- deploy to Production through GitHub Actions
- use the Production GitHub Environment
- serialize against other Production deployments
- notify the release channel / Deployoholics
- do not create, move, delete, or rewrite release tags
Acceptance criteria:
- Rollback is explicit and auditable.
- Rollback is owned by engineering release owners, not QA.
- Runtime state is visible through GitHub deployment metadata, logs, and notifications.
Phase 9: Cut over branch model
After the new workflows are proven:
- rename
mastertomain - retire
devas a long-lived release branch - update branch protection rules
- update GitHub workflow branch filters
- update documentation
- update external integrations
- update any
wire-buildsmappings if still needed
Acceptance criteria:
mainis the single trunk branch.- Edge follows
main. - Release branches are cut from
main. devandmasterno longer carry release meaning.
Phase 10: Retire old tag-driven release path
After the new release workflow is proven:
- stop Production deployment from pre-created Production tags
- deprecate or remove local release tagging commands
- remove outdated
staging/productionrelease tag assumptions where no longer needed - keep compatibility only where explicitly required
Acceptance criteria:
- Production tags are created after successful Production deployment.
- Local machines are no longer required for normal release operations.
- Old release paths cannot accidentally bypass the new process.
Phase 11: Add maintenance release automation separately
Add maintenance release automation only after the cloud release path is stable.
Required behavior:
- create maintenance branches only when needed
- use branch names like
maintenance/<maintenance-line-key> - do not deploy maintenance branches to normal Beta or Production
- validate maintenance artifacts through a dedicated maintenance path
- create maintenance tags like
<maintenance-line-key>-maintenance.X
Acceptance criteria:
- On-premises maintenance releases are separate from cloud releases.
- Normal cloud cadence is not constrained by maintenance lines.
Open questions
- Which existing environment maps to ADR “Beta” during the transition?
- Should
wire-webapp-stagingbe renamed conceptually or physically? - Where should immutable release artifacts live long term?
- Is GitHub Actions artifact retention sufficient for the first iteration?
- Should Elastic Beanstalk application versions become the durable promotion unit?
- What exact Testiny run naming convention should release workflows use?
- Which GitHub Environment reviewers should approve Production?
- Which Wire channel should receive release workflow failure and stalled approval notifications?
- What is the planned date for
mastertomainrename? - Which external integrations still depend on
devormaster? - Which parts of
wire-buildsstill need updates from the webapp release workflow?
Risks
- Accidentally keeping both old and new Production paths active.
- Creating Production tags before deployment instead of after deployment.
- Rebuilding for Production and invalidating Beta validation.
- Cancelling an in-progress Production deployment.
- Losing rollback ability because the artifact is not durable enough.
- Blocking release migration on branch renaming too early.
- Mixing maintenance release automation into the cloud release workflow.
Suggested first PR
Start with release metadata helpers and tests.
This should not change any workflow behavior.
Suggested scope:
- validate
release/YYYY-MM-DD.N - extract release identifier
- compute next Beta tag
- compute Production tag
- detect existing Production tag behavior
- add tests
- no GitHub Actions changes
Activity
screendriver commentedon Jun 19, 2026
Implementation inventory completed.
Important findings:
YYYY-MM-DD-production.N, but ADR 0002 requiresYYYY-MM-DD.N-production.YYYY-MM-DD-staging.N, but ADR 0002 requires Beta tags likeYYYY-MM-DD.N-beta.M.dev, notmain.workflow_calldoes not yet exposetestinyRunName/TESTINY_API_KEY.devandmasterstill carry release meaning.Proposed first PR:
Add pure release metadata helpers and tests.
Scope:
release/YYYY-MM-DD.NYYYY-MM-DD.NYYYY-MM-DD.N-beta.MYYYY-MM-DD.N-productionscreendriver commentedon Jun 24, 2026
Phase 3 is done.
Pull request merged:
This prepared the reusable E2E workflow for future release workflows by exposing Testiny reporting through
workflow_call.Next phase:
Add a dedicated Edge deployment workflow.
Important transition note:
The new workflow should not automatically run on
dev, because the existing publish workflow still deploysdevtowire-webapp-edge. The new workflow should auto-trigger onmainonly and optionally support manual dispatch for safe testing.screendriver commentedon Jun 24, 2026
Phase 4 is done.
PR merged:
This adds the future
main→ Edge deployment workflow without changing the existingdev→ Edge path or the current release process.Next phase:
Add the release branch → Beta workflow.
screendriver commentedon Jun 25, 2026
Phase 5 is done.
Pull request merged:
This adds the manual transition version of the release-cloud Beta workflow:
release_branchinputwire-webapp-staging)YYYY-MM-DD.N-beta.Mafter successful Beta deploymentAutomatic
release/**triggering stays disabled during the transition to avoid disrupting the current release process.screendriver commentedon Jun 29, 2026
Phase 6 is done.
Pull request merged:
This extends the manual
release-cloudworkflow with optional Production promotion:promote_to_productioninputwire-webapp-prodGitHub Environment approvalYYYY-MM-DD.N-productiontag creation after successful Production deploymentThe workflow remains manual-only during the transition.
screendriver commentedon Jun 30, 2026
Phase 7 is done.
Pull request merged:
This adds the manual GitHub Actions workflow for creating
release/YYYY-MM-DD.Nbranches.The workflow:
.0release identifierssource_refsource_reftodevduring the transitionrelease/<release_identifier>Next phase:
Add first-class Production rollback workflow.
screendriver commentedon Jun 30, 2026
Phase 8 is done.
Pull request merged:
This adds a manual first-class Production rollback workflow:
wire-webapp-prodNext phase:
Cut over the branch model.
screendriver commentedon Jul 14, 2026
The Edge and Beta environment expectations have been clarified in ADR 0002.
Pull request:
Before starting the branch-model cutover, the next step is a focused cutover-readiness inventory. This will classify repository and external branch dependencies and define the atomic migration sequence for
dev/master→main.screendriver commentedon Jul 14, 2026
Phase 9 coordinated branch cutover completed operationally on 2026-07-14.
chore: add eventListenerService [WPB-23186] #21000
feat: add state-machine for appLockflow [WPB-23186] #21005
feat: add option to disable message preprocessing in the internal appconfiguration [WPB-22420] #21275
chore(deps): update dependency dexie to v4.4.4 #21605
Update lexical to v0.52.0 #21682
chore: WPB-18035 Rename translation keys to not use keyword Services but to use Apps instead. #21767
fix: bring back optimize WebGL through ANGLE on Direct3D [WPB-25918] #21786
fix: never exposed original video when background effect enabled [WPB-26402] #21797
Join meeting calls from the Meetings tab [WPB-25057] #21822
fix(meetings): polish participant picker and schedule defaults [WPB-25055] #21826
test: add test to verify the env variables of the environment [WPB-22420] #21828
feat: add acc string for active and non-active conv [WPB-21212] #21830
feat: add accessibility string for profile icon [WPB-21213] #21831
Use refresh event for WebApp updates [WPB-22420] #21838
Phase 9 is not complete until PR #21841 is reviewed and merged and the external integrations are verified.
screendriver commentedon Jul 14, 2026
Phase 9 is complete.
Merged pull requests:
maincutovermainhttps://wire-webapp-beta.wire.com/Current state:
mainis the single trunk branchmainmainhttps://wire-webapp-beta.wire.com/wire-webapp-stagingdevandmasterremain temporarily for compatibility but are no longer normal development branchesrelease-cloudremains manual-onlyRemaining steps before Phase 10:
main, Edge, and Production GitHub protection settingsPhase 10 will retire the remaining tag-driven release path only after those checks succeed.
screendriver commentedon Jul 29, 2026
Phase 10 cleanup is in progress.
Pull request:
#22030
This retires the legacy tag-driven release path and prepares deletion of the obsolete
devandmasterbranches.Deliver main, Hosted Dev, the dev distribution channel, and recovery workflows remain unchanged.The Phase 10 checkbox stays open until the pull request is merged and both remote branches are deleted.
screendriver commentedon Jul 29, 2026
Phase 10 is complete.
Completed by:
Retired:
masterdeployment;devandmasterbranch assumptions.Deleted remote branches:
masterdevPreserved:
Deliver main;wire-builds/dev;Release WebApp;The legacy path was intentionally retired before the first complete Production run of the final workflow. The next real release will validate the new path end to end, and any issue will be repaired there rather than through a legacy fallback.
Phase 11 remains open for separate maintenance-release automation.
screendriver commentedon Aug 7, 2026
Phase 11 is nearly complete.
Implemented:
Protect release and maintenance branchesruleset now protects bothrelease/*andmaintenance/*with the same review and CI requirements.maintenance/*to the existing continuous-integration workflow filters so maintenance pull requests can satisfy those required checks.Once #22136 is merged, the repository implementation and branch-protection setup for Phase 11 are complete.
There is no Phase 12 in this issue; Phase 11 is the final defined phase.
screendriver commentedon Aug 7, 2026
ADR 0002 implementation is complete.
Phase 11 is now complete:
Protect release and maintenance branchesruleset protects bothrelease/*andmaintenance/*with the same review and CI requirements.maintenance/*.The normal cloud release process was already proven end to end with release
2026-07-27.1, and maintenance releases are now isolated from the normal cloud release cadence as defined by ADR 0002.A maintenance line will be created only when a real maintenance release is required; no artificial maintenance branch or release is needed to complete this migration.
All 11 implementation phases are complete. There is no Phase 12.