change how config is applied

This commit is contained in:
Jake Runzer
2025-02-23 21:23:42 -05:00
parent c39a419887
commit 10f5ddd58f
15 changed files with 280 additions and 250 deletions
+23 -19
View File
@@ -6,27 +6,30 @@ import (
"github.com/railwayapp/railpack/core/utils"
)
type DeployConfig struct {
AptPackages []string `json:"aptPackages,omitempty" jsonschema:"description=List of apt packages to include at runtime"`
Inputs []plan.Input `json:"inputs,omitempty" jsonschema:"description=The inputs for the deploy step"`
StartCmd string `json:"startCommand,omitempty" jsonschema:"description=The command to run in the container"`
Variables map[string]string `json:"variables,omitempty" jsonschema:"description=The variables available to this step. The key is the name of the variable that is referenced in a variable command"`
Paths []string `json:"paths,omitempty" jsonschema:"description=The paths to prepend to the $PATH environment variable"`
}
type Config struct {
// List of providers to use
Providers *[]string `json:"providers,omitempty" jsonschema:"description=List of providers to use"`
Providers []string `json:"providers" jsonschema:"description=List of providers to use"`
BuildAptPackages []string `json:"buildAptPackages,omitempty" jsonschema:"description=List of apt packages to install during the build step"`
Steps map[string]*plan.Step `json:"steps,omitempty" jsonschema:"description=Map of step names to step definitions"`
Deploy *DeployConfig `json:"deploy,omitempty" jsonschema:"description=Deploy configuration"`
Packages map[string]string `json:"packages,omitempty" jsonschema:"description=Map of package name to package version"`
Caches map[string]*plan.Cache `json:"caches,omitempty" jsonschema:"description=Map of cache name to cache definitions. The cache key can be referenced in an exec command"`
Secrets []string `json:"secrets,omitempty" jsonschema:"description=Secrets that should be made available to commands that have useSecrets set to true"`
}
// Map of step names to step definitions
Steps map[string]*plan.Step `json:"steps,omitempty" jsonschema:"description=Map of step names to step definitions"`
// Deploy configuration
Deploy plan.Deploy `json:"deploy,omitempty" jsonschema:"description=Deploy configuration"`
// Map of package name to package version
Packages map[string]string `json:"packages,omitempty" jsonschema:"description=Map of package name to package version"`
// List of apt packages to install
AptPackages []string `json:"aptPackages,omitempty" jsonschema:"description=List of apt packages to install"`
// Map of cache name to cache definitions. The cache key can be referenced in an exec command.
Caches map[string]*plan.Cache `json:"caches,omitempty" jsonschema:"description=Map of cache name to cache definitions. The cache key can be referenced in an exec command"`
// Secrets that should be made available to commands that have useSecrets set to true
Secrets []string `json:"secrets,omitempty" jsonschema:"description=Secrets that should be made available to commands that have useSecrets set to true"`
func EmptyDeployConfig() *DeployConfig {
return &DeployConfig{
AptPackages: []string{},
StartCmd: "",
Variables: make(map[string]string),
}
}
func EmptyConfig() *Config {
@@ -34,6 +37,7 @@ func EmptyConfig() *Config {
Steps: make(map[string]*plan.Step),
Packages: make(map[string]string),
Caches: make(map[string]*plan.Cache),
Deploy: EmptyDeployConfig(),
}
}
+18 -15
View File
@@ -1,6 +1,7 @@
package core
import (
"encoding/json"
"fmt"
"strings"
@@ -33,7 +34,13 @@ type BuildResult struct {
}
func GenerateBuildPlan(app *app.App, env *app.Environment, options *GenerateBuildPlanOptions) (*BuildResult, error) {
ctx, err := generate.NewGenerateContext(app, env)
// Get the full user config based on file config, env config, and options
config, err := GetConfig(app, env, options)
if err != nil {
return nil, err
}
ctx, err := generate.NewGenerateContext(app, env, config)
if err != nil {
return nil, err
}
@@ -45,12 +52,6 @@ func GenerateBuildPlan(app *app.App, env *app.Environment, options *GenerateBuil
}
}
// Get the full user config based on file config, env config, and options
config, err := GetConfig(app, env, options)
if err != nil {
return nil, err
}
// Figure out what providers to use
providersToUse, detectedProviderNames := getProviders(ctx, config)
providerNames := make([]string, len(providersToUse))
@@ -82,11 +83,6 @@ func GenerateBuildPlan(app *app.App, env *app.Environment, options *GenerateBuil
return nil, fmt.Errorf("failed to run procfile provider: %w", err)
}
// Update the context with the config
if err := ctx.ApplyConfig(config); err != nil {
return nil, fmt.Errorf("failed to apply config: %w", err)
}
buildPlan, resolvedPackages, err := ctx.Generate()
if err != nil {
return nil, fmt.Errorf("failed to generate build plan: %w", err)
@@ -173,8 +169,12 @@ func GenerateConfigFromEnvironment(app *app.App, env *app.Environment) *config.C
}
}
if envAptPackages, _ := env.GetConfigVariable("APT_PACKAGES"); envAptPackages != "" {
config.AptPackages = strings.Split(envAptPackages, " ")
if envAptPackages, _ := env.GetConfigVariable("BUILD_APT_PACKAGES"); envAptPackages != "" {
config.BuildAptPackages = strings.Split(envAptPackages, " ")
}
if envAptPackages, _ := env.GetConfigVariable("DEPLOY_APT_PACKAGES"); envAptPackages != "" {
config.Deploy.AptPackages = strings.Split(envAptPackages, " ")
}
for name := range env.Variables {
@@ -213,6 +213,9 @@ func getProviders(ctx *generate.GenerateContext, config *config.Config) ([]provi
allProviders := providers.GetLanguageProviders()
detectedProviders := []string{}
configJson, _ := json.MarshalIndent(config, "", " ")
fmt.Printf("Config: %s\n", string(configJson))
// Even if there are providers manually specified, we want to detect to see what type of app this is
for _, provider := range allProviders {
matched, err := provider.Detect(ctx)
@@ -238,7 +241,7 @@ func getProviders(ctx *generate.GenerateContext, config *config.Config) ([]provi
}
if config.Providers != nil {
for _, providerName := range *config.Providers {
for _, providerName := range config.Providers {
provider := providers.GetProvider(providerName)
if provider == nil {
log.Warnf("Provider `%s` not found", providerName)
+112 -114
View File
@@ -27,8 +27,9 @@ type StepBuilder interface {
}
type GenerateContext struct {
App *a.App
Env *a.Environment
App *a.App
Env *a.Environment
Config *config.Config
BaseImage string
Steps []StepBuilder
@@ -39,14 +40,12 @@ type GenerateContext struct {
SubContexts []string
Metadata *Metadata
Resolver *resolver.Resolver
miseStepBuilder *MiseStepBuilder
Metadata *Metadata
Resolver *resolver.Resolver
MiseStepBuilder *MiseStepBuilder
}
func NewGenerateContext(app *a.App, env *a.Environment) (*GenerateContext, error) {
func NewGenerateContext(app *a.App, env *a.Environment, config *config.Config) (*GenerateContext, error) {
resolver, err := resolver.NewResolver(mise.InstallDir)
if err != nil {
return nil, err
@@ -55,6 +54,7 @@ func NewGenerateContext(app *a.App, env *a.Environment) (*GenerateContext, error
return &GenerateContext{
App: app,
Env: env,
Config: config,
Steps: make([]StepBuilder, 0),
Deploy: NewDeployBuilder(),
Caches: NewCacheContext(),
@@ -65,10 +65,10 @@ func NewGenerateContext(app *a.App, env *a.Environment) (*GenerateContext, error
}
func (c *GenerateContext) GetMiseStepBuilder() *MiseStepBuilder {
if c.miseStepBuilder == nil {
c.miseStepBuilder = c.newMiseStepBuilder()
if c.MiseStepBuilder == nil {
c.MiseStepBuilder = c.newMiseStepBuilder()
}
return c.miseStepBuilder
return c.MiseStepBuilder
}
func (c *GenerateContext) EnterSubContext(subContext string) *GenerateContext {
@@ -104,13 +104,23 @@ func (c *GenerateContext) ResolvePackages() (map[string]*resolver.ResolvedPackag
// Generate a build plan from the context
func (c *GenerateContext) Generate() (*plan.BuildPlan, map[string]*resolver.ResolvedPackage, error) {
// Add all packages from the config to the mise step
miseStep := c.GetMiseStepBuilder()
for _, pkg := range slices.Sorted(maps.Keys(c.Config.Packages)) {
version := c.Config.Packages[pkg]
pkgRef := miseStep.Default(pkg, version)
miseStep.Version(pkgRef, version, "custom config")
}
c.applyConfig()
// Resolve all package versions into a fully qualified and valid version
resolvedPackages, err := c.ResolvePackages()
if err != nil {
return nil, nil, fmt.Errorf("failed to resolve packages: %w", err)
}
// Generate the plan based on the context and resolved packages
// Create the actual build plan
buildPlan := plan.NewBuildPlan()
buildStepOptions := &BuildStepOptions{
@@ -130,115 +140,27 @@ func (c *GenerateContext) Generate() (*plan.BuildPlan, map[string]*resolver.Reso
buildPlan.Caches = c.Caches.Caches
buildPlan.Secrets = utils.RemoveDuplicates(c.Secrets)
buildPlan.Deploy = *c.Deploy.Build()
buildPlan.Deploy = c.Deploy.Build()
return buildPlan, resolvedPackages, nil
}
func (c *GenerateContext) ApplyConfig(config *config.Config) error {
// Mise package config
miseStep := c.GetMiseStepBuilder()
for _, pkg := range slices.Sorted(maps.Keys(config.Packages)) {
version := config.Packages[pkg]
pkgRef := miseStep.Default(pkg, version)
miseStep.Version(pkgRef, version, "custom config")
func (c *GenerateContext) DefaultRuntimeInput() plan.Input {
return c.DefaultRuntimeInputWithPackages([]string{})
}
func (c *GenerateContext) DefaultRuntimeInputWithPackages(additionalAptPackages []string) plan.Input {
aptPackages := append(c.Config.Deploy.AptPackages, additionalAptPackages...)
if len(aptPackages) == 0 {
return plan.NewImageInput(plan.RAILPACK_RUNTIME_IMAGE)
}
// Apt package config
// aptStepName := ""
if len(config.AptPackages) > 0 {
aptStep := c.NewAptStepBuilder("config")
// aptStepName = aptStep.Name()
aptStep.Packages = config.AptPackages
runtimeAptStep := c.NewAptStepBuilder("runtime")
runtimeAptStep.Packages = aptPackages
runtimeAptStep.AddInput(plan.NewImageInput(plan.RAILPACK_RUNTIME_IMAGE))
// We install the apt packages again in the mise step since they may be required for install mise packages
miseStep.SupportingAptPackages = append(miseStep.SupportingAptPackages, config.AptPackages...)
}
// Step config
for _, name := range slices.Sorted(maps.Keys(config.Steps)) {
configStep := config.Steps[name]
var commandStepBuilder *CommandStepBuilder
// We need to use the key as the step name and not `configStep.Name`
if existingStep := c.GetStepByName(name); existingStep != nil {
if csb, ok := (*existingStep).(*CommandStepBuilder); ok {
commandStepBuilder = csb
} else {
log.Warnf("Step `%s` exists, but it is not a command step. Skipping...", name)
continue
}
} else {
commandStepBuilder = c.NewCommandStep(name)
}
// Overwrite the step with values from the config if they exist
// if len(configStep.DependsOn) > 0 {
// commandStepBuilder.DependsOn = configStep.DependsOn
// }
// if aptStepName != "" {
// commandStepBuilder.DependsOn = append(commandStepBuilder.DependsOn, aptStepName)
// }
if configStep.Commands != nil {
commandStepBuilder.Commands = configStep.Commands
}
// if configStep.Outputs != nil {
// commandStepBuilder.Outputs = configStep.Outputs
// }
for k, v := range configStep.Assets {
commandStepBuilder.Assets[k] = v
}
if configStep.Secrets != nil {
commandStepBuilder.Secrets = configStep.Secrets
}
// if configStep.UseSecrets != nil {
// commandStepBuilder.UseSecrets = *configStep.UseSecrets
// }
if len(configStep.Caches) > 0 {
commandStepBuilder.Caches = configStep.Caches
}
if configStep.Variables != nil {
commandStepBuilder.AddEnvVars(configStep.Variables)
}
}
// Cache config
for name, cache := range config.Caches {
c.Caches.SetCache(name, cache)
}
// Secret config
c.Secrets = append(c.Secrets, config.Secrets...)
// Start config
// if config.Start.BaseImage != "" {
// c.Start.BaseImage = config.Start.BaseImage
// }
// if config.Start.Command != "" {
// c.Start.Command = config.Start.Command
// }
// if config.Start.Variables != nil {
// c.Start.AddEnvVars(config.Start.Variables)
// }
// c.Start.AddPaths(config.Start.Paths)
// if len(config.Start.Outputs) > 0 {
// c.Start.outputs = config.Start.Outputs
// }
return nil
return plan.NewStepInput(runtimeAptStep.Name())
}
func (o *BuildStepOptions) NewAptInstallCommand(pkgs []string) plan.Command {
@@ -249,3 +171,79 @@ func (o *BuildStepOptions) NewAptInstallCommand(pkgs []string) plan.Command {
CustomName: "install apt packages: " + strings.Join(pkgs, " "),
})
}
func (c *GenerateContext) applyConfig() {
miseStep := c.GetMiseStepBuilder()
// Apply the cache config to the context
maps.Copy(c.Caches.Caches, c.Config.Caches)
// Apply step config to the context
for _, name := range slices.Sorted(maps.Keys(c.Config.Steps)) {
configStep := c.Config.Steps[name]
var commandStepBuilder *CommandStepBuilder
if existingStep := c.GetStepByName(name); existingStep != nil {
if csb, ok := (*existingStep).(*CommandStepBuilder); ok {
commandStepBuilder = csb
} else {
log.Warnf("Step `%s` exists, but it is not a command step. Skipping...", name)
continue
}
} else {
// If no build step found, create a new one
// Run the build in the builder context and copy the /app contents to the final image
commandStepBuilder = c.NewCommandStep(name)
commandStepBuilder.AddInput(plan.NewStepInput(miseStep.Name()))
c.Deploy.Inputs = append(c.Deploy.Inputs, plan.NewStepInput(commandStepBuilder.Name(), plan.InputOptions{
Include: []string{"."},
}))
}
if configStep.Commands != nil {
commandStepBuilder.Commands = configStep.Commands
}
if configStep.Inputs != nil {
commandStepBuilder.Inputs = configStep.Inputs
}
for k, v := range configStep.Assets {
commandStepBuilder.Assets[k] = v
}
if configStep.Secrets != nil {
commandStepBuilder.Secrets = configStep.Secrets
}
if len(configStep.Caches) > 0 {
commandStepBuilder.Caches = configStep.Caches
}
if configStep.Variables != nil {
commandStepBuilder.AddEnvVars(configStep.Variables)
}
// Secret config
if configStep.Secrets != nil {
commandStepBuilder.Secrets = configStep.Secrets
}
}
// Update deploy from config
if c.Config.Deploy.StartCmd != "" {
c.Deploy.StartCmd = c.Config.Deploy.StartCmd
}
if c.Config.Deploy.Inputs != nil {
fmt.Printf("Inputs: %v\n", c.Config.Deploy.Inputs)
c.Deploy.Inputs = c.Config.Deploy.Inputs
}
if c.Config.Deploy.Paths != nil {
c.Deploy.Paths = c.Config.Deploy.Paths
}
maps.Copy(c.Deploy.Variables, c.Config.Deploy.Variables)
}
+13 -8
View File
@@ -3,23 +3,28 @@ package generate
import "github.com/railwayapp/railpack/core/plan"
type DeployBuilder struct {
Inputs []plan.Input
StartCmd string
Variables map[string]string
Inputs []plan.Input
StartCmd string
Variables map[string]string
Paths []string
AptPackages []string
}
func NewDeployBuilder() *DeployBuilder {
return &DeployBuilder{
Inputs: []plan.Input{},
StartCmd: "",
Variables: map[string]string{},
Inputs: []plan.Input{},
StartCmd: "",
Variables: map[string]string{},
Paths: []string{},
AptPackages: []string{},
}
}
func (b *DeployBuilder) Build() *plan.Deploy {
return &plan.Deploy{
func (b *DeployBuilder) Build() plan.Deploy {
return plan.Deploy{
Inputs: b.Inputs,
StartCmd: b.StartCmd,
Variables: b.Variables,
Paths: b.Paths,
}
}
+18 -4
View File
@@ -10,6 +10,7 @@ type ImageStepBuilder struct {
Resolver *resolver.Resolver
Packages []*resolver.PackageRef
ResolveStepImage func(options *BuildStepOptions) string
AptPackages []string
}
func (c *GenerateContext) NewImageStep(name string, resolveStepImage func(options *BuildStepOptions) string) *ImageStepBuilder {
@@ -48,11 +49,24 @@ func (b *ImageStepBuilder) Build(options *BuildStepOptions) (*plan.Step, error)
step := plan.NewStep(b.DisplayName)
image := b.ResolveStepImage(options)
step.Inputs = []plan.Input{
plan.NewImageInput(image),
}
step.Secrets = []string{}
if len(b.AptPackages) > 0 {
runtimeAptStep := plan.NewStep("packages:apt")
runtimeAptStep.Inputs = []plan.Input{
plan.NewImageInput(image),
}
runtimeAptStep.Commands = []plan.Command{
options.NewAptInstallCommand(b.AptPackages),
}
step.Inputs = []plan.Input{
plan.NewStepInput(runtimeAptStep.Name),
}
} else {
step.Inputs = []plan.Input{
plan.NewImageInput(image),
}
}
return step, nil
}
+3 -3
View File
@@ -30,11 +30,13 @@ type MiseStepBuilder struct {
}
func (c *GenerateContext) newMiseStepBuilder() *MiseStepBuilder {
supportingAptPackages := c.Config.BuildAptPackages
step := &MiseStepBuilder{
DisplayName: MisePackageStepName,
Resolver: c.Resolver,
MisePackages: []*resolver.PackageRef{},
SupportingAptPackages: []string{},
SupportingAptPackages: append(supportingAptPackages, c.Config.BuildAptPackages...),
Assets: map[string]string{},
Inputs: []plan.Input{},
Variables: map[string]string{},
@@ -89,8 +91,6 @@ func (b *MiseStepBuilder) Build(options *BuildStepOptions) (*plan.Step, error) {
return step, nil
}
// step.StartingImage = BuilderBaseImage
step.Inputs = []plan.Input{
plan.NewImageInput(plan.RAILPACK_BUILDER_IMAGE),
}
+53 -64
View File
@@ -13,7 +13,6 @@ const (
DEFAULT_GO_VERSION = "1.23"
GO_BUILD_CACHE_KEY = "go-build"
GO_BINARY_NAME = "out"
START_IMAGE = "alpine:latest"
)
type GoProvider struct{}
@@ -31,36 +30,38 @@ func (p *GoProvider) Initialize(ctx *generate.GenerateContext) error {
}
func (p *GoProvider) Plan(ctx *generate.GenerateContext) error {
packages, err := p.Packages(ctx)
if err != nil {
return err
}
builder := p.GetBuilder(ctx)
p.InstallGoPackages(ctx, builder)
install, err := p.Install(ctx, packages)
if err != nil {
return err
}
install := ctx.NewCommandStep("install")
install.AddInput(plan.NewStepInput(builder.Name()))
p.InstallGoDeps(ctx, install)
build, err := p.Build(ctx, packages, install)
if err != nil {
return err
}
build := ctx.NewCommandStep("build")
build.AddInput(plan.NewStepInput(install.Name()))
p.Build(ctx, build)
if build != nil {
ctx.Deploy.StartCmd = fmt.Sprintf("./%s", GO_BINARY_NAME)
ctx.Deploy.StartCmd = fmt.Sprintf("./%s", GO_BINARY_NAME)
if !p.hasCGOEnabled(ctx) {
// ctx.Deploy.Outputs = []string{GO_BINARY_NAME}
if p.hasCGOEnabled(ctx) {
runtimeAptStep := ctx.NewAptStepBuilder("runtime")
runtimeAptStep.AddInput(ctx.DefaultRuntimeInputWithPackages([]string{"libc6"}))
// ctx.Start.BaseImage = START_IMAGE
// if startImage, _ := ctx.Env.GetConfigVariable("START_IMAGE"); startImage != "" {
// ctx.Start.BaseImage = startImage
// }
}
if p.isGin(ctx) {
ctx.Deploy.Variables["GIN_MODE"] = "release"
}
ctx.Deploy.Inputs = append(ctx.Deploy.Inputs, []plan.Input{
plan.NewStepInput(runtimeAptStep.Name()),
plan.NewStepInput(build.Name(), plan.InputOptions{
Include: []string{"."},
}),
plan.NewLocalInput("."),
}...)
} else {
ctx.Deploy.Inputs = append(ctx.Deploy.Inputs, []plan.Input{
ctx.DefaultRuntimeInput(),
plan.NewStepInput(build.Name(), plan.InputOptions{
Include: []string{"."},
}),
plan.NewLocalInput("."),
}...)
}
p.addMetadata(ctx)
@@ -68,52 +69,43 @@ func (p *GoProvider) Plan(ctx *generate.GenerateContext) error {
return nil
}
func (p *GoProvider) Build(ctx *generate.GenerateContext, packages *generate.MiseStepBuilder, install *generate.CommandStepBuilder) (*generate.CommandStepBuilder, error) {
func (p *GoProvider) Build(ctx *generate.GenerateContext, build *generate.CommandStepBuilder) {
var buildCmd string
flags := "-w -s"
baseBuildCmd := fmt.Sprintf("go build -ldflags=\"%s\" -o %s", flags, GO_BINARY_NAME)
if binName, _ := ctx.Env.GetConfigVariable("GO_BIN"); binName != "" {
// If there is a RAILPACK_GO_BIN variable, use that
buildCmd = fmt.Sprintf("go build -o %s ./cmd/%s", GO_BINARY_NAME, binName)
buildCmd = fmt.Sprintf("%s ./cmd/%s", baseBuildCmd, binName)
} else if p.isGoMod(ctx) && p.hasRootGoFiles(ctx) {
buildCmd = fmt.Sprintf("go build -o %s", GO_BINARY_NAME)
buildCmd = baseBuildCmd
} else if dirs, err := ctx.App.FindDirectories("cmd/*"); err == nil && len(dirs) > 0 {
// Try to find a command in the cmd directory
cmdName := filepath.Base(dirs[0])
buildCmd = fmt.Sprintf("go build -o %s ./cmd/%s", GO_BINARY_NAME, cmdName)
buildCmd = fmt.Sprintf("%s ./cmd/%s", baseBuildCmd, cmdName)
} else if p.isGoMod(ctx) {
buildCmd = fmt.Sprintf("go build -o %s", GO_BINARY_NAME)
buildCmd = baseBuildCmd
} else if ctx.App.HasMatch("main.go") {
buildCmd = fmt.Sprintf("go build -o %s main.go", GO_BINARY_NAME)
buildCmd = fmt.Sprintf("%s main.go", baseBuildCmd)
}
if buildCmd == "" {
return nil, nil
return
}
build := ctx.NewCommandStep("build")
build.AddCache(p.goBuildCache(ctx))
build.AddCommands([]plan.Command{
plan.NewCopyCommand("."),
plan.NewExecCommand(buildCmd),
})
if packages != nil {
// build.DependsOn = append(build.DependsOn, packages.DisplayName)
}
if install != nil {
// build.DependsOn = append(build.DependsOn, install.DisplayName)
}
return build, nil
}
func (p *GoProvider) Install(ctx *generate.GenerateContext, packages *generate.MiseStepBuilder) (*generate.CommandStepBuilder, error) {
func (p *GoProvider) InstallGoDeps(ctx *generate.GenerateContext, install *generate.CommandStepBuilder) {
if !p.isGoMod(ctx) {
return nil, nil
return
}
install := ctx.NewCommandStep("install")
install.AddCache(p.goBuildCache(ctx))
install.AddCommand(plan.NewCopyCommand("go.mod"))
@@ -123,24 +115,13 @@ func (p *GoProvider) Install(ctx *generate.GenerateContext, packages *generate.M
install.AddCommand(plan.NewExecCommand("go mod download"))
// If CGO is enabled, we need to install the gcc packages
if p.hasCGOEnabled(ctx) {
aptStep := ctx.NewAptStepBuilder("cgo")
aptStep.Packages = []string{"gcc", "g++", "libc6-dev"}
// install.DependsOn = append(install.DependsOn, aptStep.DisplayName)
} else {
if !p.hasCGOEnabled(ctx) {
install.AddEnvVars(map[string]string{"CGO_ENABLED": "0"})
}
// install.DependsOn = []string{packages.DisplayName}
return install, nil
}
func (p *GoProvider) Packages(ctx *generate.GenerateContext) (*generate.MiseStepBuilder, error) {
packages := ctx.GetMiseStepBuilder()
goPkg := packages.Default("go", DEFAULT_GO_VERSION)
func (p *GoProvider) InstallGoPackages(ctx *generate.GenerateContext, miseStep *generate.MiseStepBuilder) {
goPkg := miseStep.Default("go", DEFAULT_GO_VERSION)
if goModContents, err := ctx.App.ReadFile("go.mod"); err == nil {
// Split content into lines and look for "go X.XX" line
@@ -149,7 +130,7 @@ func (p *GoProvider) Packages(ctx *generate.GenerateContext) (*generate.MiseStep
if strings.HasPrefix(strings.TrimSpace(line), "go ") {
// Extract version number
if goVersion := strings.TrimSpace(strings.TrimPrefix(line, "go")); goVersion != "" {
packages.Version(goPkg, goVersion, "go.mod")
miseStep.Version(goPkg, goVersion, "go.mod")
break
}
}
@@ -157,10 +138,18 @@ func (p *GoProvider) Packages(ctx *generate.GenerateContext) (*generate.MiseStep
}
if envVersion, varName := ctx.Env.GetConfigVariable("GO_VERSION"); envVersion != "" {
packages.Version(goPkg, envVersion, varName)
miseStep.Version(goPkg, envVersion, varName)
}
}
func (p *GoProvider) GetBuilder(ctx *generate.GenerateContext) *generate.MiseStepBuilder {
miseStep := ctx.GetMiseStepBuilder()
if p.hasCGOEnabled(ctx) {
miseStep.SupportingAptPackages = append(miseStep.SupportingAptPackages, "gcc", "g++", "libc6-dev")
}
return packages, nil
return miseStep
}
func (p *GoProvider) addMetadata(ctx *generate.GenerateContext) {
+1 -1
View File
@@ -78,7 +78,7 @@ func (p *NodeProvider) Plan(ctx *generate.GenerateContext) error {
maps.Copy(ctx.Deploy.Variables, p.GetNodeEnvVars(ctx))
ctx.Deploy.Inputs = append(ctx.Deploy.Inputs, []plan.Input{
plan.NewImageInput(plan.RAILPACK_RUNTIME_IMAGE),
ctx.DefaultRuntimeInput(),
plan.NewStepInput(miseStep.Name(), plan.InputOptions{
Include: miseStep.GetOutputPaths(),
}),
+8 -7
View File
@@ -38,12 +38,8 @@ func (p *PhpProvider) Plan(ctx *generate.GenerateContext) error {
}
// Nginx
nginxPackages := ctx.NewAptStepBuilder("nginx")
nginxPackages.AddInput(plan.NewStepInput(phpImageStep.Name()))
nginxPackages.Packages = []string{"nginx", "git", "zip", "unzip"}
nginx := ctx.NewCommandStep("nginx")
nginx.AddInput(plan.NewStepInput(nginxPackages.Name()))
nginx.AddInput(plan.NewStepInput(phpImageStep.Name()))
nginx.AddCommands([]plan.Command{
plan.NewFileCommand("/etc/nginx/railpack.conf", "nginx.conf", plan.FileOptions{CustomName: "create nginx config"}),
plan.NewExecCommand("nginx -t -c /etc/nginx/railpack.conf"),
@@ -128,8 +124,7 @@ func (p *PhpProvider) Plan(ctx *generate.GenerateContext) error {
build.AddInput(plan.NewStepInput(composer.Name()))
ctx.Deploy.Inputs = []plan.Input{
// plan.NewStepInput(build.Name()),
plan.NewStepInput(composer.Name()),
plan.NewStepInput(build.Name()),
plan.NewLocalInput("."),
}
}
@@ -191,6 +186,12 @@ func (p *PhpProvider) phpImagePackage(ctx *generate.GenerateContext) (*generate.
return getPhpImage(DEFAULT_PHP_VERSION)
})
imageStep.AptPackages = append(imageStep.AptPackages, "nginx", "git", "zip", "unzip")
// Include both build and runtime apt packages since we don't have a separate runtime image
imageStep.AptPackages = append(imageStep.AptPackages, ctx.Config.BuildAptPackages...)
imageStep.AptPackages = append(imageStep.AptPackages, ctx.Config.Deploy.AptPackages...)
php := imageStep.Default("php", DEFAULT_PHP_VERSION)
// Read composer.json to get the PHP version
+18 -12
View File
@@ -144,14 +144,20 @@ func (p *PythonProvider) PlanPipenv(ctx *generate.GenerateContext) {
install.Secrets = []string{}
install.UseSecretsWithPrefixes([]string{"PYTHON", "PIP"})
install.AddCommands([]plan.Command{
plan.NewExecCommand("pipx install pipenv"),
plan.NewPathCommand(LOCAL_BIN_PATH),
plan.NewCopyCommand("Pipfile"),
plan.NewCopyCommand("Pipfile.lock"),
plan.NewExecCommand("pipenv install --deploy --ignore-pipfile"),
plan.NewPathCommand(VENV_PATH + "/bin"),
})
if ctx.App.HasMatch("Pipfile.lock") {
install.AddCommands([]plan.Command{
plan.NewExecCommand("pipx install pipenv"),
plan.NewPathCommand(LOCAL_BIN_PATH),
plan.NewCopyCommand("Pipfile"),
plan.NewCopyCommand("Pipfile.lock"),
plan.NewExecCommand("pipenv install --deploy --ignore-pipfile"),
plan.NewPathCommand(VENV_PATH + "/bin"),
})
} else {
install.AddCommands([]plan.Command{
@@ -160,6 +166,10 @@ func (p *PythonProvider) PlanPipenv(ctx *generate.GenerateContext) {
})
}
install.AddCommands([]plan.Command{
plan.NewPathCommand(VENV_PATH + "/bin"),
})
build := ctx.NewCommandStep("build")
build.AddInput(plan.NewStepInput(install.Name()))
@@ -294,7 +304,7 @@ func (p *PythonProvider) PlanPip(ctx *generate.GenerateContext) {
func (p *PythonProvider) GetImageWithRuntimeDeps(ctx *generate.GenerateContext) *generate.AptStepBuilder {
aptStep := ctx.NewAptStepBuilder("python-runtime-deps")
aptStep.Inputs = []plan.Input{
plan.NewImageInput(plan.RAILPACK_RUNTIME_IMAGE),
ctx.DefaultRuntimeInput(),
}
for dep, requiredPkgs := range pythonRuntimeDepRequirements {
@@ -306,15 +316,11 @@ func (p *PythonProvider) GetImageWithRuntimeDeps(ctx *generate.GenerateContext)
return aptStep
}
func (p *PythonProvider) GetBuilderDeps(ctx *generate.GenerateContext) *generate.AptStepBuilder {
aptStep := ctx.NewAptStepBuilder("python-builder-deps")
aptStep.Inputs = []plan.Input{
plan.NewStepInput(ctx.GetMiseStepBuilder().Name()),
}
func (p *PythonProvider) GetBuilderDeps(ctx *generate.GenerateContext) *generate.MiseStepBuilder {
miseStep := ctx.GetMiseStepBuilder()
miseStep.SupportingAptPackages = append(miseStep.SupportingAptPackages, "python3-dev", "libpq-dev")
aptStep.Packages = []string{"python3-dev", "libpq-dev"}
return aptStep
return miseStep
}
func (p *PythonProvider) InstallPythonDeps(ctx *generate.GenerateContext, install *generate.CommandStepBuilder) {
+5
View File
@@ -0,0 +1,5 @@
[
{
"expectedOutput": "Hello from Python-PDM"
}
]
+1 -1
View File
@@ -7,4 +7,4 @@ print("numpy", np.__version__)
print("pandas", pd.__version__)
print("psycopg2", psycopg2.__version__)
print("Hello from Python")
print("Hello from UV")
+1 -1
View File
@@ -1,5 +1,5 @@
[
{
"expectedOutput": "Hello from Python"
"expectedOutput": "Hello from UV"
}
]
+1 -1
View File
@@ -1,3 +1,3 @@
import cowsay
cowsay.cow("Hello, world!")
cowsay.cow("Hello from Python-Pipfile")
+5
View File
@@ -0,0 +1,5 @@
[
{
"expectedOutput": "Hello from Python-Pipfile"
}
]