feat(cli): make core ci dry-run by default

- Default behavior is now dry-run (safe)
- Add --were-go-for-launch flag to actually publish
- Update help text to make this clear
- Update SKILL.md documentation

Now you must explicitly opt-in to publishing:
  core ci                        # Preview (dry-run)
  core ci --were-go-for-launch   # Actually publish

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Snider 2026-01-29 12:50:41 +00:00
parent 331032cd57
commit f887c4b049
2 changed files with 24 additions and 15 deletions

View file

@ -26,7 +26,8 @@ The `core` command provides a unified interface for Go/Wails development, multi-
| Build project | `core build` | Auto-detects project type |
| Build for targets | `core build --targets linux/amd64,darwin/arm64` | Cross-compile |
| Build SDK | `core build sdk` | Generate API clients from OpenAPI |
| Publish release | `core ci` | Publish pre-built artifacts |
| Preview release | `core ci` | Dry-run publish (safe default) |
| Publish release | `core ci --were-go-for-launch` | Actually publish artifacts |
| Check environment | `core doctor` | Verify tools installed |
| Multi-repo status | `core dev health` | Quick summary across repos |
| Multi-repo workflow | `core dev work` | Status + commit + push |
@ -76,14 +77,16 @@ Build and publish are **separated** to prevent accidental releases:
core build
core build sdk
# Step 2: Publish to configured targets (requires pre-built artifacts)
core ci # Publish what's in dist/
core ci --dry-run # Preview what would be published
core ci --draft # Create as draft release
core ci --prerelease # Mark as prerelease
# Step 2: Preview publish (default is dry-run)
core ci # Dry-run: shows what would be published
# Step 3: Actually publish (explicit flag required)
core ci --were-go-for-launch # Actually publish to targets
core ci --were-go-for-launch --draft # Publish as draft
core ci --were-go-for-launch --prerelease # Publish as prerelease
```
**Why separate?** Running `core ci` without first building will fail safely - no accidental publishes.
**Why safe by default?** `core ci` always does a dry-run unless you explicitly say `--were-go-for-launch`.
```bash
# Release workflow utilities
@ -521,7 +524,8 @@ Go project?
└── Tidy modules: core go mod tidy
└── Build: core build [--targets <os/arch>]
└── Build SDK: core build sdk
└── Publish: core ci [--dry-run]
└── Preview publish: core ci
└── Publish: core ci --were-go-for-launch
PHP/Laravel project?
└── Start dev: core php dev [--https]

View file

@ -36,23 +36,26 @@ var (
// AddCIReleaseCommand adds the release command and its subcommands.
func AddCIReleaseCommand(app *clir.Cli) {
releaseCmd := app.NewSubCommand("ci", "Build and publish releases")
releaseCmd.LongDescription("Builds release artifacts, generates changelog, and publishes to GitHub.\n" +
"Configuration can be provided via .core/release.yaml or command-line flags.")
releaseCmd := app.NewSubCommand("ci", "Publish releases (dry-run by default)")
releaseCmd.LongDescription("Publishes pre-built artifacts from dist/ to configured targets.\n" +
"Run 'core build' first to create artifacts.\n\n" +
"SAFE BY DEFAULT: Runs in dry-run mode unless --were-go-for-launch is specified.\n\n" +
"Configuration: .core/release.yaml")
// Flags for the main release command
var dryRun bool
var goForLaunch bool
var version string
var draft bool
var prerelease bool
releaseCmd.BoolFlag("dry-run", "Preview release without publishing", &dryRun)
releaseCmd.BoolFlag("were-go-for-launch", "Actually publish (default is dry-run for safety)", &goForLaunch)
releaseCmd.StringFlag("version", "Version to release (e.g., v1.2.3)", &version)
releaseCmd.BoolFlag("draft", "Create release as a draft", &draft)
releaseCmd.BoolFlag("prerelease", "Mark release as a prerelease", &prerelease)
// Default action for `core ci` - publish only (expects artifacts in dist/)
// Default action for `core ci` - dry-run by default for safety
releaseCmd.Action(func() error {
dryRun := !goForLaunch
return runCIPublish(dryRun, version, draft, prerelease)
})
@ -118,7 +121,9 @@ func runCIPublish(dryRun bool, version string, draft, prerelease bool) error {
// Print header
fmt.Printf("%s Publishing release\n", releaseHeaderStyle.Render("CI:"))
if dryRun {
fmt.Printf(" %s\n", releaseDimStyle.Render("(dry-run mode)"))
fmt.Printf(" %s\n", releaseDimStyle.Render("(dry-run) use --were-go-for-launch to publish"))
} else {
fmt.Printf(" %s\n", releaseSuccessStyle.Render("🚀 GO FOR LAUNCH"))
}
fmt.Println()