Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,17 @@ type resourceTypeConfig struct {
Kinds []string
}

type appServiceRuntime struct {
Stack string `json:"stack,omitempty"`
Version string `json:"version,omitempty"`
}

var (
appResourceMap = map[string]resourceTypeConfig{
"host.webapp": {
"host.appservice": {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could delete this line and move it under createQuestions just like https://github.com/Azure/azure-dev/pull/4997/files

ResourceType: "Microsoft.Web/sites",
ResourceTypeDisplayName: "Web App",
Kinds: []string{"app"},
Kinds: []string{"app", "app,linux"},
},
"host.containerapp": {
ResourceType: "Microsoft.App/containerApps",
Expand All @@ -77,6 +82,21 @@ var (
},
}

appServiceStackMap = map[string]appServiceRuntime{
"python": {
Stack: "python",
Version: "3.13",
},
"js": {
Stack: "node",
Version: "22-lts",
},
"ts": {
Stack: "node",
Version: "22-lts",
},
}

defaultModelMap = map[string]string{
"chatCompletion": "gpt-4o",
"embeddings": "text-embedding-3-small",
Expand Down Expand Up @@ -336,6 +356,14 @@ func (a *startAction) Run(ctx context.Context, args []string) error {
"port": 8080,
}

if appType == "host.appservice" {
runtime, ok := appServiceStackMap[languageType]
if !ok {
return fmt.Errorf("unsupported language type: %s", languageType)
}
appConfig["runtime"] = runtime
}

appConfigJson, err := json.Marshal(appConfig)
if err != nil {
return fmt.Errorf("failed to marshal app config: %w", err)
Expand Down Expand Up @@ -1188,14 +1216,15 @@ func (a *startAction) createQuestions(ctx context.Context) (map[string]qna.Quest
Choices: []qna.Choice{
{Label: "Choose for me", Value: "choose-app"},
{Label: "Container App", Value: "host.containerapp"},
{Label: "App Service (Coming Soon)", Value: "host.webapp"},
{Label: "App Service", Value: "host.appservice"},
{Label: "Function App (Coming Soon)", Value: "host.functionapp"},
{Label: "Static Web App (Coming Soon)", Value: "host.staticwebapp"},
{Label: "Other", Value: "other-app"},
},
},
Branches: map[any][]qna.QuestionReference{
"host.containerapp": {{Key: "choose-app-resource"}},
"host.appservice": {{Key: "choose-app-resource"}},
},
Next: []qna.QuestionReference{
{Key: "choose-app-language"},
Expand All @@ -1219,7 +1248,6 @@ func (a *startAction) createQuestions(ctx context.Context) (map[string]qna.Quest
},
AfterAsk: func(ctx context.Context, q *qna.Question, value any) error {
selectedLanguage := value.(string)

// Find the default language for the selected interaction type if available.
if selectedLanguage == "default" {
interactionType := q.State["interactionType"].(string)
Expand All @@ -1231,6 +1259,22 @@ func (a *startAction) createQuestions(ctx context.Context) (map[string]qna.Quest
}
}

// App Service in composability supports a limited set of runtimes, so re-prompt
// if the user selects an unsupported language
isAppService := len(a.scenarioData.AppHostTypes) > 0 &&
a.scenarioData.AppHostTypes[len(a.scenarioData.AppHostTypes)-1] == "host.appservice"
if isAppService {
if _, ok := appServiceStackMap[selectedLanguage]; !ok {
q.Branches = map[any][]qna.QuestionReference{
selectedLanguage: {{Key: "choose-app-language"}},
}
fmt.Println(output.WithErrorFormat(
"%s is not a supported language for App Service. Please choose another language.",
selectedLanguage))
return nil
}
}

a.scenarioData.AppLanguages = append(a.scenarioData.AppLanguages, selectedLanguage)
return nil
},
Expand Down
9 changes: 9 additions & 0 deletions cli/azd/internal/grpcserver/compose_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,15 @@ func (c *composeService) ListResources(
// In the future we will converge this into a common component.
func createResourceProps(resourceType string, config []byte) (any, error) {
switch project.ResourceType(resourceType) {
case project.ResourceTypeHostAppService:
props := project.AppServiceProps{}
if len(config) == 0 {
return props, nil
}
if err := json.Unmarshal(config, &props); err != nil {
return nil, err
}
return props, nil
case project.ResourceTypeHostContainerApp:
props := project.ContainerAppProps{}
if len(config) == 0 {
Expand Down