feat: add option to bypass GHE for actions checkout (#1162)
* feat(#1161): add --through-action to assigned actions from GitHub * docs(flags): add --through-action and --through-action-token flags description * test(action, remote): add test case for ThroughAction * refactor(command): rename command from --through-action to --actions-from-github * refactor(command): rename command from --actions-from-github to --replace-ghe-action-with-github-com
This commit is contained in:
@@ -25,35 +25,37 @@ type Runner interface {
|
||||
|
||||
// Config contains the config for a new runner
|
||||
type Config struct {
|
||||
Actor string // the user that triggered the event
|
||||
Workdir string // path to working directory
|
||||
BindWorkdir bool // bind the workdir to the job container
|
||||
EventName string // name of event to run
|
||||
EventPath string // path to JSON file to use for event.json in containers
|
||||
DefaultBranch string // name of the main branch for this repository
|
||||
ReuseContainers bool // reuse containers to maintain state
|
||||
ForcePull bool // force pulling of the image, even if already present
|
||||
ForceRebuild bool // force rebuilding local docker image action
|
||||
LogOutput bool // log the output from docker run
|
||||
JSONLogger bool // use json or text logger
|
||||
Env map[string]string // env for containers
|
||||
Secrets map[string]string // list of secrets
|
||||
Token string // GitHub token
|
||||
InsecureSecrets bool // switch hiding output when printing to terminal
|
||||
Platforms map[string]string // list of platforms
|
||||
Privileged bool // use privileged mode
|
||||
UsernsMode string // user namespace to use
|
||||
ContainerArchitecture string // Desired OS/architecture platform for running containers
|
||||
ContainerDaemonSocket string // Path to Docker daemon socket
|
||||
UseGitIgnore bool // controls if paths in .gitignore should not be copied into container, default true
|
||||
GitHubInstance string // GitHub instance to use, default "github.com"
|
||||
ContainerCapAdd []string // list of kernel capabilities to add to the containers
|
||||
ContainerCapDrop []string // list of kernel capabilities to remove from the containers
|
||||
AutoRemove bool // controls if the container is automatically removed upon workflow completion
|
||||
ArtifactServerPath string // the path where the artifact server stores uploads
|
||||
ArtifactServerPort string // the port the artifact server binds to
|
||||
NoSkipCheckout bool // do not skip actions/checkout
|
||||
RemoteName string // remote name in local git repo config
|
||||
Actor string // the user that triggered the event
|
||||
Workdir string // path to working directory
|
||||
BindWorkdir bool // bind the workdir to the job container
|
||||
EventName string // name of event to run
|
||||
EventPath string // path to JSON file to use for event.json in containers
|
||||
DefaultBranch string // name of the main branch for this repository
|
||||
ReuseContainers bool // reuse containers to maintain state
|
||||
ForcePull bool // force pulling of the image, even if already present
|
||||
ForceRebuild bool // force rebuilding local docker image action
|
||||
LogOutput bool // log the output from docker run
|
||||
JSONLogger bool // use json or text logger
|
||||
Env map[string]string // env for containers
|
||||
Secrets map[string]string // list of secrets
|
||||
Token string // GitHub token
|
||||
InsecureSecrets bool // switch hiding output when printing to terminal
|
||||
Platforms map[string]string // list of platforms
|
||||
Privileged bool // use privileged mode
|
||||
UsernsMode string // user namespace to use
|
||||
ContainerArchitecture string // Desired OS/architecture platform for running containers
|
||||
ContainerDaemonSocket string // Path to Docker daemon socket
|
||||
UseGitIgnore bool // controls if paths in .gitignore should not be copied into container, default true
|
||||
GitHubInstance string // GitHub instance to use, default "github.com"
|
||||
ContainerCapAdd []string // list of kernel capabilities to add to the containers
|
||||
ContainerCapDrop []string // list of kernel capabilities to remove from the containers
|
||||
AutoRemove bool // controls if the container is automatically removed upon workflow completion
|
||||
ArtifactServerPath string // the path where the artifact server stores uploads
|
||||
ArtifactServerPort string // the port the artifact server binds to
|
||||
NoSkipCheckout bool // do not skip actions/checkout
|
||||
RemoteName string // remote name in local git repo config
|
||||
ReplaceGheActionWithGithubCom []string // Use actions from GitHub Enterprise instance to GitHub
|
||||
ReplaceGheActionTokenWithGithubCom string // Token of private action repo on GitHub.
|
||||
}
|
||||
|
||||
// Resolves the equivalent host path inside the container
|
||||
|
@@ -55,6 +55,14 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
|
||||
return nil
|
||||
}
|
||||
|
||||
sar.remoteAction.URL = sar.RunContext.Config.GitHubInstance
|
||||
for _, action := range sar.RunContext.Config.ReplaceGheActionWithGithubCom {
|
||||
if strings.EqualFold(fmt.Sprintf("%s/%s", sar.remoteAction.Org, sar.remoteAction.Repo), action) {
|
||||
sar.remoteAction.URL = "github.com"
|
||||
github.Token = sar.RunContext.Config.ReplaceGheActionTokenWithGithubCom
|
||||
}
|
||||
}
|
||||
|
||||
actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), strings.ReplaceAll(sar.Step.Uses, "/", "-"))
|
||||
gitClone := stepActionRemoteNewCloneExecutor(git.NewGitCloneExecutorInput{
|
||||
URL: sar.remoteAction.CloneURL(),
|
||||
|
@@ -256,6 +256,147 @@ func TestStepActionRemotePre(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepActionRemotePreThroughAction(t *testing.T) {
|
||||
table := []struct {
|
||||
name string
|
||||
stepModel *model.Step
|
||||
}{
|
||||
{
|
||||
name: "run-pre",
|
||||
stepModel: &model.Step{
|
||||
Uses: "org/repo/path@ref",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range table {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
clonedAction := false
|
||||
sarm := &stepActionRemoteMocks{}
|
||||
|
||||
origStepAtionRemoteNewCloneExecutor := stepActionRemoteNewCloneExecutor
|
||||
stepActionRemoteNewCloneExecutor = func(input git.NewGitCloneExecutorInput) common.Executor {
|
||||
return func(ctx context.Context) error {
|
||||
if input.URL == "https://github.com/org/repo" {
|
||||
clonedAction = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
defer (func() {
|
||||
stepActionRemoteNewCloneExecutor = origStepAtionRemoteNewCloneExecutor
|
||||
})()
|
||||
|
||||
sar := &stepActionRemote{
|
||||
Step: tt.stepModel,
|
||||
RunContext: &RunContext{
|
||||
Config: &Config{
|
||||
GitHubInstance: "https://enterprise.github.com",
|
||||
ReplaceGheActionWithGithubCom: []string{"org/repo"},
|
||||
},
|
||||
Run: &model.Run{
|
||||
JobID: "1",
|
||||
Workflow: &model.Workflow{
|
||||
Jobs: map[string]*model.Job{
|
||||
"1": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
readAction: sarm.readAction,
|
||||
}
|
||||
|
||||
suffixMatcher := func(suffix string) interface{} {
|
||||
return mock.MatchedBy(func(actionDir string) bool {
|
||||
return strings.HasSuffix(actionDir, suffix)
|
||||
})
|
||||
}
|
||||
|
||||
sarm.On("readAction", sar.Step, suffixMatcher("org-repo-path@ref"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil)
|
||||
|
||||
err := sar.pre()(ctx)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, true, clonedAction)
|
||||
|
||||
sarm.AssertExpectations(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepActionRemotePreThroughActionToken(t *testing.T) {
|
||||
table := []struct {
|
||||
name string
|
||||
stepModel *model.Step
|
||||
}{
|
||||
{
|
||||
name: "run-pre",
|
||||
stepModel: &model.Step{
|
||||
Uses: "org/repo/path@ref",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range table {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
clonedAction := false
|
||||
sarm := &stepActionRemoteMocks{}
|
||||
|
||||
origStepAtionRemoteNewCloneExecutor := stepActionRemoteNewCloneExecutor
|
||||
stepActionRemoteNewCloneExecutor = func(input git.NewGitCloneExecutorInput) common.Executor {
|
||||
return func(ctx context.Context) error {
|
||||
if input.URL == "https://github.com/org/repo" && input.Token == "PRIVATE_ACTIONS_TOKEN_ON_GITHUB" {
|
||||
clonedAction = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
defer (func() {
|
||||
stepActionRemoteNewCloneExecutor = origStepAtionRemoteNewCloneExecutor
|
||||
})()
|
||||
|
||||
sar := &stepActionRemote{
|
||||
Step: tt.stepModel,
|
||||
RunContext: &RunContext{
|
||||
Config: &Config{
|
||||
GitHubInstance: "https://enterprise.github.com",
|
||||
ReplaceGheActionWithGithubCom: []string{"org/repo"},
|
||||
ReplaceGheActionTokenWithGithubCom: "PRIVATE_ACTIONS_TOKEN_ON_GITHUB",
|
||||
},
|
||||
Run: &model.Run{
|
||||
JobID: "1",
|
||||
Workflow: &model.Workflow{
|
||||
Jobs: map[string]*model.Job{
|
||||
"1": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
readAction: sarm.readAction,
|
||||
}
|
||||
|
||||
suffixMatcher := func(suffix string) interface{} {
|
||||
return mock.MatchedBy(func(actionDir string) bool {
|
||||
return strings.HasSuffix(actionDir, suffix)
|
||||
})
|
||||
}
|
||||
|
||||
sarm.On("readAction", sar.Step, suffixMatcher("org-repo-path@ref"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil)
|
||||
|
||||
err := sar.pre()(ctx)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, true, clonedAction)
|
||||
|
||||
sarm.AssertExpectations(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepActionRemotePost(t *testing.T) {
|
||||
table := []struct {
|
||||
name string
|
||||
|
Reference in New Issue
Block a user