diff --git a/main.go b/main.go index 72cbfc3..9b40967 100644 --- a/main.go +++ b/main.go @@ -139,7 +139,7 @@ func main() { Source: codedir, Stdout: os.Stdout, Stderr: os.Stderr, - Environ: os.Environ(), + Environ: github.Environ(os.Environ()), OutputFile: outputFile, } if err := execer.Exec(ctx); err != nil { diff --git a/plugin/github/env.go b/plugin/github/env.go index 9ea5c7d..9db1466 100644 --- a/plugin/github/env.go +++ b/plugin/github/env.go @@ -14,11 +14,91 @@ import ( "strings" "github.com/drone/plugin/plugin/internal/encoder" + "github.com/drone/plugin/plugin/internal/environ" "github.com/joho/godotenv" "github.com/pkg/errors" "golang.org/x/exp/slog" ) +// Environ function converts harness or drone environment +// variables to github action environment variables. +func Environ(src []string) []string { + // make a copy of the environment variables + dst := environ.Map(src) + + // convert drone environment variables to github action + // environment variables + for key, val := range dst { + // drone prefixes plugin input parameters, github action + // does not. trim the prefix and convert to lowercase + // for github action compatibility. + if strings.HasPrefix(key, "PLUGIN_") { + key = strings.TrimPrefix("PLUGIN_", "") + key = strings.ToLower(key) + dst[key] = val + } + } + + tagName := dst["DRONE_TAG"] + branchName := dst["DRONE_BRANCH"] + + arch := "X64" + if runtime.GOARCH == "arm64" { + arch = "arm64" + } + + ostype := "Linux" + runner_tool_cache := "/opt/hostedtoolcache" + + if runtime.GOOS == "darwin" { + ostype = "macOS" + runner_tool_cache = "/Users/anka/hostedtoolcache" + } else if runtime.GOOS == "windows" { + ostype = "Windows" + runner_tool_cache = "C:\\hostedtoolcache\\windows" + } + + // github actions may depend on github action environment variables. + // map drone environment variables, which are already present + // in the execution envionment, to their github action equivalents. + // + // github action environment variable docs: + // https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables + dst = environ.Combine(dst, map[string]string{ + "GITHUB_BASE_REF": dst["DRONE_TARGET_BRANCH"], + "GITHUB_HEAD_REF": dst["DRONE_SOURCE_BRANCH"], + "GITHUB_REF": dst["DRONE_COMMIT_REF"], + "GITHUB_REPOSITORY": dst["DRONE_REPO"], + "GITHUB_REPOSITORY_OWNER": parseOwner(dst["DRONE_REPO"]), + "SHA_REF": dst["DRONE_COMMIT_SHA"], + "GITHUB_RUN_ATTEMPT": dst["DRONE_BUILD_NUMBER"], + "GITHUB_RUN_NUMBER": dst["DRONE_BUILD_NUMBER"], + "GITHUB_WORKSPACE": firstMatch(dst, "DRONE_WORKSPACE", "HARNESS_WORKSPACE"), + "RUNNER_ARCH": arch, + "RUNNER_OS": ostype, + "RUNNER_NAME": "HARNESS HOSTED", + "RUNNER_TOOL_CACHE": runner_tool_cache, + }) + + if tagName != "" { + dst["GITHUB_REF_NAME"] = tagName + dst["GITHUB_REF_TYPE"] = "tag" + } else if branchName != "" { + dst["GITHUB_REF_NAME"] = branchName + dst["GITHUB_REF_TYPE"] = "branch" + } + + return environ.Slice(dst) +} + +// helper function gets the owner from a repository slug. +func parseOwner(s string) (owner string) { + if parts := strings.Split(s, "/"); len(parts) == 2 { + return parts[0] + } + return +} + func getWith(envVars map[string]string) (map[string]string, error) { if val, ok := envVars["PLUGIN_WITH"]; ok { with, err := strToMap(val) @@ -129,3 +209,14 @@ func strToMap(s string) (map[string]string, error) { } return m, nil } + +// helper function find the first matching environment +// variable in the map. +func firstMatch(envs map[string]string, keys ...string) (val string) { + for _, key := range keys { + if env, ok := envs[key]; ok { + return env + } + } + return +} diff --git a/plugin/github/execer.go b/plugin/github/execer.go index a2fec81..4eec308 100644 --- a/plugin/github/execer.go +++ b/plugin/github/execer.go @@ -36,6 +36,7 @@ func (e *Execer) Exec(ctx context.Context) error { } envVars := environ.Map(e.Environ) + envVars["RUNNER_TEMP"] = tmpDir outputVars := getOutputVars(e.Source, e.Name) workflowFile := filepath.Join(tmpDir, "workflow.yml")