Files
Bussa Aditya Naga Sai LaxmanandCursor 7f3c946f42 fix: [CI-23943]: make plugin compatible with act 0.2.89 (#32)
* fix: [CI-23943]: remediate github-actions image vulnerabilities

Upgrade the Go toolchain, dependencies, Docker base image, and act runtime to reduce vulnerabilities while preserving plugin behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: [CI-23943]: generate valid workflows for act

Skip invalid placeholder output steps so actions without outputs remain compatible with newer act validation.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: [CI-23943]: skip invalid env var names in act env file

Harness injects a step's output variables into later steps in the stage
(e.g. cache-hit and node-version from actions/setup-node). Hyphenated
names are not valid in dotenv files, and act >= 0.2.89 fails to parse
--env-file when they are present:

  Error loading from /tmp/action.env: unexpected character "-" in
  variable name near "cache-hit=..."

Filter out any name that is not a valid dotenv identifier when writing
the env file. Secrets handling and PLUGIN_* exclusion are unchanged.

Found during HHI migration smoke testing (CI-24652) with
harnesssecure/github-actions built on custom-ci-dind-base:29.8
(act 0.2.89).

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 21:04:55 +05:30

52 lines
1.6 KiB
Go

package utils
import (
"path/filepath"
"testing"
"github.com/joho/godotenv"
"github.com/stretchr/testify/assert"
)
func TestValidEnvName(t *testing.T) {
valid := []string{"NORMAL_VAR", "_leading_underscore", "GITHUB_TOKEN", "path2"}
for _, name := range valid {
assert.True(t, validEnvName.MatchString(name), "expected %q to be valid", name)
}
// Hyphenated names come from action outputs that Harness injects into
// later steps, e.g. cache-hit and node-version from actions/setup-node.
invalid := []string{"cache-hit", "node-version", "2leading_digit", "has space", ""}
for _, name := range invalid {
assert.False(t, validEnvName.MatchString(name), "expected %q to be invalid", name)
}
}
func TestCreateEnvAndSecretFileSkipsInvalidNames(t *testing.T) {
testDir := t.TempDir()
envFile := filepath.Join(testDir, "action.env")
secretFile := filepath.Join(testDir, "action.secrets")
t.Setenv("HARNESS_GHA_TEST", "kept")
t.Setenv("cache-hit", "dropped")
t.Setenv("node-version", "v16.20.2")
t.Setenv("PLUGIN_USES", "dropped")
t.Setenv("GITHUB_TOKEN", "token")
err := CreateEnvAndSecretFile(envFile, secretFile, []string{"GITHUB_TOKEN"})
assert.NoError(t, err)
// The env file must be parseable, which is what act >= 0.2.89 requires.
env, err := godotenv.Read(envFile)
assert.NoError(t, err)
assert.Equal(t, "kept", env["HARNESS_GHA_TEST"])
assert.NotContains(t, env, "cache-hit")
assert.NotContains(t, env, "node-version")
assert.NotContains(t, env, "PLUGIN_USES")
assert.NotContains(t, env, "GITHUB_TOKEN")
secretsEnv, err := godotenv.Read(secretFile)
assert.NoError(t, err)
assert.Equal(t, "token", secretsEnv["GITHUB_TOKEN"])
}