From ef100db690308c570e01b8653c604f198d2f75e8 Mon Sep 17 00:00:00 2001 From: Shunsuke Suzuki Date: Fri, 17 Nov 2023 10:29:01 +0900 Subject: [PATCH] Refactor package structure (#226) * refactor: move code to controller package * refactor: split packages --- pkg/cli/deny_read_all_policy_internal_test.go | 82 ------------------ .../deny_write_all_policy_internal_test.go | 82 ------------------ .../job_permissions_policy_internal_test.go | 75 ---------------- pkg/cli/run.go | 72 +--------------- pkg/{cli => config}/config.go | 8 +- pkg/controller/controller.go | 86 +++++++++++++++++++ ...should_be_full_length_commit_sha_policy.go | 10 ++- ...d_be_full_length_commit_sha_policy_test.go | 38 ++++---- pkg/{cli => policy}/deny_inherit_secrets.go | 6 +- .../deny_inherit_secrets_internal_test.go | 42 ++++----- .../deny_job_container_latest_image.go | 6 +- .../deny_job_container_latest_image_test.go | 46 +++++----- pkg/{cli => policy}/deny_read_all_policy.go | 6 +- .../deny_read_all_policy_internal_test.go | 68 +++++++++++++++ pkg/{cli => policy}/deny_write_all_policy.go | 6 +- .../deny_write_all_policy_internal_test.go | 68 +++++++++++++++ pkg/{cli => policy}/job_permissions_policy.go | 6 +- .../job_permissions_policy_internal_test.go | 68 +++++++++++++++ pkg/{cli => policy}/job_secrets_policy.go | 8 +- .../job_secrets_policy_test.go | 56 ++++++------ pkg/{cli => policy}/job_secrets_test.go | 6 +- .../workflow_secrets_policy.go | 6 +- .../workflow_secrets_policy_test.go | 38 ++++---- pkg/{cli => workflow}/job_secrets.go | 2 +- pkg/{cli => workflow}/list_workflows.go | 4 +- pkg/{cli => workflow}/permissions.go | 2 +- pkg/{cli => workflow}/read_workflow.go | 4 +- pkg/{cli => workflow}/workflow.go | 2 +- 28 files changed, 453 insertions(+), 450 deletions(-) delete mode 100644 pkg/cli/deny_read_all_policy_internal_test.go delete mode 100644 pkg/cli/deny_write_all_policy_internal_test.go delete mode 100644 pkg/cli/job_permissions_policy_internal_test.go rename pkg/{cli => config}/config.go (90%) create mode 100644 pkg/controller/controller.go rename pkg/{cli => policy}/action_ref_should_be_full_length_commit_sha_policy.go (87%) rename pkg/{cli => policy}/action_ref_should_be_full_length_commit_sha_policy_test.go (72%) rename pkg/{cli => policy}/deny_inherit_secrets.go (76%) rename pkg/{cli => policy}/deny_inherit_secrets_internal_test.go (55%) rename pkg/{cli => policy}/deny_job_container_latest_image.go (82%) rename pkg/{cli => policy}/deny_job_container_latest_image_test.go (53%) rename pkg/{cli => policy}/deny_read_all_policy.go (79%) create mode 100644 pkg/policy/deny_read_all_policy_internal_test.go rename pkg/{cli => policy}/deny_write_all_policy.go (79%) create mode 100644 pkg/policy/deny_write_all_policy_internal_test.go rename pkg/{cli => policy}/job_permissions_policy.go (81%) create mode 100644 pkg/policy/job_permissions_policy_internal_test.go rename pkg/{cli => policy}/job_secrets_policy.go (83%) rename pkg/{cli => policy}/job_secrets_policy_test.go (65%) rename pkg/{cli => policy}/job_secrets_test.go (85%) rename pkg/{cli => policy}/workflow_secrets_policy.go (85%) rename pkg/{cli => policy}/workflow_secrets_policy_test.go (66%) rename pkg/{cli => workflow}/job_secrets.go (98%) rename pkg/{cli => workflow}/list_workflows.go (85%) rename pkg/{cli => workflow}/permissions.go (99%) rename pkg/{cli => workflow}/read_workflow.go (80%) rename pkg/{cli => workflow}/workflow.go (96%) diff --git a/pkg/cli/deny_read_all_policy_internal_test.go b/pkg/cli/deny_read_all_policy_internal_test.go deleted file mode 100644 index 2b909d7..0000000 --- a/pkg/cli/deny_read_all_policy_internal_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package cli //nolint:dupl - -import ( - "context" - "testing" - - "github.com/sirupsen/logrus" -) - -func TestDenyReadAllPermissionPolicy_Apply(t *testing.T) { //nolint:funlen - t.Parallel() - data := []struct { - name string - cfg *Config - wf *Workflow - isErr bool - }{ - { - name: "don't use read-all", - cfg: &Config{}, - wf: &Workflow{ - Permissions: &Permissions{ - m: map[string]string{}, - }, - Jobs: map[string]*Job{ - "foo": { - Permissions: &Permissions{ - readAll: true, - }, - }, - }, - }, - isErr: true, - }, - { - name: "job permissions is null and workflow permissions is read-all", - cfg: &Config{}, - wf: &Workflow{ - Permissions: &Permissions{ - readAll: true, - }, - Jobs: map[string]*Job{ - "foo": {}, - }, - }, - isErr: true, - }, - { - name: "pass", - cfg: &Config{}, - wf: &Workflow{ - Jobs: map[string]*Job{ - "foo": { - Permissions: &Permissions{ - m: map[string]string{ - "contents": "read", - }, - }, - }, - }, - }, - }, - } - policy := &DenyReadAllPermissionPolicy{} - logE := logrus.NewEntry(logrus.New()) - ctx := context.Background() - for _, d := range data { - d := d - t.Run(d.name, func(t *testing.T) { - t.Parallel() - if err := policy.Apply(ctx, logE, d.cfg, d.wf); err != nil { - if !d.isErr { - t.Fatal(err) - } - return - } - if d.isErr { - t.Fatal("error must be returned") - } - }) - } -} diff --git a/pkg/cli/deny_write_all_policy_internal_test.go b/pkg/cli/deny_write_all_policy_internal_test.go deleted file mode 100644 index 28a00da..0000000 --- a/pkg/cli/deny_write_all_policy_internal_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package cli //nolint:dupl - -import ( - "context" - "testing" - - "github.com/sirupsen/logrus" -) - -func TestDenyWriteAllPermissionPolicy_Apply(t *testing.T) { //nolint:funlen - t.Parallel() - data := []struct { - name string - cfg *Config - wf *Workflow - isErr bool - }{ - { - name: "don't use write-all", - cfg: &Config{}, - wf: &Workflow{ - Permissions: &Permissions{ - m: map[string]string{}, - }, - Jobs: map[string]*Job{ - "foo": { - Permissions: &Permissions{ - writeAll: true, - }, - }, - }, - }, - isErr: true, - }, - { - name: "job permissions is null and workflow permissions is write-all", - cfg: &Config{}, - wf: &Workflow{ - Permissions: &Permissions{ - writeAll: true, - }, - Jobs: map[string]*Job{ - "foo": {}, - }, - }, - isErr: true, - }, - { - name: "pass", - cfg: &Config{}, - wf: &Workflow{ - Jobs: map[string]*Job{ - "foo": { - Permissions: &Permissions{ - m: map[string]string{ - "contents": "read", - }, - }, - }, - }, - }, - }, - } - policy := &DenyWriteAllPermissionPolicy{} - logE := logrus.NewEntry(logrus.New()) - ctx := context.Background() - for _, d := range data { - d := d - t.Run(d.name, func(t *testing.T) { - t.Parallel() - if err := policy.Apply(ctx, logE, d.cfg, d.wf); err != nil { - if !d.isErr { - t.Fatal(err) - } - return - } - if d.isErr { - t.Fatal("error must be returned") - } - }) - } -} diff --git a/pkg/cli/job_permissions_policy_internal_test.go b/pkg/cli/job_permissions_policy_internal_test.go deleted file mode 100644 index 0703da2..0000000 --- a/pkg/cli/job_permissions_policy_internal_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package cli - -import ( - "context" - "testing" - - "github.com/sirupsen/logrus" -) - -func TestJobPermissionsPolicy_Apply(t *testing.T) { //nolint:funlen - t.Parallel() - data := []struct { - name string - cfg *Config - wf *Workflow - isErr bool - }{ - { - name: "workflow permissions is empty", - cfg: &Config{}, - wf: &Workflow{ - Permissions: &Permissions{ - m: map[string]string{}, - }, - Jobs: map[string]*Job{ - "foo": {}, - "bar": {}, - }, - }, - }, - { - name: "workflow has only one job", - cfg: &Config{}, - wf: &Workflow{ - Permissions: &Permissions{ - m: map[string]string{ - "contents": "read", - }, - }, - Jobs: map[string]*Job{ - "foo": {}, - }, - }, - }, - { - name: "job should have permissions", - cfg: &Config{}, - wf: &Workflow{ - Jobs: map[string]*Job{ - "foo": {}, - "bar": {}, - }, - }, - isErr: true, - }, - } - policy := &JobPermissionsPolicy{} - logE := logrus.NewEntry(logrus.New()) - ctx := context.Background() - for _, d := range data { - d := d - t.Run(d.name, func(t *testing.T) { - t.Parallel() - if err := policy.Apply(ctx, logE, d.cfg, d.wf); err != nil { - if !d.isErr { - t.Fatal(err) - } - return - } - if d.isErr { - t.Fatal("error must be returned") - } - }) - } -} diff --git a/pkg/cli/run.go b/pkg/cli/run.go index bf7b6f7..742625e 100644 --- a/pkg/cli/run.go +++ b/pkg/cli/run.go @@ -1,13 +1,10 @@ package cli import ( - "context" - "errors" "os" - "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/ghalint/pkg/controller" "github.com/suzuki-shunsuke/ghalint/pkg/log" - "github.com/suzuki-shunsuke/logrus-error/logerr" "github.com/urfave/cli/v2" ) @@ -18,70 +15,7 @@ func (r *Runner) Run(ctx *cli.Context) error { log.SetColor(color, logE) } - return r.run(ctx.Context, logE) -} - -func (r *Runner) run(ctx context.Context, logE *logrus.Entry) error { - cfg := &Config{} - if cfgFilePath := findConfig(r.fs); cfgFilePath != "" { - if err := readConfig(r.fs, cfg, cfgFilePath); err != nil { - logE.WithError(err).Error("read a configuration file") - return err - } - } - if err := validateConfig(cfg); err != nil { - logE.WithError(err).Error("validate a configuration file") - return err - } - filePaths, err := listWorkflows(r.fs) - if err != nil { - logE.Error(err) - return err - } - policies := []Policy{ - &JobPermissionsPolicy{}, - NewWorkflowSecretsPolicy(), - NewJobSecretsPolicy(), - &DenyReadAllPermissionPolicy{}, - &DenyWriteAllPermissionPolicy{}, - &DenyInheritSecretsPolicy{}, - &DenyJobContainerLatestImagePolicy{}, - NewActionRefShouldBeSHA1Policy(), - } - failed := false - for _, filePath := range filePaths { - logE := logE.WithField("workflow_file_path", filePath) - if r.validateWorkflow(ctx, logE, cfg, policies, filePath) { - failed = true - } - } - if failed { - return errors.New("some workflow files are invalid") - } - return nil -} - -func (r *Runner) validateWorkflow(ctx context.Context, logE *logrus.Entry, cfg *Config, policies []Policy, filePath string) bool { - wf := &Workflow{ - FilePath: filePath, - } - if err := readWorkflow(r.fs, filePath, wf); err != nil { - logerr.WithError(logE, err).Error("read a workflow file") - return true - } - - failed := false - for _, policy := range policies { - logE := logE.WithField("policy_name", policy.Name()) - if err := policy.Apply(ctx, logE, cfg, wf); err != nil { - failed = true - continue - } - } - return failed -} + ctrl := controller.New(r.fs) -type Policy interface { - Name() string - Apply(ctx context.Context, logE *logrus.Entry, cfg *Config, wf *Workflow) error + return ctrl.Run(ctx.Context, logE) //nolint:wrapcheck } diff --git a/pkg/cli/config.go b/pkg/config/config.go similarity index 90% rename from pkg/cli/config.go rename to pkg/config/config.go index 7e30b65..aa5dd18 100644 --- a/pkg/cli/config.go +++ b/pkg/config/config.go @@ -1,4 +1,4 @@ -package cli +package config import ( "errors" @@ -19,7 +19,7 @@ type Exclude struct { ActionName string `yaml:"action_name"` } -func findConfig(fs afero.Fs) string { +func Find(fs afero.Fs) string { for _, filePath := range []string{"ghalint.yaml", ".ghalint.yaml", "ghalint.yml", ".ghalint.yml"} { if _, err := fs.Stat(filePath); err == nil { return filePath @@ -28,7 +28,7 @@ func findConfig(fs afero.Fs) string { return "" } -func readConfig(fs afero.Fs, cfg *Config, filePath string) error { +func Read(fs afero.Fs, cfg *Config, filePath string) error { f, err := fs.Open(filePath) if err != nil { return fmt.Errorf("open a configuration file: %w", err) @@ -40,7 +40,7 @@ func readConfig(fs afero.Fs, cfg *Config, filePath string) error { return nil } -func validateConfig(cfg *Config) error { +func Validate(cfg *Config) error { for _, exclude := range cfg.Excludes { if exclude.PolicyName == "" { return errors.New(`policy_name is required`) diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go new file mode 100644 index 0000000..920a3fb --- /dev/null +++ b/pkg/controller/controller.go @@ -0,0 +1,86 @@ +package controller + +import ( + "context" + "errors" + "fmt" + + "github.com/sirupsen/logrus" + "github.com/spf13/afero" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/policy" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" + "github.com/suzuki-shunsuke/logrus-error/logerr" +) + +type Controller struct { + fs afero.Fs +} + +func New(fs afero.Fs) *Controller { + return &Controller{ + fs: fs, + } +} + +func (c *Controller) Run(ctx context.Context, logE *logrus.Entry) error { + cfg := &config.Config{} + if cfgFilePath := config.Find(c.fs); cfgFilePath != "" { + if err := config.Read(c.fs, cfg, cfgFilePath); err != nil { + return fmt.Errorf("read a configuration file: %w", err) + } + } + if err := config.Validate(cfg); err != nil { + return fmt.Errorf("validate a configuration file: %w", err) + } + filePaths, err := workflow.List(c.fs) + if err != nil { + return fmt.Errorf("find workflow files: %w", err) + } + policies := []Policy{ + &policy.JobPermissionsPolicy{}, + policy.NewWorkflowSecretsPolicy(), + policy.NewJobSecretsPolicy(), + &policy.DenyReadAllPermissionPolicy{}, + &policy.DenyWriteAllPermissionPolicy{}, + &policy.DenyInheritSecretsPolicy{}, + &policy.DenyJobContainerLatestImagePolicy{}, + policy.NewActionRefShouldBeSHA1Policy(), + } + failed := false + for _, filePath := range filePaths { + logE := logE.WithField("workflow_file_path", filePath) + if c.validateWorkflow(ctx, logE, cfg, policies, filePath) { + failed = true + } + } + if failed { + return errors.New("some workflow files are invalid") + } + return nil +} + +func (c *Controller) validateWorkflow(ctx context.Context, logE *logrus.Entry, cfg *config.Config, policies []Policy, filePath string) bool { + wf := &workflow.Workflow{ + FilePath: filePath, + } + if err := workflow.Read(c.fs, filePath, wf); err != nil { + logerr.WithError(logE, err).Error("read a workflow file") + return true + } + + failed := false + for _, policy := range policies { + logE := logE.WithField("policy_name", policy.Name()) + if err := policy.Apply(ctx, logE, cfg, wf); err != nil { + failed = true + continue + } + } + return failed +} + +type Policy interface { + Name() string + Apply(ctx context.Context, logE *logrus.Entry, cfg *config.Config, wf *workflow.Workflow) error +} diff --git a/pkg/cli/action_ref_should_be_full_length_commit_sha_policy.go b/pkg/policy/action_ref_should_be_full_length_commit_sha_policy.go similarity index 87% rename from pkg/cli/action_ref_should_be_full_length_commit_sha_policy.go rename to pkg/policy/action_ref_should_be_full_length_commit_sha_policy.go index 4187986..218c3dd 100644 --- a/pkg/cli/action_ref_should_be_full_length_commit_sha_policy.go +++ b/pkg/policy/action_ref_should_be_full_length_commit_sha_policy.go @@ -1,4 +1,4 @@ -package cli +package policy import ( "context" @@ -7,6 +7,8 @@ import ( "strings" "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" ) type ActionRefShouldBeSHA1Policy struct { @@ -23,7 +25,7 @@ func (p *ActionRefShouldBeSHA1Policy) Name() string { return "action_ref_should_be_full_length_commit_sha" } -func (p *ActionRefShouldBeSHA1Policy) excluded(action string, excludes []*Exclude) bool { +func (p *ActionRefShouldBeSHA1Policy) excluded(action string, excludes []*config.Exclude) bool { for _, exclude := range excludes { if exclude.PolicyName != p.Name() { continue @@ -35,7 +37,7 @@ func (p *ActionRefShouldBeSHA1Policy) excluded(action string, excludes []*Exclud return false } -func (p *ActionRefShouldBeSHA1Policy) Apply(ctx context.Context, logE *logrus.Entry, cfg *Config, wf *Workflow) error { +func (p *ActionRefShouldBeSHA1Policy) Apply(ctx context.Context, logE *logrus.Entry, cfg *config.Config, wf *workflow.Workflow) error { failed := false for jobName, job := range wf.Jobs { logE := logE.WithField("job_name", jobName) @@ -49,7 +51,7 @@ func (p *ActionRefShouldBeSHA1Policy) Apply(ctx context.Context, logE *logrus.En return nil } -func (p *ActionRefShouldBeSHA1Policy) applyJob(logE *logrus.Entry, cfg *Config, job *Job) bool { +func (p *ActionRefShouldBeSHA1Policy) applyJob(logE *logrus.Entry, cfg *config.Config, job *workflow.Job) bool { if action := p.checkUses(job.Uses); action != "" { if p.excluded(action, cfg.Excludes) { return false diff --git a/pkg/cli/action_ref_should_be_full_length_commit_sha_policy_test.go b/pkg/policy/action_ref_should_be_full_length_commit_sha_policy_test.go similarity index 72% rename from pkg/cli/action_ref_should_be_full_length_commit_sha_policy_test.go rename to pkg/policy/action_ref_should_be_full_length_commit_sha_policy_test.go index 3e3fb2a..8fd8b6c 100644 --- a/pkg/cli/action_ref_should_be_full_length_commit_sha_policy_test.go +++ b/pkg/policy/action_ref_should_be_full_length_commit_sha_policy_test.go @@ -1,25 +1,27 @@ -package cli_test +package policy_test import ( "context" "testing" "github.com/sirupsen/logrus" - "github.com/suzuki-shunsuke/ghalint/pkg/cli" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/policy" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" ) func TestActionRefShouldBeSHA1Policy_Apply(t *testing.T) { //nolint:funlen t.Parallel() data := []struct { name string - cfg *cli.Config - wf *cli.Workflow + cfg *config.Config + wf *workflow.Workflow isErr bool }{ { name: "exclude", - cfg: &cli.Config{ - Excludes: []*cli.Exclude{ + cfg: &config.Config{ + Excludes: []*config.Exclude{ { PolicyName: "action_ref_should_be_full_length_commit_sha", ActionName: "slsa-framework/slsa-github-generator", @@ -30,10 +32,10 @@ func TestActionRefShouldBeSHA1Policy_Apply(t *testing.T) { //nolint:funlen }, }, }, - wf: &cli.Workflow{ - Jobs: map[string]*cli.Job{ + wf: &workflow.Workflow{ + Jobs: map[string]*workflow.Job{ "release": { - Steps: []*cli.Step{ + Steps: []*workflow.Step{ { Uses: "slsa-framework/slsa-github-generator@v1.5.0", }, @@ -48,18 +50,18 @@ func TestActionRefShouldBeSHA1Policy_Apply(t *testing.T) { //nolint:funlen { name: "step error", isErr: true, - cfg: &cli.Config{ - Excludes: []*cli.Exclude{ + cfg: &config.Config{ + Excludes: []*config.Exclude{ { PolicyName: "action_ref_should_be_full_length_commit_sha", ActionName: "actions/checkout", }, }, }, - wf: &cli.Workflow{ - Jobs: map[string]*cli.Job{ + wf: &workflow.Workflow{ + Jobs: map[string]*workflow.Job{ "release": { - Steps: []*cli.Step{ + Steps: []*workflow.Step{ { Uses: "slsa-framework/slsa-github-generator@v1.5.0", ID: "generate", @@ -73,9 +75,9 @@ func TestActionRefShouldBeSHA1Policy_Apply(t *testing.T) { //nolint:funlen { name: "job error", isErr: true, - cfg: &cli.Config{}, - wf: &cli.Workflow{ - Jobs: map[string]*cli.Job{ + cfg: &config.Config{}, + wf: &workflow.Workflow{ + Jobs: map[string]*workflow.Job{ "release": { Uses: "suzuki-shunsuke/go-release-workflow/.github/workflows/release.yaml@v0.4.4", }, @@ -83,7 +85,7 @@ func TestActionRefShouldBeSHA1Policy_Apply(t *testing.T) { //nolint:funlen }, }, } - p := cli.NewActionRefShouldBeSHA1Policy() + p := policy.NewActionRefShouldBeSHA1Policy() ctx := context.Background() logE := logrus.NewEntry(logrus.New()) for _, d := range data { diff --git a/pkg/cli/deny_inherit_secrets.go b/pkg/policy/deny_inherit_secrets.go similarity index 76% rename from pkg/cli/deny_inherit_secrets.go rename to pkg/policy/deny_inherit_secrets.go index 83391dd..74d9850 100644 --- a/pkg/cli/deny_inherit_secrets.go +++ b/pkg/policy/deny_inherit_secrets.go @@ -1,10 +1,12 @@ -package cli +package policy import ( "context" "errors" "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" ) type DenyInheritSecretsPolicy struct{} @@ -13,7 +15,7 @@ func (p *DenyInheritSecretsPolicy) Name() string { return "deny_inherit_secrets" } -func (p *DenyInheritSecretsPolicy) Apply(ctx context.Context, logE *logrus.Entry, cfg *Config, wf *Workflow) error { +func (p *DenyInheritSecretsPolicy) Apply(ctx context.Context, logE *logrus.Entry, cfg *config.Config, wf *workflow.Workflow) error { failed := false for jobName, job := range wf.Jobs { logE := logE.WithField("job_name", jobName) diff --git a/pkg/cli/deny_inherit_secrets_internal_test.go b/pkg/policy/deny_inherit_secrets_internal_test.go similarity index 55% rename from pkg/cli/deny_inherit_secrets_internal_test.go rename to pkg/policy/deny_inherit_secrets_internal_test.go index daa1a19..ada33aa 100644 --- a/pkg/cli/deny_inherit_secrets_internal_test.go +++ b/pkg/policy/deny_inherit_secrets_internal_test.go @@ -1,46 +1,36 @@ -package cli +package policy import ( "context" "testing" "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" + "gopkg.in/yaml.v3" ) func TestDenyInheritSecretsPolicy_Apply(t *testing.T) { t.Parallel() data := []struct { name string - cfg *Config - wf *Workflow + cfg *config.Config + wf string isErr bool }{ { name: "error", - wf: &Workflow{ - Jobs: map[string]*Job{ - "release": { - Secrets: &JobSecrets{ - inherit: true, - }, - }, - }, - }, + wf: `jobs: + releases: + secrets: inherit`, isErr: true, }, { name: "pass", - wf: &Workflow{ - Jobs: map[string]*Job{ - "release": { - Secrets: &JobSecrets{ - m: map[string]string{ - "foo": "${{secrets.API_KEY}}", - }, - }, - }, - }, - }, + wf: `jobs: + release: + secrets: + foo: ${{secrets.API_KEY}}`, }, } p := &DenyInheritSecretsPolicy{} @@ -50,7 +40,11 @@ func TestDenyInheritSecretsPolicy_Apply(t *testing.T) { d := d t.Run(d.name, func(t *testing.T) { t.Parallel() - if err := p.Apply(ctx, logE, d.cfg, d.wf); err != nil { + wf := &workflow.Workflow{} + if err := yaml.Unmarshal([]byte(d.wf), wf); err != nil { + t.Fatal(err) + } + if err := p.Apply(ctx, logE, d.cfg, wf); err != nil { if d.isErr { return } diff --git a/pkg/cli/deny_job_container_latest_image.go b/pkg/policy/deny_job_container_latest_image.go similarity index 82% rename from pkg/cli/deny_job_container_latest_image.go rename to pkg/policy/deny_job_container_latest_image.go index 15bed05..2f41d65 100644 --- a/pkg/cli/deny_job_container_latest_image.go +++ b/pkg/policy/deny_job_container_latest_image.go @@ -1,4 +1,4 @@ -package cli +package policy import ( "context" @@ -6,6 +6,8 @@ import ( "strings" "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" ) type DenyJobContainerLatestImagePolicy struct{} @@ -14,7 +16,7 @@ func (p *DenyJobContainerLatestImagePolicy) Name() string { return "deny_job_container_latest_image" } -func (p *DenyJobContainerLatestImagePolicy) Apply(ctx context.Context, logE *logrus.Entry, cfg *Config, wf *Workflow) error { +func (p *DenyJobContainerLatestImagePolicy) Apply(ctx context.Context, logE *logrus.Entry, cfg *config.Config, wf *workflow.Workflow) error { failed := false for jobName, job := range wf.Jobs { logE := logE.WithField("job_name", jobName) diff --git a/pkg/cli/deny_job_container_latest_image_test.go b/pkg/policy/deny_job_container_latest_image_test.go similarity index 53% rename from pkg/cli/deny_job_container_latest_image_test.go rename to pkg/policy/deny_job_container_latest_image_test.go index fc9b76c..89d24ac 100644 --- a/pkg/cli/deny_job_container_latest_image_test.go +++ b/pkg/policy/deny_job_container_latest_image_test.go @@ -1,29 +1,31 @@ -package cli_test +package policy_test import ( "context" "testing" "github.com/sirupsen/logrus" - "github.com/suzuki-shunsuke/ghalint/pkg/cli" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/policy" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" ) func TestDenyJobContainerLatestImagePolicy_Apply(t *testing.T) { //nolint:funlen t.Parallel() data := []struct { name string - cfg *cli.Config - wf *cli.Workflow + cfg *config.Config + wf *workflow.Workflow isErr bool }{ { name: "pass", - cfg: &cli.Config{}, - wf: &cli.Workflow{ - Jobs: map[string]*cli.Job{ + cfg: &config.Config{}, + wf: &workflow.Workflow{ + Jobs: map[string]*workflow.Job{ "foo": {}, "bar": { - Container: &cli.Container{ + Container: &workflow.Container{ Image: "node:18", }, }, @@ -32,11 +34,11 @@ func TestDenyJobContainerLatestImagePolicy_Apply(t *testing.T) { //nolint:funlen }, { name: "job container should have image", - cfg: &cli.Config{}, - wf: &cli.Workflow{ - Jobs: map[string]*cli.Job{ + cfg: &config.Config{}, + wf: &workflow.Workflow{ + Jobs: map[string]*workflow.Job{ "bar": { - Container: &cli.Container{}, + Container: &workflow.Container{}, }, }, }, @@ -44,11 +46,11 @@ func TestDenyJobContainerLatestImagePolicy_Apply(t *testing.T) { //nolint:funlen }, { name: "job container image should have tag", - cfg: &cli.Config{}, - wf: &cli.Workflow{ - Jobs: map[string]*cli.Job{ + cfg: &config.Config{}, + wf: &workflow.Workflow{ + Jobs: map[string]*workflow.Job{ "bar": { - Container: &cli.Container{ + Container: &workflow.Container{ Image: "node", }, }, @@ -58,11 +60,11 @@ func TestDenyJobContainerLatestImagePolicy_Apply(t *testing.T) { //nolint:funlen }, { name: "latest", - cfg: &cli.Config{}, - wf: &cli.Workflow{ - Jobs: map[string]*cli.Job{ + cfg: &config.Config{}, + wf: &workflow.Workflow{ + Jobs: map[string]*workflow.Job{ "bar": { - Container: &cli.Container{ + Container: &workflow.Container{ Image: "node:latest", }, }, @@ -71,14 +73,14 @@ func TestDenyJobContainerLatestImagePolicy_Apply(t *testing.T) { //nolint:funlen isErr: true, }, } - policy := &cli.DenyJobContainerLatestImagePolicy{} + p := &policy.DenyJobContainerLatestImagePolicy{} logE := logrus.NewEntry(logrus.New()) ctx := context.Background() for _, d := range data { d := d t.Run(d.name, func(t *testing.T) { t.Parallel() - if err := policy.Apply(ctx, logE, d.cfg, d.wf); err != nil { + if err := p.Apply(ctx, logE, d.cfg, d.wf); err != nil { if !d.isErr { t.Fatal(err) } diff --git a/pkg/cli/deny_read_all_policy.go b/pkg/policy/deny_read_all_policy.go similarity index 79% rename from pkg/cli/deny_read_all_policy.go rename to pkg/policy/deny_read_all_policy.go index 356c51d..ed7fcb5 100644 --- a/pkg/cli/deny_read_all_policy.go +++ b/pkg/policy/deny_read_all_policy.go @@ -1,10 +1,12 @@ -package cli +package policy import ( "context" "errors" "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" ) type DenyReadAllPermissionPolicy struct{} @@ -13,7 +15,7 @@ func (p *DenyReadAllPermissionPolicy) Name() string { return "deny_read_all_permission" } -func (p *DenyReadAllPermissionPolicy) Apply(ctx context.Context, logE *logrus.Entry, cfg *Config, wf *Workflow) error { +func (p *DenyReadAllPermissionPolicy) Apply(ctx context.Context, logE *logrus.Entry, cfg *config.Config, wf *workflow.Workflow) error { failed := false wfReadAll := wf.Permissions.ReadAll() for jobName, job := range wf.Jobs { diff --git a/pkg/policy/deny_read_all_policy_internal_test.go b/pkg/policy/deny_read_all_policy_internal_test.go new file mode 100644 index 0000000..c736b46 --- /dev/null +++ b/pkg/policy/deny_read_all_policy_internal_test.go @@ -0,0 +1,68 @@ +package policy //nolint:dupl + +import ( + "context" + "testing" + + "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" + "gopkg.in/yaml.v3" +) + +func TestDenyReadAllPermissionPolicy_Apply(t *testing.T) { + t.Parallel() + data := []struct { + name string + cfg *config.Config + wf string + isErr bool + }{ + { + name: "don't use read-all", + cfg: &config.Config{}, + wf: `jobs: + foo: + permissions: read-all`, + isErr: true, + }, + { + name: "job permissions is null and workflow permissions is read-all", + cfg: &config.Config{}, + wf: `permissions: read-all +jobs: + foo: {}`, + isErr: true, + }, + { + name: "pass", + cfg: &config.Config{}, + wf: `jobs: + foo: + permissions: + contents: read`, + }, + } + policy := &DenyReadAllPermissionPolicy{} + logE := logrus.NewEntry(logrus.New()) + ctx := context.Background() + for _, d := range data { + d := d + t.Run(d.name, func(t *testing.T) { + t.Parallel() + wf := &workflow.Workflow{} + if err := yaml.Unmarshal([]byte(d.wf), wf); err != nil { + t.Fatal(err) + } + if err := policy.Apply(ctx, logE, d.cfg, wf); err != nil { + if !d.isErr { + t.Fatal(err) + } + return + } + if d.isErr { + t.Fatal("error must be returned") + } + }) + } +} diff --git a/pkg/cli/deny_write_all_policy.go b/pkg/policy/deny_write_all_policy.go similarity index 79% rename from pkg/cli/deny_write_all_policy.go rename to pkg/policy/deny_write_all_policy.go index 8c19d90..00d5e59 100644 --- a/pkg/cli/deny_write_all_policy.go +++ b/pkg/policy/deny_write_all_policy.go @@ -1,10 +1,12 @@ -package cli +package policy import ( "context" "errors" "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" ) type DenyWriteAllPermissionPolicy struct{} @@ -13,7 +15,7 @@ func (p *DenyWriteAllPermissionPolicy) Name() string { return "deny_write_all_permission" } -func (p *DenyWriteAllPermissionPolicy) Apply(ctx context.Context, logE *logrus.Entry, cfg *Config, wf *Workflow) error { +func (p *DenyWriteAllPermissionPolicy) Apply(ctx context.Context, logE *logrus.Entry, cfg *config.Config, wf *workflow.Workflow) error { failed := false wfWriteAll := wf.Permissions.WriteAll() for jobName, job := range wf.Jobs { diff --git a/pkg/policy/deny_write_all_policy_internal_test.go b/pkg/policy/deny_write_all_policy_internal_test.go new file mode 100644 index 0000000..d725c36 --- /dev/null +++ b/pkg/policy/deny_write_all_policy_internal_test.go @@ -0,0 +1,68 @@ +package policy //nolint:dupl + +import ( + "context" + "testing" + + "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" + "gopkg.in/yaml.v3" +) + +func TestDenyWriteAllPermissionPolicy_Apply(t *testing.T) { + t.Parallel() + data := []struct { + name string + cfg *config.Config + wf string + isErr bool + }{ + { + name: "don't use write-all", + cfg: &config.Config{}, + wf: `jobs: + foo: + permissions: write-all`, + isErr: true, + }, + { + name: "job permissions is null and workflow permissions is write-all", + cfg: &config.Config{}, + wf: `permissions: write-all +jobs: + foo: {}`, + isErr: true, + }, + { + name: "pass", + cfg: &config.Config{}, + wf: `jobs: + foo: + permissions: + contents: read`, + }, + } + policy := &DenyWriteAllPermissionPolicy{} + logE := logrus.NewEntry(logrus.New()) + ctx := context.Background() + for _, d := range data { + d := d + t.Run(d.name, func(t *testing.T) { + t.Parallel() + wf := &workflow.Workflow{} + if err := yaml.Unmarshal([]byte(d.wf), wf); err != nil { + t.Fatal(err) + } + if err := policy.Apply(ctx, logE, d.cfg, wf); err != nil { + if !d.isErr { + t.Fatal(err) + } + return + } + if d.isErr { + t.Fatal("error must be returned") + } + }) + } +} diff --git a/pkg/cli/job_permissions_policy.go b/pkg/policy/job_permissions_policy.go similarity index 81% rename from pkg/cli/job_permissions_policy.go rename to pkg/policy/job_permissions_policy.go index 075faaa..0548607 100644 --- a/pkg/cli/job_permissions_policy.go +++ b/pkg/policy/job_permissions_policy.go @@ -1,10 +1,12 @@ -package cli +package policy import ( "context" "errors" "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" ) type JobPermissionsPolicy struct{} @@ -13,7 +15,7 @@ func (p *JobPermissionsPolicy) Name() string { return "job_permissions" } -func (p *JobPermissionsPolicy) Apply(ctx context.Context, logE *logrus.Entry, cfg *Config, wf *Workflow) error { +func (p *JobPermissionsPolicy) Apply(ctx context.Context, logE *logrus.Entry, cfg *config.Config, wf *workflow.Workflow) error { failed := false wfPermissions := wf.Permissions.Permissions() if wfPermissions != nil && len(wfPermissions) == 0 { diff --git a/pkg/policy/job_permissions_policy_internal_test.go b/pkg/policy/job_permissions_policy_internal_test.go new file mode 100644 index 0000000..61fccbe --- /dev/null +++ b/pkg/policy/job_permissions_policy_internal_test.go @@ -0,0 +1,68 @@ +package policy + +import ( + "context" + "testing" + + "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" + "gopkg.in/yaml.v3" +) + +func TestJobPermissionsPolicy_Apply(t *testing.T) { + t.Parallel() + data := []struct { + name string + cfg *config.Config + wf string + isErr bool + }{ + { + name: "workflow permissions is empty", + cfg: &config.Config{}, + wf: `permissions: {} +jobs: + foo: {} + bar: {}`, + }, + { + name: "workflow has only one job", + cfg: &config.Config{}, + wf: `permissions: + contents: read +jobs: + foo: {}`, + }, + { + name: "job should have permissions", + cfg: &config.Config{}, + wf: `jobs: + foo: {} + bar: {}`, + isErr: true, + }, + } + policy := &JobPermissionsPolicy{} + logE := logrus.NewEntry(logrus.New()) + ctx := context.Background() + for _, d := range data { + d := d + t.Run(d.name, func(t *testing.T) { + t.Parallel() + wf := &workflow.Workflow{} + if err := yaml.Unmarshal([]byte(d.wf), wf); err != nil { + t.Fatal(err) + } + if err := policy.Apply(ctx, logE, d.cfg, wf); err != nil { + if !d.isErr { + t.Fatal(err) + } + return + } + if d.isErr { + t.Fatal("error must be returned") + } + }) + } +} diff --git a/pkg/cli/job_secrets_policy.go b/pkg/policy/job_secrets_policy.go similarity index 83% rename from pkg/cli/job_secrets_policy.go rename to pkg/policy/job_secrets_policy.go index 0e06a78..651f163 100644 --- a/pkg/cli/job_secrets_policy.go +++ b/pkg/policy/job_secrets_policy.go @@ -1,4 +1,4 @@ -package cli +package policy import ( "context" @@ -6,6 +6,8 @@ import ( "regexp" "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" ) type JobSecretsPolicy struct { @@ -24,7 +26,7 @@ func (p *JobSecretsPolicy) Name() string { return "job_secrets" } -func checkExcludes(policyName string, wf *Workflow, jobName string, cfg *Config) bool { +func checkExcludes(policyName string, wf *workflow.Workflow, jobName string, cfg *config.Config) bool { for _, exclude := range cfg.Excludes { if exclude.PolicyName == policyName && wf.FilePath == exclude.WorkflowFilePath && jobName == exclude.JobName { return true @@ -33,7 +35,7 @@ func checkExcludes(policyName string, wf *Workflow, jobName string, cfg *Config) return false } -func (p *JobSecretsPolicy) Apply(ctx context.Context, logE *logrus.Entry, cfg *Config, wf *Workflow) error { +func (p *JobSecretsPolicy) Apply(ctx context.Context, logE *logrus.Entry, cfg *config.Config, wf *workflow.Workflow) error { failed := false for jobName, job := range wf.Jobs { logE := logE.WithField("job_name", jobName) diff --git a/pkg/cli/job_secrets_policy_test.go b/pkg/policy/job_secrets_policy_test.go similarity index 65% rename from pkg/cli/job_secrets_policy_test.go rename to pkg/policy/job_secrets_policy_test.go index 030bc4c..a23ebd9 100644 --- a/pkg/cli/job_secrets_policy_test.go +++ b/pkg/policy/job_secrets_policy_test.go @@ -1,25 +1,27 @@ -package cli_test +package policy_test import ( "context" "testing" "github.com/sirupsen/logrus" - "github.com/suzuki-shunsuke/ghalint/pkg/cli" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/policy" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" ) func TestJobSecretsPolicy_Apply(t *testing.T) { //nolint:funlen t.Parallel() data := []struct { name string - cfg *cli.Config - wf *cli.Workflow + cfg *config.Config + wf *workflow.Workflow isErr bool }{ { name: "exclude", - cfg: &cli.Config{ - Excludes: []*cli.Exclude{ + cfg: &config.Config{ + Excludes: []*config.Exclude{ { PolicyName: "job_secrets", WorkflowFilePath: ".github/workflows/test.yaml", @@ -27,14 +29,14 @@ func TestJobSecretsPolicy_Apply(t *testing.T) { //nolint:funlen }, }, }, - wf: &cli.Workflow{ + wf: &workflow.Workflow{ FilePath: ".github/workflows/test.yaml", - Jobs: map[string]*cli.Job{ + Jobs: map[string]*workflow.Job{ "foo": { Env: map[string]string{ "GITHUB_TOKEN": "${{github.token}}", }, - Steps: []*cli.Step{ + Steps: []*workflow.Step{ {}, {}, }, @@ -44,15 +46,15 @@ func TestJobSecretsPolicy_Apply(t *testing.T) { //nolint:funlen }, { name: "job has only one step", - cfg: &cli.Config{}, - wf: &cli.Workflow{ + cfg: &config.Config{}, + wf: &workflow.Workflow{ FilePath: ".github/workflows/test.yaml", - Jobs: map[string]*cli.Job{ + Jobs: map[string]*workflow.Job{ "foo": { Env: map[string]string{ "GITHUB_TOKEN": "${{github.token}}", }, - Steps: []*cli.Step{ + Steps: []*workflow.Step{ {}, }, }, @@ -61,15 +63,15 @@ func TestJobSecretsPolicy_Apply(t *testing.T) { //nolint:funlen }, { name: "secret should not be set to job's env", - cfg: &cli.Config{}, - wf: &cli.Workflow{ + cfg: &config.Config{}, + wf: &workflow.Workflow{ FilePath: ".github/workflows/test.yaml", - Jobs: map[string]*cli.Job{ + Jobs: map[string]*workflow.Job{ "foo": { Env: map[string]string{ "GITHUB_TOKEN": "${{secrets.GITHUB_TOKEN}}", }, - Steps: []*cli.Step{ + Steps: []*workflow.Step{ {}, {}, }, @@ -80,15 +82,15 @@ func TestJobSecretsPolicy_Apply(t *testing.T) { //nolint:funlen }, { name: "github token should not be set to job's env", - cfg: &cli.Config{}, - wf: &cli.Workflow{ + cfg: &config.Config{}, + wf: &workflow.Workflow{ FilePath: ".github/workflows/test.yaml", - Jobs: map[string]*cli.Job{ + Jobs: map[string]*workflow.Job{ "foo": { Env: map[string]string{ "GITHUB_TOKEN": "${{github.token}}", }, - Steps: []*cli.Step{ + Steps: []*workflow.Step{ {}, {}, }, @@ -99,15 +101,15 @@ func TestJobSecretsPolicy_Apply(t *testing.T) { //nolint:funlen }, { name: "pass", - cfg: &cli.Config{}, - wf: &cli.Workflow{ + cfg: &config.Config{}, + wf: &workflow.Workflow{ FilePath: ".github/workflows/test.yaml", - Jobs: map[string]*cli.Job{ + Jobs: map[string]*workflow.Job{ "foo": { Env: map[string]string{ "FOO": "foo", }, - Steps: []*cli.Step{ + Steps: []*workflow.Step{ {}, {}, }, @@ -116,14 +118,14 @@ func TestJobSecretsPolicy_Apply(t *testing.T) { //nolint:funlen }, }, } - policy := cli.NewJobSecretsPolicy() + p := policy.NewJobSecretsPolicy() logE := logrus.NewEntry(logrus.New()) ctx := context.Background() for _, d := range data { d := d t.Run(d.name, func(t *testing.T) { t.Parallel() - if err := policy.Apply(ctx, logE, d.cfg, d.wf); err != nil { + if err := p.Apply(ctx, logE, d.cfg, d.wf); err != nil { if !d.isErr { t.Fatal(err) } diff --git a/pkg/cli/job_secrets_test.go b/pkg/policy/job_secrets_test.go similarity index 85% rename from pkg/cli/job_secrets_test.go rename to pkg/policy/job_secrets_test.go index 3e92520..726d0be 100644 --- a/pkg/cli/job_secrets_test.go +++ b/pkg/policy/job_secrets_test.go @@ -1,9 +1,9 @@ -package cli_test +package policy_test import ( "testing" - "github.com/suzuki-shunsuke/ghalint/pkg/cli" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" "gopkg.in/yaml.v3" ) @@ -28,7 +28,7 @@ func TestJobSecrets_UnmarshalYAML(t *testing.T) { d := d t.Run(d.name, func(t *testing.T) { t.Parallel() - js := &cli.JobSecrets{} + js := &workflow.JobSecrets{} if err := yaml.Unmarshal([]byte(d.yaml), js); err != nil { t.Fatal(err) } diff --git a/pkg/cli/workflow_secrets_policy.go b/pkg/policy/workflow_secrets_policy.go similarity index 85% rename from pkg/cli/workflow_secrets_policy.go rename to pkg/policy/workflow_secrets_policy.go index 99e7134..729bba8 100644 --- a/pkg/cli/workflow_secrets_policy.go +++ b/pkg/policy/workflow_secrets_policy.go @@ -1,4 +1,4 @@ -package cli +package policy import ( "context" @@ -6,6 +6,8 @@ import ( "regexp" "github.com/sirupsen/logrus" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" ) type WorkflowSecretsPolicy struct { @@ -24,7 +26,7 @@ func (p *WorkflowSecretsPolicy) Name() string { return "workflow_secrets" } -func (p *WorkflowSecretsPolicy) Apply(ctx context.Context, logE *logrus.Entry, cfg *Config, wf *Workflow) error { +func (p *WorkflowSecretsPolicy) Apply(ctx context.Context, logE *logrus.Entry, cfg *config.Config, wf *workflow.Workflow) error { if len(wf.Jobs) < 2 { //nolint:gomnd return nil } diff --git a/pkg/cli/workflow_secrets_policy_test.go b/pkg/policy/workflow_secrets_policy_test.go similarity index 66% rename from pkg/cli/workflow_secrets_policy_test.go rename to pkg/policy/workflow_secrets_policy_test.go index 6ad8367..c07e575 100644 --- a/pkg/cli/workflow_secrets_policy_test.go +++ b/pkg/policy/workflow_secrets_policy_test.go @@ -1,43 +1,45 @@ -package cli_test +package policy_test import ( "context" "testing" "github.com/sirupsen/logrus" - "github.com/suzuki-shunsuke/ghalint/pkg/cli" + "github.com/suzuki-shunsuke/ghalint/pkg/config" + "github.com/suzuki-shunsuke/ghalint/pkg/policy" + "github.com/suzuki-shunsuke/ghalint/pkg/workflow" ) func TestWorkflowSecretsPolicy_Apply(t *testing.T) { //nolint:funlen t.Parallel() data := []struct { name string - cfg *cli.Config - wf *cli.Workflow + cfg *config.Config + wf *workflow.Workflow isErr bool }{ { name: "workflow has only one job", - cfg: &cli.Config{}, - wf: &cli.Workflow{ + cfg: &config.Config{}, + wf: &workflow.Workflow{ FilePath: ".github/workflows/test.yaml", Env: map[string]string{ "GITHUB_TOKEN": "${{github.token}}", }, - Jobs: map[string]*cli.Job{ + Jobs: map[string]*workflow.Job{ "foo": {}, }, }, }, { name: "secret should not be set to workflow's env", - cfg: &cli.Config{}, - wf: &cli.Workflow{ + cfg: &config.Config{}, + wf: &workflow.Workflow{ FilePath: ".github/workflows/test.yaml", Env: map[string]string{ "GITHUB_TOKEN": "${{secrets.GITHUB_TOKEN}}", }, - Jobs: map[string]*cli.Job{ + Jobs: map[string]*workflow.Job{ "foo": {}, "bar": {}, }, @@ -46,13 +48,13 @@ func TestWorkflowSecretsPolicy_Apply(t *testing.T) { //nolint:funlen }, { name: "github token should not be set to workflow's env", - cfg: &cli.Config{}, - wf: &cli.Workflow{ + cfg: &config.Config{}, + wf: &workflow.Workflow{ FilePath: ".github/workflows/test.yaml", Env: map[string]string{ "GITHUB_TOKEN": "${{github.token}}", }, - Jobs: map[string]*cli.Job{ + Jobs: map[string]*workflow.Job{ "foo": {}, "bar": {}, }, @@ -61,27 +63,27 @@ func TestWorkflowSecretsPolicy_Apply(t *testing.T) { //nolint:funlen }, { name: "pass", - cfg: &cli.Config{}, - wf: &cli.Workflow{ + cfg: &config.Config{}, + wf: &workflow.Workflow{ FilePath: ".github/workflows/test.yaml", Env: map[string]string{ "FOO": "foo", }, - Jobs: map[string]*cli.Job{ + Jobs: map[string]*workflow.Job{ "foo": {}, "bar": {}, }, }, }, } - policy := cli.NewWorkflowSecretsPolicy() + p := policy.NewWorkflowSecretsPolicy() logE := logrus.NewEntry(logrus.New()) ctx := context.Background() for _, d := range data { d := d t.Run(d.name, func(t *testing.T) { t.Parallel() - if err := policy.Apply(ctx, logE, d.cfg, d.wf); err != nil { + if err := p.Apply(ctx, logE, d.cfg, d.wf); err != nil { if !d.isErr { t.Fatal(err) } diff --git a/pkg/cli/job_secrets.go b/pkg/workflow/job_secrets.go similarity index 98% rename from pkg/cli/job_secrets.go rename to pkg/workflow/job_secrets.go index ad69703..6a05841 100644 --- a/pkg/cli/job_secrets.go +++ b/pkg/workflow/job_secrets.go @@ -1,4 +1,4 @@ -package cli +package workflow import ( "errors" diff --git a/pkg/cli/list_workflows.go b/pkg/workflow/list_workflows.go similarity index 85% rename from pkg/cli/list_workflows.go rename to pkg/workflow/list_workflows.go index 33dd319..7365a31 100644 --- a/pkg/cli/list_workflows.go +++ b/pkg/workflow/list_workflows.go @@ -1,4 +1,4 @@ -package cli +package workflow import ( "fmt" @@ -6,7 +6,7 @@ import ( "github.com/spf13/afero" ) -func listWorkflows(fs afero.Fs) ([]string, error) { +func List(fs afero.Fs) ([]string, error) { files, err := afero.Glob(fs, ".github/workflows/*.yml") if err != nil { return nil, fmt.Errorf("find .github/workflows/*.yml: %w", err) diff --git a/pkg/cli/permissions.go b/pkg/workflow/permissions.go similarity index 99% rename from pkg/cli/permissions.go rename to pkg/workflow/permissions.go index 4f2f0f6..d9f730d 100644 --- a/pkg/cli/permissions.go +++ b/pkg/workflow/permissions.go @@ -1,4 +1,4 @@ -package cli +package workflow import ( "errors" diff --git a/pkg/cli/read_workflow.go b/pkg/workflow/read_workflow.go similarity index 80% rename from pkg/cli/read_workflow.go rename to pkg/workflow/read_workflow.go index 036eadf..18dd51e 100644 --- a/pkg/cli/read_workflow.go +++ b/pkg/workflow/read_workflow.go @@ -1,4 +1,4 @@ -package cli +package workflow import ( "fmt" @@ -7,7 +7,7 @@ import ( "gopkg.in/yaml.v3" ) -func readWorkflow(fs afero.Fs, p string, wf *Workflow) error { +func Read(fs afero.Fs, p string, wf *Workflow) error { f, err := fs.Open(p) if err != nil { return fmt.Errorf("open a workflow file: %w", err) diff --git a/pkg/cli/workflow.go b/pkg/workflow/workflow.go similarity index 96% rename from pkg/cli/workflow.go rename to pkg/workflow/workflow.go index b6dfac5..041cdbf 100644 --- a/pkg/cli/workflow.go +++ b/pkg/workflow/workflow.go @@ -1,4 +1,4 @@ -package cli +package workflow type Workflow struct { FilePath string `yaml:"-"`