@@ -23,7 +23,7 @@ import (
2323 "github.com/operatorstack/boatstack/boatstack/internal/softwaredelivery/protocol"
2424)
2525
26- const flowCompilerVersion = "control-program.compiler.6 "
26+ const flowCompilerVersion = "control-program.compiler.7 "
2727
2828type flowCommandOptions struct {
2929 repository string
@@ -107,7 +107,7 @@ func compileFlow(ctx context.Context, options flowCommandOptions) error {
107107 if err != nil {
108108 return err
109109 }
110- configPath , configRaw , _ , projections , err := loadProjectProjectionSelection (options .repository )
110+ configPath , configRaw , _ , config , projections , err := loadProjectProjectionSelection (options .repository )
111111 if err != nil {
112112 return err
113113 }
@@ -143,6 +143,9 @@ func compileFlow(ctx context.Context, options flowCommandOptions) error {
143143 if err := validateCompiledFlow (ctx , options .repository , compiled , resolver ); err != nil {
144144 return err
145145 }
146+ if err := validateProgramHumanIdentity (compiled , config ); err != nil {
147+ return err
148+ }
146149 artifactPath , err := resolveArtifactPath (options .repository , options .artifact , compiled .Document .Program .ID )
147150 if err != nil {
148151 return err
@@ -623,32 +626,50 @@ func renderFlowResult(status, artifactPath string, artifact controlprogram.Artif
623626 })
624627}
625628
626- func loadProjectProjectionSelection (repository string ) (string , []byte , string , []hostprojection.ID , error ) {
629+ func loadProjectProjectionSelection (repository string ) (string , []byte , string , protocol. ProjectConfig , []hostprojection.ID , error ) {
627630 path , err := exactRepositoryPath (repository , filepath .Join (".boatstack" , "project.json" ))
628631 if err != nil {
629- return "" , nil , "" , nil , err
632+ return "" , nil , "" , protocol. ProjectConfig {}, nil , err
630633 }
631634 raw , err := os .ReadFile (path )
632635 if err != nil {
633- return "" , nil , "" , nil , fmt .Errorf ("PROJECT_PROJECTIONS_REQUIRED: read project configuration: %w" , err )
636+ return "" , nil , "" , protocol. ProjectConfig {}, nil , fmt .Errorf ("PROJECT_PROJECTIONS_REQUIRED: read project configuration: %w" , err )
634637 }
635638 config , fingerprint , err := protocol .ProjectConfigFingerprint (raw )
636639 if err != nil {
637- return "" , nil , "" , nil , err
640+ return "" , nil , "" , protocol. ProjectConfig {}, nil , err
638641 }
639642 projections , err := config .ProjectionIDs ()
640643 if err != nil {
641- return "" , nil , "" , nil , err
644+ return "" , nil , "" , protocol. ProjectConfig {}, nil , err
642645 }
643- return path , raw , fingerprint , projections , nil
646+ return path , raw , fingerprint , config , projections , nil
644647}
645648
646649func checkArtifactForCurrentProject (repository string , artifact controlprogram.Artifact , resolver controlprogram.BindingResolver ) (controlprogram.Compiled , error ) {
647- _ , _ , _ , projections , err := loadProjectProjectionSelection (repository )
650+ _ , _ , _ , config , projections , err := loadProjectProjectionSelection (repository )
651+ if err != nil {
652+ return controlprogram.Compiled {}, err
653+ }
654+ compiled , err := controlprogram .CheckArtifact (repository , artifact , flowCompilerVersion , resolver , projections , generateSoftwareFlowProjections )
648655 if err != nil {
649656 return controlprogram.Compiled {}, err
650657 }
651- return controlprogram .CheckArtifact (repository , artifact , flowCompilerVersion , resolver , projections , generateSoftwareFlowProjections )
658+ if err := validateProgramHumanIdentity (compiled , config ); err != nil {
659+ return controlprogram.Compiled {}, err
660+ }
661+ return compiled , nil
662+ }
663+
664+ func validateProgramHumanIdentity (compiled controlprogram.Compiled , config protocol.ProjectConfig ) error {
665+ role := compiled .Document .Program .HumanIdentity
666+ if role == "" {
667+ return nil
668+ }
669+ if _ , ok := config .Identity .Roles [role ]; ! ok {
670+ return fmt .Errorf ("CONTROL_PROGRAM_HUMAN_IDENTITY_UNBOUND: program %q requires identity role %q, but the current project configuration does not define it" , compiled .Document .Program .ID , role )
671+ }
672+ return nil
652673}
653674
654675func entryIDs (entries []controlprogram.Entry ) []string {
0 commit comments