@monochange/skill 0.0.0 → 0.4.2

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.
@@ -0,0 +1,237 @@
1
+ # Multi-package publishing patterns
2
+
3
+ Use this guide when one repository publishes more than one public package and the publish workflow cannot be explained by a single generic `mc publish-readiness` plus `mc publish` example.
4
+
5
+ This is the practical companion to [trusted-publishing.md](./trusted-publishing.md).
6
+
7
+ ## Core idea
8
+
9
+ For multi-package repositories, keep one distinction clear:
10
+
11
+ - monochange plans releases at the workspace level
12
+ - registries authorize publishing at the package level
13
+
14
+ That means one release commit can describe the whole workspace while publish automation still needs to stay package-specific.
15
+
16
+ A good default rollout is:
17
+
18
+ 1. let monochange prepare one release commit for the workspace
19
+ 2. decide which packages use built-in publishing and which use `mode = "external"`
20
+ 3. keep each registry's trusted-publishing enrollment aligned with the exact workflow, tag pattern, and working directory that will publish that package
21
+
22
+ ## Pattern 1: one post-merge `mc publish-readiness` and `mc publish` job
23
+
24
+ Use this when most packages can stay on monochange's built-in publishing path.
25
+
26
+ ```yaml
27
+ name: publish-packages
28
+
29
+ on:
30
+ push:
31
+ branches: [main]
32
+
33
+ jobs:
34
+ publish:
35
+ runs-on: ubuntu-latest
36
+ permissions:
37
+ contents: read
38
+ id-token: write
39
+ steps:
40
+ - uses: actions/checkout@v6
41
+ with:
42
+ fetch-depth: 0
43
+
44
+ - uses: ./.github/actions/devenv
45
+ with:
46
+ github-token: ${{ secrets.GITHUB_TOKEN }}
47
+
48
+ - name: detect monochange release commit
49
+ shell: bash
50
+ run: |
51
+ set -euo pipefail
52
+ if ! devenv shell -- mc release-record --from HEAD --format json >/tmp/release-record.json 2>/dev/null; then
53
+ echo "HEAD is not a monochange release commit; skipping publish"
54
+ exit 0
55
+ fi
56
+
57
+ - name: publish packages
58
+ run: |
59
+ devenv shell -- mc publish-readiness --from HEAD --output .monochange/readiness.json
60
+ devenv shell -- mc publish --output .monochange/publish-result.json
61
+ ```
62
+
63
+ This is the best fit when:
64
+
65
+ - multiple npm packages publish from the same workflow
66
+ - multiple packages share the same built-in post-merge flow
67
+ - you do not need package-specific tag triggers to satisfy the registry
68
+
69
+ ## Pattern 2: package-specific external workflows
70
+
71
+ Use this when the registry expects each package to have its own tag trigger, working directory, or workflow.
72
+
73
+ This is often the clearest fit for:
74
+
75
+ - `pub.dev`
76
+ - some `crates.io` setups
77
+ - mixed workspaces where one package needs registry-native steps that do not match `mc publish`
78
+
79
+ Example tag naming scheme:
80
+
81
+ - `web-v{{version}}`
82
+ - `cli-v{{version}}`
83
+ - `dart_client-v{{version}}`
84
+
85
+ Example config:
86
+
87
+ ```toml
88
+ [ecosystems.cargo.publish]
89
+ enabled = true
90
+ mode = "external"
91
+ trusted_publishing = true
92
+
93
+ [ecosystems.dart.publish]
94
+ enabled = true
95
+ mode = "external"
96
+ trusted_publishing = true
97
+ registry = "pub.dev"
98
+ ```
99
+
100
+ Example workflow shape:
101
+
102
+ ```yaml
103
+ name: publish-dart-client
104
+
105
+ on:
106
+ push:
107
+ tags:
108
+ - "dart_client-v[0-9]+.[0-9]+.[0-9]+"
109
+
110
+ jobs:
111
+ publish:
112
+ permissions:
113
+ id-token: write
114
+ uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1
115
+ with:
116
+ working-directory: packages/dart_client
117
+ # environment: pub.dev
118
+ ```
119
+
120
+ Choose this pattern when a tag for one package must never authorize publishing a different package.
121
+
122
+ ## Pattern 3: one workflow, multiple package-specific jobs
123
+
124
+ Use this when you want one workflow file but separate jobs per package.
125
+
126
+ That gives you:
127
+
128
+ - one place to manage permissions and branch or tag triggers
129
+ - package-specific working directories
130
+ - package-specific environments
131
+ - package-specific failure visibility
132
+
133
+ Example shape:
134
+
135
+ ```yaml
136
+ jobs:
137
+ publish-crate-a:
138
+ environment: crates-a
139
+ permissions:
140
+ contents: read
141
+ id-token: write
142
+ steps:
143
+ - uses: actions/checkout@v6
144
+ - uses: rust-lang/crates-io-auth-action@v1
145
+ id: auth
146
+ - run: cargo publish --package crate_a
147
+ env:
148
+ CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
149
+
150
+ publish-crate-b:
151
+ environment: crates-b
152
+ permissions:
153
+ contents: read
154
+ id-token: write
155
+ steps:
156
+ - uses: actions/checkout@v6
157
+ - uses: rust-lang/crates-io-auth-action@v1
158
+ id: auth
159
+ - run: cargo publish --package crate_b
160
+ env:
161
+ CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
162
+ ```
163
+
164
+ This pattern is especially useful when multiple packages live in the same ecosystem but should not share the same trusted-publishing enrollment.
165
+
166
+ ## Registry-specific recommendations
167
+
168
+ | Registry | Recommended multi-package pattern | Why |
169
+ | --------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
170
+ | npm | one post-merge `mc publish-readiness` + `mc publish` job when possible | monochange can automate npm trusted-publishing setup on GitHub |
171
+ | crates.io | one job per crate when using external OIDC auth | trusted publishing is enrolled per crate and workflow context matters |
172
+ | jsr | built-in `mc publish-readiness` + `mc publish` is often fine, but keep setup package-specific | registry linking is still manual today |
173
+ | pub.dev | package-specific tags and often one workflow per package | automated publishing is tag-driven and package-specific |
174
+
175
+ ## Keep config, tags, and workflows aligned
176
+
177
+ For each published package, keep these values aligned:
178
+
179
+ - package id in `monochange.toml`
180
+ - registry package name
181
+ - trusted-publishing repository, workflow, and environment values
182
+ - workflow trigger
183
+ - tag pattern, when the registry uses tags
184
+ - working directory, when the registry workflow publishes from a subdirectory
185
+
186
+ If those drift apart, trusted-publishing validation will be confusing even when release planning is correct.
187
+
188
+ ## When to use package-level overrides
189
+
190
+ Use package-level publishing config when one package differs from the ecosystem default.
191
+
192
+ ```toml
193
+ [ecosystems.dart.publish]
194
+ enabled = true
195
+ mode = "external"
196
+ trusted_publishing = true
197
+ registry = "pub.dev"
198
+
199
+ [package.dart_client.publish.trusted_publishing]
200
+ workflow = "publish-dart-client.yml"
201
+ environment = "pub.dev"
202
+
203
+ [package.example_app.publish]
204
+ enabled = false
205
+ ```
206
+
207
+ This is the right move when:
208
+
209
+ - one package publishes from a different workflow file
210
+ - one package needs a protected environment but others do not
211
+ - one package is internal and should not publish publicly
212
+ - one ecosystem default is correct for most packages, but not all of them
213
+
214
+ ## Practical rollout
215
+
216
+ 1. decide which packages are public and which stay unpublished
217
+ 2. choose `builtin` or `external` per ecosystem or package
218
+ 3. register trusted publishing for each package at the registry
219
+ 4. prefer package-specific tags where a registry is tag-authorized
220
+ 5. run `mc publish --dry-run` after registry enrollment changes
221
+ 6. keep the workflow filename and environment stable once a registry record is enrolled
222
+
223
+ ## Common mistakes
224
+
225
+ Avoid these failure modes:
226
+
227
+ - using one broad tag pattern that lets a tag for package A publish package B
228
+ - reusing one trusted-publishing record across packages that actually publish from different workflows
229
+ - changing a workflow filename after registry enrollment without updating the registry record
230
+ - keeping `mode = "builtin"` for packages that really need registry-native external publish steps
231
+ - forgetting that `pub.dev` automated publishing is tag-triggered
232
+
233
+ ## Related references
234
+
235
+ - [trusted-publishing.md](./trusted-publishing.md) — registry-side trusted-publishing setup details
236
+ - [configuration.md](./configuration.md) — publishing config and per-package overrides
237
+ - [reference.md](./reference.md) — broader publishing and release workflow reference
@@ -0,0 +1,18 @@
1
+ # monochange skill deep dives
2
+
3
+ Use these focused guides when the top-level [SKILL.md](../SKILL.md) is not enough context:
4
+
5
+ - [adoption.md](./adoption.md) — setup-depth questions, migration guidance, and recommendation patterns
6
+ - [changesets.md](./changesets.md) — creating, updating, replacing, and removing `.changeset/*.md` files
7
+ - [commands.md](./commands.md) — the built-in `mc` commands, when to run them, and how they fit together
8
+ - [configuration.md](./configuration.md) — creating and evolving `monochange.toml`
9
+ - [linting.md](./linting.md) — `mc check`, `[lints]`, presets, and manifest-focused rule explanations with examples
10
+ - [../examples/readme.md](../examples/readme.md) — condensed scenario examples for quick recommendations
11
+ - [./multi-package-publishing.md](./multi-package-publishing.md) — publishing patterns for repositories that ship multiple public packages
12
+
13
+ Keep [reference.md](./reference.md) open when you want a single high-context document with broader examples and copy-paste snippets.
14
+
15
+ For deeper changeset guidance, also see:
16
+
17
+ - [changeset-guide.md](./changeset-guide.md)
18
+ - [artifact-types.md](./artifact-types.md)