Map CLI profiles to selected modules
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
||||
"gitea.maximumdirect.net/eric/ReleaseKit"
|
||||
"gitea.maximumdirect.net/eric/ReleaseKit/buildinfo"
|
||||
"gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit/internal/cli"
|
||||
"gitea.maximumdirect.net/eric/ReleaseKit/internal/releaseidentity"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -42,11 +43,15 @@ func run(ctx context.Context, args []string, stdout, stderr io.Writer) int {
|
||||
}
|
||||
request := candidateRequest(invocation, settings, stderr)
|
||||
if invocation.Command == cli.PublishAction {
|
||||
if err := checkExpectedModule(invocation.Repository, invocation.ExpectedModule, settings.ModuleDir); err != nil {
|
||||
fmt.Fprintf(stderr, "profile module selection: %v\n", err)
|
||||
return 2
|
||||
}
|
||||
request.ExpectedPushURL = settings.ExpectedPushURL
|
||||
fmt.Fprintf(stderr, "validating and publishing %s\n", invocation.Version)
|
||||
fmt.Fprintf(stderr, "validating and publishing module %s version %s\n", selectedModuleLabel(settings.ModuleDir), invocation.Version)
|
||||
result, err := releasekit.Publish(ctx, request)
|
||||
if err != nil {
|
||||
fmt.Fprintf(stderr, "publication state=%s phase=%s version=%s commit=%s tag-object=%s endpoint=%q: %s\n", result.State, result.Phase, result.Version, result.CandidateCommit, result.TagObject, result.Endpoint, candidateFailureText(err))
|
||||
fmt.Fprintf(stderr, "publication state=%s phase=%s module=%s module-dir=%s version=%s tag=%s commit=%s tag-object=%s endpoint=%q: %s\n", result.State, result.Phase, result.ModulePath, result.ModuleDir, result.Version, result.Tag, result.CandidateCommit, result.TagObject, result.Endpoint, candidateFailureText(err))
|
||||
if errors.Is(err, releasekit.ErrInvalidVersion) {
|
||||
return 2
|
||||
}
|
||||
@@ -55,18 +60,18 @@ func run(ctx context.Context, args []string, stdout, stderr io.Writer) int {
|
||||
}
|
||||
return 1
|
||||
}
|
||||
fmt.Fprintf(stdout, "published %s at %s (tag object %s)\n", result.Version, result.CandidateCommit, result.TagObject)
|
||||
fmt.Fprintf(stdout, "published %s as %s at %s (tag object %s)\n", result.Version, result.Tag, result.CandidateCommit, result.TagObject)
|
||||
return 0
|
||||
}
|
||||
candidate, err := releasekit.Check(ctx, request)
|
||||
if err != nil {
|
||||
fmt.Fprintf(stderr, "check failed: %s\n", candidateFailureText(err))
|
||||
fmt.Fprintf(stderr, "check failed module=%s module-dir=%s version=%s tag=%s commit=%s: %s\n", candidate.ModulePath, candidate.ModuleDir, candidate.Version, candidate.Tag, candidate.Commit, candidateFailureText(err))
|
||||
if errors.Is(err, releasekit.ErrInvalidVersion) {
|
||||
return 2
|
||||
}
|
||||
return 1
|
||||
}
|
||||
fmt.Fprintf(stdout, "local candidate %s at %s is valid\n", candidate.Version, candidate.Commit)
|
||||
fmt.Fprintf(stdout, "local candidate module %s version %s tag %s at %s is valid\n", candidate.ModulePath, candidate.Version, candidate.Tag, candidate.Commit)
|
||||
return 0
|
||||
case cli.BuildAction:
|
||||
settings, err := cli.LoadSettings(invocation.Repository, invocation.ConfigPath)
|
||||
@@ -80,6 +85,7 @@ func run(ctx context.Context, args []string, stdout, stderr io.Writer) int {
|
||||
}
|
||||
result, err := releasekit.Build(ctx, releasekit.BuildRequest{
|
||||
RepositoryDir: invocation.Repository,
|
||||
ModuleDir: settings.ModuleDir,
|
||||
Version: invocation.Version,
|
||||
Spec: *configuredBuildSpec(settings.Build),
|
||||
OutputDir: invocation.OutputDir,
|
||||
@@ -92,7 +98,7 @@ func run(ctx context.Context, args []string, stdout, stderr io.Writer) int {
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintf(stderr, "build failed at %s: %v\n", result.CandidateCommit, err)
|
||||
fmt.Fprintf(stderr, "build failed module=%s module-dir=%s version=%s tag=%s commit=%s: %v\n", result.ModulePath, result.ModuleDir, result.Version, result.Tag, result.CandidateCommit, err)
|
||||
for _, artifact := range result.Artifacts {
|
||||
fmt.Fprintf(stderr, "built %s %s\n", artifact.Filename, artifact.SHA256)
|
||||
}
|
||||
@@ -102,7 +108,7 @@ func run(ctx context.Context, args []string, stdout, stderr io.Writer) int {
|
||||
return 1
|
||||
}
|
||||
if len(result.Targets) == 0 {
|
||||
fmt.Fprintf(stdout, "no build targets selected for %s at %s\n", result.Version, result.CandidateCommit)
|
||||
fmt.Fprintf(stdout, "no build targets selected for module %s version %s tag %s at %s\n", result.ModulePath, result.Version, result.Tag, result.CandidateCommit)
|
||||
return 0
|
||||
}
|
||||
receipt := receiptFromBuild(result)
|
||||
@@ -120,7 +126,7 @@ func run(ctx context.Context, args []string, stdout, stderr io.Writer) int {
|
||||
fmt.Fprintln(stderr, "build receipt does not match the selected source and build settings")
|
||||
return 1
|
||||
}
|
||||
fmt.Fprintf(stdout, "built %d artifacts for %s at %s with %s\n", len(result.Artifacts), result.Version, result.CandidateCommit, result.Compiler)
|
||||
fmt.Fprintf(stdout, "built %d artifacts for module %s version %s tag %s at %s with %s\n", len(result.Artifacts), result.ModulePath, result.Version, result.Tag, result.CandidateCommit, result.Compiler)
|
||||
for _, artifact := range result.Artifacts {
|
||||
fmt.Fprintf(stdout, "%s %s\n", artifact.Filename, artifact.SHA256)
|
||||
}
|
||||
@@ -137,6 +143,7 @@ func run(ctx context.Context, args []string, stdout, stderr io.Writer) int {
|
||||
func candidateRequest(invocation cli.Invocation, settings cli.Settings, output io.Writer) releasekit.ReleaseRequest {
|
||||
request := releasekit.ReleaseRequest{
|
||||
RepositoryDir: invocation.Repository,
|
||||
ModuleDir: settings.ModuleDir,
|
||||
Product: settings.Product,
|
||||
Version: invocation.Version,
|
||||
Remote: settings.Remote,
|
||||
@@ -147,9 +154,13 @@ func candidateRequest(invocation cli.Invocation, settings cli.Settings, output i
|
||||
if len(settings.Checks) != 0 {
|
||||
checks := settings.Checks
|
||||
request.AdditionalChecks = func(ctx context.Context, candidate releasekit.Candidate) error {
|
||||
return cli.RunChecks(ctx, candidate.RepositoryDir, checks, map[string]string{
|
||||
"RELEASEKIT_VERSION": candidate.Version,
|
||||
"RELEASEKIT_CANDIDATE": candidate.Commit,
|
||||
return cli.RunChecks(ctx, candidate.ModuleDir, checks, map[string]string{
|
||||
"RELEASEKIT_VERSION": candidate.Version,
|
||||
"RELEASEKIT_CANDIDATE": candidate.Commit,
|
||||
"RELEASEKIT_REPOSITORY_DIR": candidate.RepositoryDir,
|
||||
"RELEASEKIT_MODULE_DIR": candidate.ModuleDir,
|
||||
"RELEASEKIT_MODULE_PATH": candidate.ModulePath,
|
||||
"RELEASEKIT_TAG": candidate.Tag,
|
||||
}, output, output)
|
||||
}
|
||||
}
|
||||
@@ -161,7 +172,8 @@ func validationSpec(settings *cli.ValidationSettings) releasekit.ValidationSpec
|
||||
return releasekit.ValidationSpec{}
|
||||
}
|
||||
result := releasekit.ValidationSpec{
|
||||
GoFormat: settings.GoFormat,
|
||||
SharedFiles: copyStringsPreservingEmpty(settings.SharedFiles),
|
||||
GoFormat: settings.GoFormat,
|
||||
ModuleDistribution: releasekit.ModuleDistributionValidationSpec{
|
||||
WorkspaceFiles: settings.ModuleDistribution.WorkspaceFiles,
|
||||
LocalReplacements: settings.ModuleDistribution.LocalReplacements,
|
||||
@@ -199,6 +211,38 @@ func candidateFailureText(err error) string {
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
func checkExpectedModule(repositoryDir, expectedModule, profileModule string) error {
|
||||
if expectedModule == "" {
|
||||
return nil
|
||||
}
|
||||
expected, err := releaseidentity.ResolveSelection(repositoryDir, expectedModule)
|
||||
if err != nil {
|
||||
return fmt.Errorf("normalize expected module %q: %w", expectedModule, err)
|
||||
}
|
||||
selected, err := releaseidentity.ResolveSelection(repositoryDir, profileModule)
|
||||
if err != nil {
|
||||
return fmt.Errorf("normalize profile module %q: %w", profileModule, err)
|
||||
}
|
||||
if expected.ModuleSubdir != selected.ModuleSubdir {
|
||||
return fmt.Errorf("expected module %q resolves to %q, but the profile selects %q", expectedModule, expected.ModuleSubdir, selected.ModuleSubdir)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func selectedModuleLabel(moduleDir string) string {
|
||||
if moduleDir == "" {
|
||||
return "."
|
||||
}
|
||||
return moduleDir
|
||||
}
|
||||
|
||||
func copyStringsPreservingEmpty(values []string) []string {
|
||||
if values == nil {
|
||||
return nil
|
||||
}
|
||||
return append([]string{}, values...)
|
||||
}
|
||||
|
||||
func runDelivery(ctx context.Context, invocation cli.Invocation, stdout, stderr io.Writer) int {
|
||||
settings, err := cli.LoadSettings(invocation.Repository, invocation.ConfigPath)
|
||||
if err != nil {
|
||||
@@ -233,7 +277,10 @@ func runCIDelivery(ctx context.Context, invocation cli.Invocation, stdout, stder
|
||||
return status
|
||||
}
|
||||
if settings.Build != nil && len(settings.Build.Targets) != 0 {
|
||||
if err := releasekit.PrepareBuildDependencies(ctx, invocation.Repository); err != nil {
|
||||
if err := releasekit.PrepareBuildDependencies(ctx, releasekit.DependencyPreparationRequest{
|
||||
RepositoryDir: invocation.Repository,
|
||||
ModuleDir: settings.ModuleDir,
|
||||
}); err != nil {
|
||||
fmt.Fprintf(stderr, "prepare build dependencies: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
@@ -301,6 +348,7 @@ func deliverWithDestination(ctx context.Context, invocation cli.Invocation, sett
|
||||
|
||||
result, err := releasekit.Deliver(ctx, releasekit.DeliveryRequest{
|
||||
RepositoryDir: invocation.Repository,
|
||||
ModuleDir: settings.ModuleDir,
|
||||
Product: settings.Product,
|
||||
Version: invocation.Version,
|
||||
Destination: destination,
|
||||
@@ -309,7 +357,7 @@ func deliverWithDestination(ctx context.Context, invocation cli.Invocation, sett
|
||||
Output: stderr,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Fprintf(stderr, "delivery state=%s version=%s commit=%s url=%s: %v\n", result.State, result.Version, result.CandidateCommit, result.ReleaseURL, err)
|
||||
fmt.Fprintf(stderr, "delivery state=%s module=%s module-dir=%s version=%s tag=%s commit=%s url=%s: %v\n", result.State, result.ModulePath, result.ModuleDir, result.Version, result.Tag, result.CandidateCommit, result.ReleaseURL, err)
|
||||
writeDeliveryAssets(stderr, result)
|
||||
writeDeliveryRecovery(stderr, result)
|
||||
if errors.Is(err, releasekit.ErrInvalidVersion) {
|
||||
@@ -320,7 +368,7 @@ func deliverWithDestination(ctx context.Context, invocation cli.Invocation, sett
|
||||
}
|
||||
return 1
|
||||
}
|
||||
fmt.Fprintf(stdout, "delivered %s at %s (state %s)\n", result.Version, result.CandidateCommit, result.State)
|
||||
fmt.Fprintf(stdout, "delivered module %s version %s tag %s at %s (state %s)\n", result.ModulePath, result.Version, result.Tag, result.CandidateCommit, result.State)
|
||||
if result.ReleaseURL != "" {
|
||||
fmt.Fprintf(stdout, "release: %s\n", result.ReleaseURL)
|
||||
}
|
||||
@@ -342,13 +390,13 @@ func writeDeliveryAssets(output io.Writer, result releasekit.DeliveryResult) {
|
||||
func writeDeliveryRecovery(output io.Writer, result releasekit.DeliveryResult) {
|
||||
switch result.State {
|
||||
case releasekit.DeliveryNotAttempted:
|
||||
fmt.Fprintln(output, "recovery: fix the local or preflight failure before retrying; no remote write was attempted")
|
||||
fmt.Fprintf(output, "recovery: fix the local or preflight failure for module %s version %s tag %s before retrying; no remote write was attempted\n", result.ModulePath, result.Version, result.Tag)
|
||||
case releasekit.DeliveryPartial:
|
||||
fmt.Fprintln(output, "recovery: fix the reported cause, then retry this version")
|
||||
fmt.Fprintf(output, "recovery: fix the reported cause, then retry module %s version %s tag %s\n", result.ModulePath, result.Version, result.Tag)
|
||||
case releasekit.DeliveryConflict:
|
||||
fmt.Fprintln(output, "recovery: investigate conflicting hosted content; use a new version if the source or published contents need correction")
|
||||
fmt.Fprintf(output, "recovery: investigate conflicting hosted content for module %s version %s tag %s; use a new version if the source or published contents need correction\n", result.ModulePath, result.Version, result.Tag)
|
||||
case releasekit.DeliveryUnknown:
|
||||
fmt.Fprintln(output, "recovery: resolve the remote state before retrying")
|
||||
fmt.Fprintf(output, "recovery: resolve the remote state for module %s version %s tag %s before retrying\n", result.ModulePath, result.Version, result.Tag)
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user