Skip to content

Commit

Permalink
Allow excluding just the action name
Browse files Browse the repository at this point in the history
Frizbee allowed to exclude the whole action name including the tag e.g.
`actions/checkout@v4`. But this is not user-friendly for cases where the
exclude would be upgraded over time as the exclude would have to be kept
in sync.

Let's also support the case where the exclude is just in the form of
`owner/action_name`.
  • Loading branch information
jhrozek committed Dec 19, 2023
1 parent b7db63b commit 889261e
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 6 deletions.
12 changes: 6 additions & 6 deletions pkg/ghactions/ghactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,15 @@ func ModifyReferencesInYAMLWithCache(
continue
}

if shouldExclude(cfg, v.Value) {
continue
}

act, ref, err := ParseActionReference(v.Value)
if err != nil {
return modified, fmt.Errorf("failed to parse action reference '%s': %w", v.Value, err)
}

if shouldExclude(cfg, v.Value, act) {
continue
}

var sum string

// Check if we have a cached value
Expand Down Expand Up @@ -253,9 +253,9 @@ func parseValue(val string) (*Action, error) {
}, nil
}

func shouldExclude(cfg *config.GHActions, input string) bool {
func shouldExclude(cfg *config.GHActions, fullValue, action string) bool {
for _, e := range cfg.Exclude {
if e == input {
if e == fullValue || e == action {
return true
}
}
Expand Down
123 changes: 123 additions & 0 deletions pkg/ghactions/ghactions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ package ghactions_test
import (
"context"
"os"
"strings"
"testing"

"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"

"github.com/stacklok/frizbee/internal/ghrest"
"github.com/stacklok/frizbee/pkg/config"
"github.com/stacklok/frizbee/pkg/ghactions"
)

Expand Down Expand Up @@ -236,3 +239,123 @@ func TestGetChecksum(t *testing.T) {
})
}
}

const (
workflowYAML = `
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v4
- name: setup go
uses: actions/setup-go@v4
`
)

func TestModifyReferencesInYAML(t *testing.T) {
t.Parallel()

tok := os.Getenv("GITHUB_TOKEN")

tests := []struct {
name string
mustContain []string
mustNotContain []string
wantErr bool
cfg *config.GHActions
}{
{
name: "modify all",
wantErr: false,
mustContain: []string{
" uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4",
" uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4",
},
mustNotContain: []string{
" uses: actions/checkout@v4",
" uses: actions/setup-go@v4",
},
cfg: &config.GHActions{
Filter: config.Filter{
Exclude: []string{},
},
},
},
{
name: "exclude full uses",
wantErr: false,
mustContain: []string{
" uses: actions/checkout@v4",
" uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4",
},
mustNotContain: []string{
" uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4",
" uses: actions/setup-go@v4",
},
cfg: &config.GHActions{
Filter: config.Filter{
Exclude: []string{
"actions/checkout@v4",
},
},
},
},
{
name: "exclude just the action name",
wantErr: false,
mustContain: []string{
" uses: actions/checkout@v4",
" uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4",
},
mustNotContain: []string{
" uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4",
" uses: actions/setup-go@v4",
},
cfg: &config.GHActions{
Filter: config.Filter{
Exclude: []string{
"actions/checkout",
},
},
},
},
}

for _, tt := range tests {
tt := tt

t.Run(tt.name, func(t *testing.T) {
t.Parallel()

ghcli := ghrest.NewGhRest(tok)

var root yaml.Node
err := yaml.Unmarshal([]byte(workflowYAML), &root)
require.NoError(t, err, "Error unmarshalling YAML, got %v", err)

got, err := ghactions.ModifyReferencesInYAML(context.Background(), ghcli, &root, tt.cfg)
if tt.wantErr {
require.Error(t, err, "Wanted error, got none")
require.Empty(t, got, "Wanted empty string, got %v", got)
return
}
require.NoError(t, err, "Wanted no error, got %v", err)

out, err := yaml.Marshal(&root)
require.NoError(t, err, "Error marhsalling YAML, got %v", err)
stringSlice := strings.Split(string(out), "\n")

require.Subset(t, stringSlice, tt.mustContain, "Expected %v to not appear in %v", tt.mustContain, stringSlice)
require.NotSubset(t, stringSlice, tt.mustNotContain, "Expected %v to not appear in %v", tt.mustNotContain, stringSlice)
})
}
}

0 comments on commit 889261e

Please sign in to comment.