@@ -151,12 +151,32 @@ func resolveModuleConfig(cfg *config.Config, path string) (*config.Config, strin
151151}
152152
153153// runCreateCmd creates a git tag for the current version.
154+ // When --all is used with multiple modules, it iterates all modules and creates
155+ // a tag for each one instead of only tagging the first module.
154156func (tc * TagCommand ) runCreateCmd (ctx context.Context , cmd * cli.Command , cfg * config.Config ) error {
155- path , err := resolveVersionPath (ctx , cmd , cfg )
157+ execCtx , err := clix . GetExecutionContext (ctx , cmd , cfg )
156158 if err != nil {
157159 return err
158160 }
159161
162+ // Multi-module mode: create tags for all modules.
163+ if execCtx .IsMultiModule () && len (execCtx .Modules ) > 1 {
164+ return tc .createTagsForAllModules (ctx , cmd , cfg , execCtx )
165+ }
166+
167+ // Single-module mode (or multi-module with only one selected module).
168+ path := execCtx .Path
169+ if execCtx .IsMultiModule () && len (execCtx .Modules ) == 1 {
170+ mod := execCtx .Modules [0 ]
171+ printer .PrintInfo (fmt .Sprintf ("Using version from module %q (%s)" , mod .Name , mod .RelPath ))
172+ path = mod .Path
173+ }
174+
175+ return tc .createTagForPath (ctx , cmd , cfg , path )
176+ }
177+
178+ // createTagForPath creates a single git tag for the version at the given path.
179+ func (tc * TagCommand ) createTagForPath (ctx context.Context , cmd * cli.Command , cfg * config.Config , path string ) error {
160180 version , err := semver .ReadVersion (path )
161181 if err != nil {
162182 return fmt .Errorf ("failed to read version from %s: %w" , path , err )
@@ -198,6 +218,74 @@ func (tc *TagCommand) runCreateCmd(ctx context.Context, cmd *cli.Command, cfg *c
198218 return nil
199219}
200220
221+ // createTagsForAllModules iterates all modules in the execution context and
222+ // creates a tag for each one. It continues on individual module failure and
223+ // returns a summary error if any modules failed.
224+ func (tc * TagCommand ) createTagsForAllModules (ctx context.Context , cmd * cli.Command , cfg * config.Config , execCtx * clix.ExecutionContext ) error {
225+ var failedModules []string
226+ totalModules := len (execCtx .Modules )
227+
228+ shouldPush := cmd .Bool ("push" )
229+
230+ for _ , mod := range execCtx .Modules {
231+ printer .PrintInfo (fmt .Sprintf ("Processing module %q (%s)" , mod .Name , mod .RelPath ))
232+
233+ version , err := semver .ReadVersion (mod .Path )
234+ if err != nil {
235+ printer .PrintError (fmt .Sprintf (" Failed to read version for module %q: %v" , mod .Name , err ))
236+ failedModules = append (failedModules , mod .Name )
237+ continue
238+ }
239+
240+ effectiveCfg , modulePath := resolveModuleConfig (cfg , mod .Path )
241+ tmConfig := buildTagManagerConfig (effectiveCfg )
242+ prefix := tagmanager .InterpolatePrefix (tmConfig .Prefix , modulePath )
243+ tagName := prefix + version .String ()
244+
245+ exists , err := tc .gitOps .TagExists (ctx , tagName )
246+ if err != nil {
247+ printer .PrintError (fmt .Sprintf (" Failed to check tag existence for module %q: %v" , mod .Name , err ))
248+ failedModules = append (failedModules , mod .Name )
249+ continue
250+ }
251+ if exists {
252+ printer .PrintInfo (fmt .Sprintf (" Tag %s already exists, skipping module %q" , tagName , mod .Name ))
253+ continue
254+ }
255+
256+ message := cmd .String ("message" )
257+ if message == "" {
258+ data := tagmanager .NewTemplateData (version , prefix , modulePath )
259+ message = tagmanager .FormatMessage (tmConfig .MessageTemplate , data )
260+ }
261+
262+ if err := tc .createTag (ctx , tagName , message , tmConfig ); err != nil {
263+ printer .PrintError (fmt .Sprintf (" Failed to create tag for module %q: %v" , mod .Name , err ))
264+ failedModules = append (failedModules , mod .Name )
265+ continue
266+ }
267+
268+ printer .PrintSuccess (fmt .Sprintf (" Created tag %s for module %q" , tagName , mod .Name ))
269+
270+ pushThis := shouldPush || tmConfig .Push
271+ if pushThis {
272+ if err := tc .gitOps .PushTag (ctx , tagName ); err != nil {
273+ printer .PrintError (fmt .Sprintf (" Failed to push tag %s for module %q: %v" , tagName , mod .Name , err ))
274+ failedModules = append (failedModules , mod .Name )
275+ continue
276+ }
277+ printer .PrintSuccess (fmt .Sprintf (" Pushed tag %s to remote" , tagName ))
278+ }
279+ }
280+
281+ if len (failedModules ) > 0 {
282+ return fmt .Errorf ("%d of %d module(s) failed tag creation: %s" ,
283+ len (failedModules ), totalModules , strings .Join (failedModules , ", " ))
284+ }
285+
286+ return nil
287+ }
288+
201289// createTag creates a tag based on the configuration.
202290func (tc * TagCommand ) createTag (ctx context.Context , tagName , message string , cfg * tagmanager.Config ) error {
203291 switch {
0 commit comments