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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

* Release tasks work with latest metadata from Heroku Buildpacks

## [2.2.0] - 2025-09-19

### Added

* apppack.toml file is now accessible by APPPACK_TOML environment variable, allowing different services in different environments.
13 changes: 8 additions & 5 deletions builder/build/apppacktoml.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"strings"

"github.com/apppackio/codebuild-image/builder/filesystem"
"github.com/BurntSushi/toml"
"github.com/rs/zerolog/log"
)
Expand Down Expand Up @@ -103,19 +104,21 @@ func (a *AppPackToml) GetTestEnv() map[string]string {
func ParseAppPackToml(ctx context.Context) (*AppPackToml, error) {
var config AppPackToml
// if the file doesn't exist, just return an empty config
if _, err := os.Stat("apppack.toml"); os.IsNotExist(err) {
log.Ctx(ctx).Debug().Msg("apppack.toml not found")
filename := filesystem.GetAppPackTomlFilename()
if _, err := os.Stat(filename); os.IsNotExist(err) {
log.Ctx(ctx).Debug().Msg(fmt.Sprintf("%s not found", filename))
return &config, nil
}
if _, err := toml.DecodeFile("apppack.toml", &config); err != nil {
if _, err := toml.DecodeFile(filename, &config); err != nil {
return nil, err
}
return &config, nil
}

func (a AppPackToml) Write(ctx context.Context) error {
log.Ctx(ctx).Debug().Msg("writing apppack.toml")
f, err := os.Create("apppack.toml")
filename := filesystem.GetAppPackTomlFilename()
log.Ctx(ctx).Debug().Msg(fmt.Sprintf("writing %s", filename))
f, err := os.Create(filename)
if err != nil {
return err
}
Expand Down
7 changes: 4 additions & 3 deletions builder/build/prebuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,16 @@ func (b *Build) ConvertAppJson() error {
return err
}
// check if apppack.toml file exists
apppackTomlExists, err := b.state.FileExists("apppack.toml")
filename := filesystem.GetAppPackTomlFilename()
apppackTomlExists, err := b.state.FileExists(filename)
if err != nil {
return err
}
if appJsonExists && !apppackTomlExists {
// convert app.json to apppack.toml
b.Log().Info().Msg("Converting app.json to apppack.toml")
b.Log().Info().Msg(fmt.Sprintf("Converting app.json to %s", filename))
t := b.AppJSON.ToApppackToml()
return b.state.WriteTomlToFile("apppack.toml", t)
return b.state.WriteTomlToFile(filename, t)
}
return nil
}
Expand Down
12 changes: 11 additions & 1 deletion builder/filesystem/filesystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ func (f *FileState) Log() *zerolog.Logger {

func (f *FileState) CreateIfNotExists() error {
// touch files codebuild expects to exist
for _, filename := range []string{"apppack.toml", "build.log", "metadata.toml", "test.log"} {
apppackToml := GetAppPackTomlFilename()

for _, filename := range []string{apppackToml, "build.log", "metadata.toml", "test.log"} {
exists, err := f.FileExists(filename)
if err != nil {
return err
Expand Down Expand Up @@ -177,3 +179,11 @@ func (f *FileState) WriteJsonToFile(filename string, v interface{}) error {
}
return nil
}

func GetAppPackTomlFilename() string {
filename := "apppack.toml"
if envFile := os.Getenv("APPPACK_TOML"); envFile != "" {
filename = envFile
}
return filename
}
33 changes: 29 additions & 4 deletions builder/filesystem/filesystem_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"archive/tar"
"bytes"
"context"
"fmt"
"io"
"os"
"testing"
Expand All @@ -16,8 +17,11 @@ var testContext = zerolog.New(os.Stdout).With().Timestamp().Logger().WithContext

func TestCreateIfNotExists(t *testing.T) {
fs := afero.Afero{Fs: afero.NewMemMapFs()}
if _, err := fs.Stat("apppack.toml"); !os.IsNotExist(err) {
t.Error("apppack.toml should not exist")

filename := GetAppPackTomlFilename()

if _, err := fs.Stat(filename); !os.IsNotExist(err) {
t.Error(fmt.Sprintf("%s should not exist", filename))
}
s := &FileState{
fs: fs,
Expand All @@ -27,8 +31,8 @@ func TestCreateIfNotExists(t *testing.T) {
if err != nil {
t.Error(err)
}
if _, err := fs.Stat("apppack.toml"); os.IsNotExist(err) {
t.Error("apppack.toml should exist")
if _, err := fs.Stat(filename); os.IsNotExist(err) {
t.Error(fmt.Sprintf("%s should exist", filename))
}
}

Expand Down Expand Up @@ -105,6 +109,27 @@ func TestWriteEnvFile(t *testing.T) {
}
}

func TestGetFilename(t *testing.T) {
// Check that there is no env variable set
if os.Getenv("APPPACK_TOML") != "" {
t.Error("APPPACK_TOML env variable should not be set")
}
// Call GetAppPackTomlFilename and check the default value

filename := GetAppPackTomlFilename()
if filename != "apppack.toml" {
t.Errorf("expected apppack.toml, got %s", filename)
}

// Set the env variable and check again
os.Setenv("APPPACK_TOML", "custom.toml")
defer os.Unsetenv("APPPACK_TOML") // Clean up after the test
filename = GetAppPackTomlFilename()
if filename != "custom.toml" {
t.Errorf("expected custom.toml, got %s", filename)
}
}

func dummyTarBuffer() (*io.Reader, error) {
var buf bytes.Buffer
tw := tar.NewWriter(&buf)
Expand Down