feat(app-dev): add dry-run preview to dev sync (#21251)

Split out of #21240. Stacked on #21250 (review/merge that first).

`yarn twenty dev --once --dry-run` computes the migration plan and
prints the diff **without applying anything** (no migration, no
app-record update, no SDK generation). Also renders the diff on a normal
`dev --once` sync.

<img width="646" height="179" alt="image"
src="https://github.com/user-attachments/assets/59f3ddcd-2a5b-4b8a-b21a-c659abe16af0"
/>
This commit is contained in:
martmull
2026-06-05 19:49:02 +02:00
committed by GitHub
parent bfb83e93b2
commit 6c65d26ced
19 changed files with 257 additions and 51 deletions
@@ -3360,7 +3360,7 @@ type Mutation {
syncMarketplaceCatalog: Boolean!
createDevelopmentApplication(universalIdentifier: String!, name: String!): DevelopmentApplication!
generateApplicationToken(applicationId: UUID!): ApplicationTokenPair!
syncApplication(manifest: JSON!): WorkspaceMigration!
syncApplication(manifest: JSON!, dryRun: Boolean): WorkspaceMigration!
uploadApplicationFile(file: Upload!, applicationUniversalIdentifier: String!, fileFolder: FileFolder!, filePath: String!): File!
upgradeApplication(appRegistrationId: String!, targetVersion: String!): Boolean!
renewApplicationToken(applicationRefreshToken: String!): ApplicationTokenPair!
@@ -5972,7 +5972,7 @@ export interface MutationGenqlSelection{
syncMarketplaceCatalog?: boolean | number
createDevelopmentApplication?: (DevelopmentApplicationGenqlSelection & { __args: {universalIdentifier: Scalars['String'], name: Scalars['String']} })
generateApplicationToken?: (ApplicationTokenPairGenqlSelection & { __args: {applicationId: Scalars['UUID']} })
syncApplication?: (WorkspaceMigrationGenqlSelection & { __args: {manifest: Scalars['JSON']} })
syncApplication?: (WorkspaceMigrationGenqlSelection & { __args: {manifest: Scalars['JSON'], dryRun?: (Scalars['Boolean'] | null)} })
uploadApplicationFile?: (FileGenqlSelection & { __args: {file: Scalars['Upload'], applicationUniversalIdentifier: Scalars['String'], fileFolder: FileFolder, filePath: Scalars['String']} })
upgradeApplication?: { __args: {appRegistrationId: Scalars['String'], targetVersion: Scalars['String']} }
renewApplicationToken?: (ApplicationTokenPairGenqlSelection & { __args: {applicationRefreshToken: Scalars['String']} })
@@ -8761,6 +8761,9 @@ export default {
"manifest": [
15,
"JSON!"
],
"dryRun": [
6
]
}
],