diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5ee2d26..b3f5fe1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,5 +18,11 @@ jobs: - name: Checkout code uses: actions/checkout@v2 + - name: Allow skip provisioner tests + uses: allenevans/set-env@v1.0.0 + if: matrix.os != 'ubuntu-latest' + with: + ALLOW_PROVISIONER_SKIP: 1 + - name: Test run: go test ./... \ No newline at end of file diff --git a/starlark/types/provider_test.go b/starlark/types/provider_test.go index f743e35..06fce1e 100644 --- a/starlark/types/provider_test.go +++ b/starlark/types/provider_test.go @@ -4,6 +4,7 @@ import ( "fmt" "io/ioutil" "log" + stdos "os" "testing" "github.com/mcuadros/ascode/starlark/module/os" @@ -33,6 +34,10 @@ func TestProvider(t *testing.T) { } func TestProvisioner(t *testing.T) { + if stdos.Getenv("ALLOW_PROVISIONER_SKIP") != "" && !terraform.IsTerraformBinaryAvailable() { + t.Skip("terraform binary now available in $PATH") + } + doTest(t, "testdata/provisioner.star") } diff --git a/terraform/plugins.go b/terraform/plugins.go index e88e5e1..c583f0b 100644 --- a/terraform/plugins.go +++ b/terraform/plugins.go @@ -1,6 +1,7 @@ package terraform import ( + "fmt" "os" "os/exec" "strings" @@ -42,6 +43,10 @@ func (m *PluginManager) Provider(provider, version string, forceLocal bool) (*pl // try to locate it at the local Path, if not try to execute it from the // built-in plugins in the terraform binary. func (m *PluginManager) Provisioner(provisioner string) (*plugin.Client, discovery.PluginMeta, error) { + if !IsTerraformBinaryAvailable() { + return nil, discovery.PluginMeta{}, ErrTerraformNotAvailable + } + meta, ok := m.getLocal("provisioner", provisioner, "") if ok { return client(meta), meta, nil @@ -121,3 +126,17 @@ func (m *PluginManager) getLocal(kind, provider, version string) (discovery.Plug return set.Newest(), true } + +// ErrTerraformNotAvailable error used when `terraform` binary in not in the +// path and we try to use a provisioner. +var ErrTerraformNotAvailable = fmt.Errorf("provisioner error: executable file 'terraform' not found in $PATH") + +// IsTerraformBinaryAvailable determines if Terraform binary is available in +// the path of the system. Terraform binary is a requirement for executing +// provisioner plugins, since they are built-in on the Terrafrom binary. :( +// +// https://github.com/hashicorp/terraform/issues/20896#issuecomment-479054649 +func IsTerraformBinaryAvailable() bool { + _, err := exec.LookPath("terraform") + return err == nil +} diff --git a/terraform/plugins_test.go b/terraform/plugins_test.go index 875b793..dbc86ea 100644 --- a/terraform/plugins_test.go +++ b/terraform/plugins_test.go @@ -3,6 +3,7 @@ package terraform import ( "fmt" "io/ioutil" + "os" "strings" "testing" @@ -51,6 +52,10 @@ func TestPluginManager_ProviderDefault(t *testing.T) { } func TestPluginManager_ProvisionerDefault(t *testing.T) { + if os.Getenv("ALLOW_PROVISIONER_SKIP") != "" && !IsTerraformBinaryAvailable() { + t.Skip("terraform binary now available in $PATH") + } + path, err := ioutil.TempDir("", "provisioner") assert.NoError(t, err)