-
Notifications
You must be signed in to change notification settings - Fork 131
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Read and parse agent config * Lint * Lint fix? * Fix import * Validate that files exist * Lint fix * Simplify minimal config * Cleanup
- Loading branch information
Showing
4 changed files
with
238 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package configs | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/bitrise-io/go-utils/pathutil" | ||
"gopkg.in/yaml.v2" | ||
) | ||
|
||
const defaultSourceDir = "workspace" | ||
const defaultDeployDir = "$BITRISE_APP_SLUG/$BITRISE_BUILD_SLUG/artifacts" | ||
const defaultTestDeployDir = "$BITRISE_APP_SLUG/$BITRISE_BUILD_SLUG/test_results" | ||
|
||
type AgentConfig struct { | ||
BitriseDirs BitriseDirs `yaml:"bitrise_dirs"` | ||
Hooks AgentHooks `yaml:"hooks"` | ||
} | ||
|
||
type BitriseDirs struct { | ||
// BitriseDataHomeDir is the root directory for all Bitrise data produced at runtime | ||
BitriseDataHomeDir string `yaml:"BITRISE_DATA_HOME_DIR"` | ||
|
||
// SourceDir is for source code checkouts. | ||
// It might be outside of BitriseDataHomeDir if the user has configured it so | ||
SourceDir string `yaml:"BITRISE_SOURCE_DIR"` | ||
|
||
// DeployDir is for deployable artifacts. | ||
// It might be outside of BitriseDataHomeDir if the user has configured it so | ||
DeployDir string `yaml:"BITRISE_DEPLOY_DIR"` | ||
|
||
// TestDeployDir is for deployable test result artifacts. | ||
// It might be outside of BitriseDataHomeDir if the user has configured it so | ||
TestDeployDir string `yaml:"BITRISE_TEST_DEPLOY_DIR"` | ||
} | ||
|
||
type AgentHooks struct { | ||
// CleanupOnWorkflowStart is the list of UNEXPANDED paths to clean up when the workflow starts. | ||
// The actual string value should be expanded at execution time, so that | ||
// Bitrise dirs defined in this config file are correctly expanded. | ||
CleanupOnWorkflowStart []string `yaml:"cleanup_on_workflow_start"` | ||
|
||
// CleanupOnWorkflowEnd is the list of UNEXPANDED paths to clean up when the workflow end. | ||
// The actual string value should be expanded at execution time, so that | ||
// Bitrise dirs defined in this config file are correctly expanded. | ||
CleanupOnWorkflowEnd []string `yaml:"cleanup_on_workflow_end"` | ||
|
||
// DoOnWorkflowStart is an optional executable to run when the workflow starts. | ||
DoOnWorkflowStart string `yaml:"do_on_workflow_start"` | ||
|
||
// DoOnWorkflowEnd is an optional executable to run when the workflow ends. | ||
DoOnWorkflowEnd string `yaml:"do_on_workflow_end"` | ||
} | ||
|
||
func readAgentConfig(configFile string) (AgentConfig, error) { | ||
fileContent, err := os.ReadFile(configFile) | ||
if err != nil { | ||
return AgentConfig{}, err | ||
} | ||
|
||
var config AgentConfig | ||
err = yaml.Unmarshal(fileContent, &config) | ||
if err != nil { | ||
return AgentConfig{}, err | ||
} | ||
|
||
expandedBitriseDataHomeDir, err := expandPath(config.BitriseDirs.BitriseDataHomeDir) | ||
if err != nil { | ||
return AgentConfig{}, fmt.Errorf("expand BITRISE_DATA_HOME_DIR value: %s", err) | ||
} | ||
config.BitriseDirs.BitriseDataHomeDir = expandedBitriseDataHomeDir | ||
|
||
// BITRISE_SOURCE_DIR | ||
if config.BitriseDirs.SourceDir == "" { | ||
config.BitriseDirs.SourceDir = filepath.Join(config.BitriseDirs.BitriseDataHomeDir, defaultSourceDir) | ||
} | ||
expandedSourceDir, err := expandPath(config.BitriseDirs.SourceDir) | ||
if err != nil { | ||
return AgentConfig{}, fmt.Errorf("expand BITRISE_SOURCE_DIR value: %s", err) | ||
} | ||
config.BitriseDirs.SourceDir = expandedSourceDir | ||
|
||
// BITRISE_DEPLOY_DIR | ||
if config.BitriseDirs.DeployDir == "" { | ||
config.BitriseDirs.DeployDir = filepath.Join(config.BitriseDirs.BitriseDataHomeDir, defaultDeployDir) | ||
} | ||
expandedDeployDir, err := expandPath(config.BitriseDirs.DeployDir) | ||
if err != nil { | ||
return AgentConfig{}, fmt.Errorf("expand BITRISE_DEPLOY_DIR value: %s", err) | ||
} | ||
config.BitriseDirs.DeployDir = expandedDeployDir | ||
|
||
// BITRISE_TEST_DEPLOY_DIR | ||
if config.BitriseDirs.TestDeployDir == "" { | ||
config.BitriseDirs.TestDeployDir = filepath.Join(config.BitriseDirs.BitriseDataHomeDir, defaultTestDeployDir) | ||
} | ||
expandedTestDeployDir, err := expandPath(config.BitriseDirs.TestDeployDir) | ||
if err != nil { | ||
return AgentConfig{}, fmt.Errorf("expand BITRISE_TEST_DEPLOY_DIR value: %s", err) | ||
} | ||
config.BitriseDirs.TestDeployDir = expandedTestDeployDir | ||
|
||
// Hooks | ||
if config.Hooks.DoOnWorkflowStart != "" { | ||
expandedDoOnWorkflowStart, err := expandPath(config.Hooks.DoOnWorkflowStart) | ||
if err != nil { | ||
return AgentConfig{}, fmt.Errorf("expand do_on_workflow_start value: %s", err) | ||
} | ||
doOnWorkflowStartExists, err := pathutil.IsPathExists(expandedDoOnWorkflowStart) | ||
if err != nil { | ||
return AgentConfig{}, err | ||
} | ||
if !doOnWorkflowStartExists { | ||
return AgentConfig{}, fmt.Errorf("do_on_workflow_start path does not exist: %s", expandedDoOnWorkflowStart) | ||
} | ||
config.Hooks.DoOnWorkflowStart = expandedDoOnWorkflowStart | ||
} | ||
|
||
if config.Hooks.DoOnWorkflowEnd != "" { | ||
expandedDoOnWorkflowEnd, err := expandPath(config.Hooks.DoOnWorkflowEnd) | ||
if err != nil { | ||
return AgentConfig{}, fmt.Errorf("expand do_on_workflow_end value: %s", err) | ||
} | ||
doOnWorkflowEndExists, err := pathutil.IsPathExists(expandedDoOnWorkflowEnd) | ||
if err != nil { | ||
return AgentConfig{}, err | ||
} | ||
if !doOnWorkflowEndExists { | ||
return AgentConfig{}, fmt.Errorf("do_on_workflow_end path does not exist: %s", expandedDoOnWorkflowEnd) | ||
} | ||
config.Hooks.DoOnWorkflowEnd = expandedDoOnWorkflowEnd | ||
} | ||
|
||
return config, nil | ||
} | ||
|
||
func expandPath(path string) (string, error) { | ||
return pathutil.ExpandTilde(os.ExpandEnv(path)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package configs | ||
|
||
import ( | ||
"io/ioutil" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestReadAgentConfig(t *testing.T) { | ||
t.Setenv("BITRISE_APP_SLUG", "ef7a9665e8b6408b") | ||
t.Setenv("BITRISE_BUILD_SLUG", "80b66786-d011-430f-9c68-00e9416a7325") | ||
tempDir := t.TempDir() | ||
t.Setenv("HOOKS_DIR", tempDir) | ||
err := ioutil.WriteFile(filepath.Join(tempDir, "cleanup.sh"), []byte("echo cleanup.sh"), 0644) | ||
require.NoError(t, err) | ||
|
||
testCases := []struct { | ||
name string | ||
configFile string | ||
expectedConfig AgentConfig | ||
expectedErr bool | ||
}{ | ||
{ | ||
name: "Full config file", | ||
configFile: "testdata/full-agent-config.yml", | ||
expectedConfig: AgentConfig{ | ||
BitriseDirs{ | ||
BitriseDataHomeDir: "/opt/bitrise", | ||
SourceDir: "/opt/bitrise/workspace/ef7a9665e8b6408b", | ||
DeployDir: "/opt/bitrise/ef7a9665e8b6408b/80b66786-d011-430f-9c68-00e9416a7325/artifacts", | ||
TestDeployDir: "/opt/bitrise/ef7a9665e8b6408b/80b66786-d011-430f-9c68-00e9416a7325/test_results", | ||
}, | ||
AgentHooks{ | ||
CleanupOnWorkflowStart: []string{"$BITRISE_DEPLOY_DIR"}, | ||
CleanupOnWorkflowEnd: []string{"$BITRISE_TEST_DEPLOY_DIR"}, | ||
DoOnWorkflowStart: filepath.Join(tempDir, "cleanup.sh"), | ||
DoOnWorkflowEnd: filepath.Join(tempDir, "cleanup.sh"), | ||
}, | ||
}, | ||
expectedErr: false, | ||
}, | ||
{ | ||
name: "Minimal config file", | ||
configFile: "testdata/minimal-agent-config.yml", | ||
expectedConfig: AgentConfig{ | ||
BitriseDirs{ | ||
BitriseDataHomeDir: "/opt/bitrise", | ||
SourceDir: "/opt/bitrise/workspace", | ||
DeployDir: "/opt/bitrise/ef7a9665e8b6408b/80b66786-d011-430f-9c68-00e9416a7325/artifacts", | ||
TestDeployDir: "/opt/bitrise/ef7a9665e8b6408b/80b66786-d011-430f-9c68-00e9416a7325/test_results", | ||
}, | ||
AgentHooks{}, | ||
}, | ||
expectedErr: false, | ||
}, | ||
{ | ||
name: "Non-existent config file", | ||
configFile: "nonexistent", | ||
expectedConfig: AgentConfig{}, | ||
expectedErr: true, | ||
}, | ||
{ | ||
name: "Config file with invalid YAML", | ||
configFile: "testdata", | ||
expectedConfig: AgentConfig{}, | ||
expectedErr: true, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
config, err := readAgentConfig(tc.configFile) | ||
if (err != nil) != tc.expectedErr { | ||
t.Errorf("Unexpected error: %v", err) | ||
} | ||
require.Equal(t, tc.expectedConfig, config) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
bitrise_dirs: | ||
BITRISE_DATA_HOME_DIR: /opt/bitrise | ||
BITRISE_SOURCE_DIR: /opt/bitrise/workspace/$BITRISE_APP_SLUG | ||
BITRISE_DEPLOY_DIR: /opt/bitrise/$BITRISE_APP_SLUG/$BITRISE_BUILD_SLUG/artifacts | ||
BITRISE_TEST_DEPLOY_DIR: /opt/bitrise/$BITRISE_APP_SLUG/$BITRISE_BUILD_SLUG/test_results | ||
|
||
hooks: | ||
cleanup_on_workflow_start: | ||
- $BITRISE_DEPLOY_DIR | ||
|
||
cleanup_on_workflow_end: | ||
- $BITRISE_TEST_DEPLOY_DIR | ||
|
||
do_on_workflow_start: $HOOKS_DIR/cleanup.sh | ||
do_on_workflow_end: $HOOKS_DIR/cleanup.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
bitrise_dirs: | ||
BITRISE_DATA_HOME_DIR: /opt/bitrise |