dsh-d365-kit 0.34.1 → 0.34.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +319 -308
- package/CHANGELOG.zh-CN.md +318 -307
- package/INSTALL.md +94 -94
- package/INSTALL.zh-CN.md +93 -93
- package/LICENSE +21 -21
- package/README.md +336 -327
- package/README.zh-CN.md +336 -327
- package/client.js +1818 -1818
- package/cordis.patch.yml +44 -44
- package/docs/en/architecture.md +172 -172
- package/docs/en/checks.md +184 -184
- package/docs/en/installation.md +151 -151
- package/docs/en/permissions.md +161 -161
- package/docs/en/scenarios.md +202 -202
- package/docs/en/tools.md +665 -665
- package/docs/en/troubleshooting.md +131 -131
- package/docs/zh/architecture.md +172 -172
- package/docs/zh/checks.md +184 -184
- package/docs/zh/installation.md +151 -151
- package/docs/zh/permissions.md +161 -161
- package/docs/zh/scenarios.md +202 -202
- package/docs/zh/tools.md +665 -665
- package/docs/zh/troubleshooting.md +131 -131
- package/examples/prompts.en.md +206 -206
- package/examples/prompts.zh-CN.md +206 -206
- package/examples/waivers.example.json +20 -20
- package/icon.svg +6 -6
- package/index.js +139 -139
- package/lib/auth.js +181 -181
- package/lib/client.js +496 -496
- package/lib/code-check.js +549 -549
- package/lib/config.js +323 -323
- package/lib/contract-history.js +49 -49
- package/lib/contract.js +583 -583
- package/lib/csharp-check.js +493 -493
- package/lib/data-migrate.js +1318 -1318
- package/lib/data-policy.js +78 -78
- package/lib/error-codes.js +80 -80
- package/lib/gitlab.js +161 -161
- package/lib/health.js +205 -205
- package/lib/migrate.js +732 -732
- package/lib/preflight.js +116 -116
- package/lib/refs.js +191 -191
- package/lib/resources.js +320 -320
- package/lib/retention-defaults.js +17 -17
- package/lib/retention.js +384 -384
- package/lib/runtime.js +232 -232
- package/lib/settings-http.js +512 -512
- package/lib/settings-store.js +371 -371
- package/lib/snapshot.js +149 -149
- package/lib/tool-code-check.js +133 -133
- package/lib/tool-configure.js +169 -169
- package/lib/tool-contract.js +376 -376
- package/lib/tool-data-sync.js +559 -559
- package/lib/tool-data-write.js +203 -203
- package/lib/tool-data.js +282 -282
- package/lib/tool-diff.js +484 -484
- package/lib/tool-environments.js +106 -106
- package/lib/tool-flows.js +540 -540
- package/lib/tool-health.js +127 -127
- package/lib/tool-layers.js +497 -497
- package/lib/tool-metadata.js +417 -417
- package/lib/tool-migrate.js +102 -102
- package/lib/tool-refs.js +206 -206
- package/lib/tool-reports.js +299 -299
- package/lib/tool-sync.js +430 -430
- package/lib/tool-write.js +563 -563
- package/lib/waivers.js +83 -83
- package/lib/write-actions.js +1374 -1374
- package/lib/write-policy.js +199 -199
- package/lib/write-store.js +167 -167
- package/locale/en.json +68 -68
- package/locale/zh.json +68 -68
- package/package.json +2 -2
- package/skills/d365-troubleshooting/SKILL.md +115 -115
package/docs/en/scenarios.md
CHANGED
|
@@ -1,202 +1,202 @@
|
|
|
1
|
-
# Usage Scenarios
|
|
2
|
-
|
|
3
|
-
**English** | [简体中文](../zh/scenarios.md)
|
|
4
|
-
|
|
5
|
-
Everything below can be said to the agent as-is. Tool arguments are in brackets; the agent fills them in itself.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 1. Taking over an environment: get the lay of the land
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
Connect to all four environments and see what each one is doing.
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
d365_envs check=true
|
|
17
|
-
d365_health allEnvironments=true hours=24
|
|
18
|
-
d365_metadata resource=organization
|
|
19
|
-
d365_metadata resource=solutions top=10 orderby="installedon desc"
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
What you get: whether each environment is reachable, its org version, hung/failed jobs, imports and publishes in progress, and what was installed recently.
|
|
23
|
-
|
|
24
|
-
This is the first step before answering any "does the environment have X" — it keeps you from mistaking "not configured" for "not present in the environment".
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## 2. Can this field be deleted?
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
Which forms, views, and workflows still use contoso_customertier on account? Also check how many records still carry a value.
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
d365_refs kind=field entity=account attribute=contoso_customertier allEnvironments=true
|
|
36
|
-
d365_data action=group entity=account field=contoso_customertier top=10
|
|
37
|
-
d365_layers component=contoso_customertier componentType=Attribute entity=account
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Three pieces of evidence together:
|
|
41
|
-
|
|
42
|
-
- **References**: 17 forms, 64 views (62 columns / 50 filters), 0 workflows/business rules;
|
|
43
|
-
- **Data**: the distribution of records that have a value for the field (empty is its own bucket);
|
|
44
|
-
- **Layers**: who added the field and which solution owns the active layer — if it comes from a managed solution you cannot delete it locally, only the publisher can change it.
|
|
45
|
-
|
|
46
|
-
The delete itself is `d365_write action=plan-delete-attribute ... acknowledge=true`, but you usually use these three pieces of evidence to convince people first.
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## 3. Why two environments differ
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
Sync forms, views, and fields from DEV and SIT, tell me the differences, then explain why the Account form differs.
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
```
|
|
57
|
-
d365_sync environments=["dev","sit"] resources=["forms","views","solutions"] includeAttributes=true entities=["account"]
|
|
58
|
-
d365_diff base=dev head=sit resources=["forms","views","attributes"]
|
|
59
|
-
d365_layers component=Account componentType=SystemForm allEnvironments=true
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
`d365_diff` gives the mechanical difference (which rows were added/removed, which fields changed); `d365_layers` gives the reason (who overrode it, who sits on top).
|
|
63
|
-
|
|
64
|
-
Noise is already handled: timestamps and `*id` columns are not compared, and `organization` is skipped by default. When form content differs a lot, the field-level diff in the report reads far better than a wall of XML.
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
## 4. Assessing a solution before release
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
What are the risks of shipping ContosoBase from DEV to SIT and UAT?
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
d365_migrate action=assess source=dev solution=ContosoBase targets=["sit","uat"]
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
The report answers:
|
|
79
|
-
|
|
80
|
-
- whether the targets have this solution, and whether the source version is newer;
|
|
81
|
-
- who owns the top layer of each component in the target, and which solutions' definitions get shadowed after import (shadowed solutions are listed, sorted by component count);
|
|
82
|
-
- whether option set values will be lost (a value the source has and the target lacks = critical; mismatched labels = warning);
|
|
83
|
-
- which components the target is missing;
|
|
84
|
-
- when the source is unmanaged, the layer the import creates cannot be cleared by uninstalling a solution.
|
|
85
|
-
|
|
86
|
-
A real case: for a solution holding just 1 global option set, the assessment can come back as "0 critical, 2 warnings, but it will invalidate the definitions of 7 solutions" — the decision that actually matters is not about losing data, it is that **the next time anyone imports a Contoso patch, that layer gets covered again**.
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## 5. Checking whether an MR can ship to UAT
|
|
91
|
-
|
|
92
|
-
```
|
|
93
|
-
https://gitlab.example.com/contoso/powerapps/-/merge_requests/7759/diffs will this MR cause problems if it goes to UAT?
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
```
|
|
97
|
-
d365_code_check mergeRequest="https://gitlab.example.com/contoso/powerapps/-/merge_requests/7759/diffs" targets=["uat"]
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Three sections come out:
|
|
101
|
-
|
|
102
|
-
- **Blockers**: a field is on none of the forms that load the library, an entity does not exist, a deleted function is still referenced by a handler, a C# type/step/image is missing;
|
|
103
|
-
- **Warnings**: a field is only on some forms, the assembly version was not bumped, a hard-coded GUID;
|
|
104
|
-
- **Manual confirmation**: configuration data, secure configuration, privileges, ambiguity between a column name and a plain key.
|
|
105
|
-
|
|
106
|
-
The report is at `.d365/reports/code-check-<MR>-<timestamp>.md`.
|
|
107
|
-
|
|
108
|
-
C#-only MRs work too: infer the assembly from the project directory → exact match → look up types/steps/images/filtering attributes. Assembly names are matched exactly only; guessing wrong is worse than not checking.
|
|
109
|
-
|
|
110
|
-
---
|
|
111
|
-
|
|
112
|
-
## 6. Filling in a batch of option values
|
|
113
|
-
|
|
114
|
-
```
|
|
115
|
-
contoso_taxcategoryos is still missing 36 tax registration number types; add them to DEV from the list in .d365/reports.
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
```
|
|
119
|
-
d365_write action=plan-add-options environment=dev optionSet=contoso_taxcategoryos \
|
|
120
|
-
labels=["AD3|Andorra: Tax Register Number (NRT)", "..."]
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
The plan returns the list of operations (values continue from the current maximum +1; codes that already exist go into skipped). Once checked:
|
|
124
|
-
|
|
125
|
-
```
|
|
126
|
-
Run mw04aul6-1ci6aa
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
A card pops up in the conversation → approve → write → publish only this option set. The audit trail is in `.d365/changes/`, the publish result in `.d365/changes/publish-<planId>.json`.
|
|
130
|
-
|
|
131
|
-
**Do not append them by hand in the remaining environments**: let them ride along with the solution import, otherwise the next time someone imports a managed patch your hand-added layer gets covered.
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
## 7. Upstream changed a plugin — what is downstream missing
|
|
136
|
-
|
|
137
|
-
```
|
|
138
|
-
Has SIT and UAT caught up with DEV's plugin registrations? Also check whether any scripts referenced by forms are missing.
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
```
|
|
142
|
-
d365_contract action=drift source=dev targets=["sit","uat"] forms=true
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
Typical result (real data): 86 findings = 4 missing assemblies, 72 missing plugin steps, 8 missing types, 2 missing form libraries.
|
|
146
|
-
`forms=false` skips reading formxml; `handlers=true` downloads scripts to check that the functions exist (slow, up to 400 scripts per environment).
|
|
147
|
-
|
|
148
|
-
Register a waiver for differences that are genuinely allowed:
|
|
149
|
-
|
|
150
|
-
```
|
|
151
|
-
d365_contract action=waive rule=form-library-missing env=sit \
|
|
152
|
-
object="/_static/_common/scripts/CommandbarActions.js" reason="this environment does not use SLA dialogs" days=30
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
The next run over the same `source → targets` reports a trend of "N new / M gone".
|
|
156
|
-
|
|
157
|
-
---
|
|
158
|
-
|
|
159
|
-
## 8. Publish is stuck / can I write now
|
|
160
|
-
|
|
161
|
-
```
|
|
162
|
-
Is any import or publish running in the four environments right now? I want to change some metadata.
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
```
|
|
166
|
-
d365_health allEnvironments=true
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
If an environment has a `Publish` or an import in progress, any write gets `0x80071151` or waits until the lock times out. Wait for it to finish; `d365_write execute` checks this step itself and refuses outright when the environment is busy instead of throwing a raw 429.
|
|
170
|
-
|
|
171
|
-
Only use `force: true` once you have confirmed that record is a leftover (for example, an import that was interrupted days ago).
|
|
172
|
-
|
|
173
|
-
---
|
|
174
|
-
|
|
175
|
-
## 9. Disk is bloated by artifacts
|
|
176
|
-
|
|
177
|
-
```
|
|
178
|
-
How big is .d365 now? What can be cleaned up?
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
```
|
|
182
|
-
d365_reports action=list
|
|
183
|
-
d365_reports action=cleanup target=query # dry run only by default
|
|
184
|
-
d365_reports action=cleanup target=query dryRun=false
|
|
185
|
-
d365_reports action=compact # compact snapshot JSON to one line
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
Real data: four full snapshots take about 540 MB, and compacting to one line saves 68 MB; within a single snapshot, `plugin_steps.json` is about 55 MB, `solution_components.json` about 39 MB, and `web_resources.json` about 20 MB.
|
|
189
|
-
|
|
190
|
-
For the retention policy and automatic cleanup, see [tools.md](tools.md#d365_reports) and the [root README](../../README.md).
|
|
191
|
-
|
|
192
|
-
---
|
|
193
|
-
|
|
194
|
-
## Combined usage
|
|
195
|
-
|
|
196
|
-
| Question | Combination |
|
|
197
|
-
| --- | --- |
|
|
198
|
-
| Is it safe to change this field | `d365_refs` + `d365_data` + `d365_layers` |
|
|
199
|
-
| Can this version ship | `d365_health` + `d365_migrate` + `d365_contract` |
|
|
200
|
-
| Can this MR merge | `d365_code_check` + `d365_refs` |
|
|
201
|
-
| Where do the environments differ | `d365_sync` + `d365_diff` + `d365_layers` |
|
|
202
|
-
| Why does it fail at runtime | `d365_refs` (field/script references) + `d365_layers` (who overrides) + `d365_health` (jobs) |
|
|
1
|
+
# Usage Scenarios
|
|
2
|
+
|
|
3
|
+
**English** | [简体中文](../zh/scenarios.md)
|
|
4
|
+
|
|
5
|
+
Everything below can be said to the agent as-is. Tool arguments are in brackets; the agent fills them in itself.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Taking over an environment: get the lay of the land
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Connect to all four environments and see what each one is doing.
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
d365_envs check=true
|
|
17
|
+
d365_health allEnvironments=true hours=24
|
|
18
|
+
d365_metadata resource=organization
|
|
19
|
+
d365_metadata resource=solutions top=10 orderby="installedon desc"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
What you get: whether each environment is reachable, its org version, hung/failed jobs, imports and publishes in progress, and what was installed recently.
|
|
23
|
+
|
|
24
|
+
This is the first step before answering any "does the environment have X" — it keeps you from mistaking "not configured" for "not present in the environment".
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 2. Can this field be deleted?
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
Which forms, views, and workflows still use contoso_customertier on account? Also check how many records still carry a value.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
d365_refs kind=field entity=account attribute=contoso_customertier allEnvironments=true
|
|
36
|
+
d365_data action=group entity=account field=contoso_customertier top=10
|
|
37
|
+
d365_layers component=contoso_customertier componentType=Attribute entity=account
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Three pieces of evidence together:
|
|
41
|
+
|
|
42
|
+
- **References**: 17 forms, 64 views (62 columns / 50 filters), 0 workflows/business rules;
|
|
43
|
+
- **Data**: the distribution of records that have a value for the field (empty is its own bucket);
|
|
44
|
+
- **Layers**: who added the field and which solution owns the active layer — if it comes from a managed solution you cannot delete it locally, only the publisher can change it.
|
|
45
|
+
|
|
46
|
+
The delete itself is `d365_write action=plan-delete-attribute ... acknowledge=true`, but you usually use these three pieces of evidence to convince people first.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 3. Why two environments differ
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
Sync forms, views, and fields from DEV and SIT, tell me the differences, then explain why the Account form differs.
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
d365_sync environments=["dev","sit"] resources=["forms","views","solutions"] includeAttributes=true entities=["account"]
|
|
58
|
+
d365_diff base=dev head=sit resources=["forms","views","attributes"]
|
|
59
|
+
d365_layers component=Account componentType=SystemForm allEnvironments=true
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`d365_diff` gives the mechanical difference (which rows were added/removed, which fields changed); `d365_layers` gives the reason (who overrode it, who sits on top).
|
|
63
|
+
|
|
64
|
+
Noise is already handled: timestamps and `*id` columns are not compared, and `organization` is skipped by default. When form content differs a lot, the field-level diff in the report reads far better than a wall of XML.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 4. Assessing a solution before release
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
What are the risks of shipping ContosoBase from DEV to SIT and UAT?
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
d365_migrate action=assess source=dev solution=ContosoBase targets=["sit","uat"]
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The report answers:
|
|
79
|
+
|
|
80
|
+
- whether the targets have this solution, and whether the source version is newer;
|
|
81
|
+
- who owns the top layer of each component in the target, and which solutions' definitions get shadowed after import (shadowed solutions are listed, sorted by component count);
|
|
82
|
+
- whether option set values will be lost (a value the source has and the target lacks = critical; mismatched labels = warning);
|
|
83
|
+
- which components the target is missing;
|
|
84
|
+
- when the source is unmanaged, the layer the import creates cannot be cleared by uninstalling a solution.
|
|
85
|
+
|
|
86
|
+
A real case: for a solution holding just 1 global option set, the assessment can come back as "0 critical, 2 warnings, but it will invalidate the definitions of 7 solutions" — the decision that actually matters is not about losing data, it is that **the next time anyone imports a Contoso patch, that layer gets covered again**.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 5. Checking whether an MR can ship to UAT
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
https://gitlab.example.com/contoso/powerapps/-/merge_requests/7759/diffs will this MR cause problems if it goes to UAT?
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
d365_code_check mergeRequest="https://gitlab.example.com/contoso/powerapps/-/merge_requests/7759/diffs" targets=["uat"]
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Three sections come out:
|
|
101
|
+
|
|
102
|
+
- **Blockers**: a field is on none of the forms that load the library, an entity does not exist, a deleted function is still referenced by a handler, a C# type/step/image is missing;
|
|
103
|
+
- **Warnings**: a field is only on some forms, the assembly version was not bumped, a hard-coded GUID;
|
|
104
|
+
- **Manual confirmation**: configuration data, secure configuration, privileges, ambiguity between a column name and a plain key.
|
|
105
|
+
|
|
106
|
+
The report is at `.d365/reports/code-check-<MR>-<timestamp>.md`.
|
|
107
|
+
|
|
108
|
+
C#-only MRs work too: infer the assembly from the project directory → exact match → look up types/steps/images/filtering attributes. Assembly names are matched exactly only; guessing wrong is worse than not checking.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 6. Filling in a batch of option values
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
contoso_taxcategoryos is still missing 36 tax registration number types; add them to DEV from the list in .d365/reports.
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
d365_write action=plan-add-options environment=dev optionSet=contoso_taxcategoryos \
|
|
120
|
+
labels=["AD3|Andorra: Tax Register Number (NRT)", "..."]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The plan returns the list of operations (values continue from the current maximum +1; codes that already exist go into skipped). Once checked:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
Run mw04aul6-1ci6aa
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
A card pops up in the conversation → approve → write → publish only this option set. The audit trail is in `.d365/changes/`, the publish result in `.d365/changes/publish-<planId>.json`.
|
|
130
|
+
|
|
131
|
+
**Do not append them by hand in the remaining environments**: let them ride along with the solution import, otherwise the next time someone imports a managed patch your hand-added layer gets covered.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 7. Upstream changed a plugin — what is downstream missing
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
Has SIT and UAT caught up with DEV's plugin registrations? Also check whether any scripts referenced by forms are missing.
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
d365_contract action=drift source=dev targets=["sit","uat"] forms=true
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Typical result (real data): 86 findings = 4 missing assemblies, 72 missing plugin steps, 8 missing types, 2 missing form libraries.
|
|
146
|
+
`forms=false` skips reading formxml; `handlers=true` downloads scripts to check that the functions exist (slow, up to 400 scripts per environment).
|
|
147
|
+
|
|
148
|
+
Register a waiver for differences that are genuinely allowed:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
d365_contract action=waive rule=form-library-missing env=sit \
|
|
152
|
+
object="/_static/_common/scripts/CommandbarActions.js" reason="this environment does not use SLA dialogs" days=30
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The next run over the same `source → targets` reports a trend of "N new / M gone".
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 8. Publish is stuck / can I write now
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
Is any import or publish running in the four environments right now? I want to change some metadata.
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
d365_health allEnvironments=true
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
If an environment has a `Publish` or an import in progress, any write gets `0x80071151` or waits until the lock times out. Wait for it to finish; `d365_write execute` checks this step itself and refuses outright when the environment is busy instead of throwing a raw 429.
|
|
170
|
+
|
|
171
|
+
Only use `force: true` once you have confirmed that record is a leftover (for example, an import that was interrupted days ago).
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## 9. Disk is bloated by artifacts
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
How big is .d365 now? What can be cleaned up?
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
d365_reports action=list
|
|
183
|
+
d365_reports action=cleanup target=query # dry run only by default
|
|
184
|
+
d365_reports action=cleanup target=query dryRun=false
|
|
185
|
+
d365_reports action=compact # compact snapshot JSON to one line
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Real data: four full snapshots take about 540 MB, and compacting to one line saves 68 MB; within a single snapshot, `plugin_steps.json` is about 55 MB, `solution_components.json` about 39 MB, and `web_resources.json` about 20 MB.
|
|
189
|
+
|
|
190
|
+
For the retention policy and automatic cleanup, see [tools.md](tools.md#d365_reports) and the [root README](../../README.md).
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Combined usage
|
|
195
|
+
|
|
196
|
+
| Question | Combination |
|
|
197
|
+
| --- | --- |
|
|
198
|
+
| Is it safe to change this field | `d365_refs` + `d365_data` + `d365_layers` |
|
|
199
|
+
| Can this version ship | `d365_health` + `d365_migrate` + `d365_contract` |
|
|
200
|
+
| Can this MR merge | `d365_code_check` + `d365_refs` |
|
|
201
|
+
| Where do the environments differ | `d365_sync` + `d365_diff` + `d365_layers` |
|
|
202
|
+
| Why does it fail at runtime | `d365_refs` (field/script references) + `d365_layers` (who overrides) + `d365_health` (jobs) |
|