Repository navigation
fix(gitops): the cell file never silently drops a composed module's workloads - #1150
Merged
Merged
Conversation
…orkloads The cell file is regenerated whole from the per-module render records (deployments/modules/<m>/.codefly-render.json), which are uncommitted render outputs. After a clean of deployments/, rendering saas and robin wrote a cell file with 4 insertions and 1026 deletions: 25 workloads of 9 other modules gone, and nothing warned. - A render refuses to write the cell file while a module the workspace composes has no render record for the environment (missing, or rendered for another environment), naming each module and the command that renders it. It does not carry the module's entries over from the file on disk: an entry is derived from the whole composition, so a carried-over entry is a claim about a composition that may no longer exist. - plan/publish hold the workspace's cell file to the delivery base branch's and refuse one that removes a namespace, workload, endpoint or endpoint consumer the base admits, unless --allow-cell-removal names the module the removal concerns; the plan lists every removal it lets through. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Defect
On 2026-10-24, in obin-ai/platform-obin with CLI 0.1.211,
codefly deploy gitops render <module> --env bluerebuilt the whole cell file (deployments/environments/blue/cells/blue/cell.yaml) from whichever per-module render records (deployments/modules/<m>/.codefly-render.json) happened to be in the checkout. Those records are uncommitted render outputs. After agit cleanofdeployments/, rendering only saas and robin wrote a cell file with 4 insertions and 1026 deletions: 25 workloads of 9 other modules were gone. Publishing that file would have taken those modules out of admission, so every new pod would have been denied. Earlier the same day, a render where 6 modules failed produced a cell file missing 818 lines. Neither run warned.Design
Classification: fix, made where the behaviour lives (the cell render and the publish). No hack.
refuseUnrenderedModules,pkg/gitops/cell.go). Suppose a module inworkspace.Moduleshas no render record for the environment, either because there is none or because the one present was rendered for a different environment. ThenderiveCellrefuses. It names each such module and gives the command that renders it (codefly deploy gitops render <m> --env <env>, orrender --all). The cell file is not written, and the copy on disk stays as it was. A single-module render still finishes and reports the refusal through the existing "Cell file not re-derived" warning. Rendering module by module converges, andrender --allis unaffected.git cleanthat removes the records. No digest is invented.deploy dev. It already refused any namespace move (cellMovesBeyond), and it now gets the clearer reason.holdCellToBase,pkg/gitops/cell_removals.go).planandpublishread two files for a hosted environment: the workspace's cell file, and the one at<gitops path>/cells/<env>/cell.yamlon the delivery base revision in the promotion clone. They refuse when the workspace's file removes anything the base admits: a namespace, a workload, an endpoint, or a consumer of an endpoint. The error names every removal and the module it concerns.--allow-cell-removal <module>(repeatable, onplan/publish) lets through the removals that concern a named module. Use it, for example, when the workspace no longer composes a module. A consumer edge is covered by naming either the endpoint's module or the consumer's module.cellRemovals. That field is part of the plan ID.Reused:
deriveCell/CellPath/cellfile.Parse, the promotion clone and base revision thatpreparePublishalready holds,gitCommandBytes/gitSaysAbsent, and the plan-ID hashing.Not done, on purpose: publish still does not stage the cell file into the delivery repository. The cell file is committed alongside the rendered trees, as before. This check is what holds that claim to the base before a promotion. Rollback is not covered: it re-promotes a module tree and leaves the cell file alone.
Tests
TestCellFileRefusesToDropAComposedModuleWithNoRender: a full render writes the file. Deleting billing's render makes the next render refuse, naming billing andcodefly deploy gitops render billing --env staging, and the file on disk stays byte-identical. Rendering billing again writes the file.TestCellFileSkipsTreesRenderedForAnotherEnvironment(updated): a composed module whose only record is for another environment is refused by name instead of being skipped silently.TestPublishRefusesACellFileThatRemovesWhatTheBaseAdmits:--allow-cell-removal (billing).shopcovers the edge but not the namespace.billingallows both, and the plan lists them.TestCellFileInventoriesEveryRenderedWorkloadand the rest ofpkg/gitops,cmd/deployandcmd(CLI reference) pass unchanged.make lintreports 0 issues.Docs
docs/commands.md: the cell file section now covers the never-drop rule with its justification and the publish hold with--allow-cell-removal. The render section says a single render reports a composed module with no render as owed.docs/cli-reference.md: regenerated for the new flag.Not verified
holdCellToBaseis unit-tested directly against a real git base revision. No fullpublishtest goes through a hosted fixture with a pre-existing base cell file; the wiring inpreparePublishis one call.workspace.Modulesmatches "every module delivered to this environment" in every composition: a module whose services an environment excludes entirely would now need a record. It is the same setrender --allrenders.🤖 Generated with Claude Code