Skip to content

Commit

Permalink
Merge pull request #11 from stacklok/config
Browse files Browse the repository at this point in the history
Add configuration for frizbee
  • Loading branch information
JAORMX committed Nov 21, 2023
2 parents b340bf7 + 48a8cbf commit 30218a2
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .frizbee.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ghactions:
exclude:
# Exclude the SLSA GitHub Generator workflow.
# See https://github.com/slsa-framework/slsa-github-generator/issues/2993
- slsa-framework/slsa-github-generator/.github/workflows/[email protected]
2 changes: 1 addition & 1 deletion .github/workflows/releaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ jobs:
actions: read # To read the workflow path.
id-token: write # To sign the provenance.
contents: write # To add assets to a release.
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@07e64b653f10a80b6510f4568f685f8b7b9ea830 # v1.9.0
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
with:
base64-subjects: "${{ needs.release.outputs.hashes }}"
upload-assets: true # upload to a new release
Expand Down
8 changes: 7 additions & 1 deletion cmd/ghactions/ghactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (

"github.com/google/go-github/v56/github"
"github.com/spf13/cobra"

"github.com/stacklok/frizbee/pkg/config"
)

// CmdGHActions represents the ghactions command
Expand Down Expand Up @@ -70,6 +72,10 @@ func replace(cmd *cobra.Command, _ []string) error {
if err != nil {
return fmt.Errorf("failed to get quiet flag: %w", err)
}
cfg, err := config.FromContext(cmd.Context())
if err != nil {
return fmt.Errorf("failed to get config from context: %w", err)
}

// remove trailing / from dir. This doesn't play well with
// the go-billy filesystem and walker we use.
Expand All @@ -94,5 +100,5 @@ func replace(cmd *cobra.Command, _ []string) error {
errOnModified: errOnModified,
}

return replacer.do(ctx, cmd)
return replacer.do(ctx, cmd, cfg)
}
5 changes: 3 additions & 2 deletions cmd/ghactions/replacer.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"

"github.com/stacklok/frizbee/pkg/config"
"github.com/stacklok/frizbee/pkg/ghactions"
"github.com/stacklok/frizbee/pkg/utils"
)
Expand All @@ -41,7 +42,7 @@ type replacer struct {
errOnModified bool
}

func (r *replacer) do(ctx context.Context, cmd *cobra.Command) error {
func (r *replacer) do(ctx context.Context, cmd *cobra.Command, cfg *config.Config) error {
basedir := filepath.Dir(r.dir)
base := filepath.Base(r.dir)
bfs := osfs.New(basedir, osfs.WithBoundOS())
Expand All @@ -51,7 +52,7 @@ func (r *replacer) do(ctx context.Context, cmd *cobra.Command) error {

err := ghactions.TraverseGitHubActionWorkflows(bfs, base, func(path string, wflow *yaml.Node) error {
r.logf(cmd, "Processing %s\n", path)
m, err := ghactions.ModifyReferencesInYAML(ctx, r.ghcli, wflow)
m, err := ghactions.ModifyReferencesInYAML(ctx, r.ghcli, wflow, &cfg.GHActions)
if err != nil {
return fmt.Errorf("failed to process YAML file %s: %w", path, err)
}
Expand Down
37 changes: 33 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,52 @@ package cmd

import (
"context"
"fmt"
"os"

"github.com/spf13/cobra"

"github.com/stacklok/frizbee/cmd/ghactions"
"github.com/stacklok/frizbee/pkg/config"
)

// Execute runs the root command.
func Execute() {
var rootCmd = &cobra.Command{
Use: "frizbee",
Short: "frizbee is a tool you may throw a tag at and it comes back with a checksum",
Use: "frizbee",
Short: "frizbee is a tool you may throw a tag at and it comes back with a checksum",
PersistentPreRunE: prerun,
}

rootCmd.PersistentFlags().StringP("config", "c", ".frizbee.yml", "config file (default is .frizbee.yml)")

rootCmd.AddCommand(ghactions.CmdGHActions())
err := rootCmd.ExecuteContext(context.Background())
if err != nil {

if err := rootCmd.ExecuteContext(context.Background()); err != nil {
os.Exit(1)
}
}

func prerun(cmd *cobra.Command, _ []string) error {
ctx := cmd.Context()

cfg, err := readConfig(cmd)
if err != nil {
return fmt.Errorf("failed to read config: %w", err)
}

ctx = context.WithValue(ctx, config.ContextConfigKey, cfg)

cmd.SetContext(ctx)

return nil
}

func readConfig(cmd *cobra.Command) (*config.Config, error) {
configFile, err := cmd.Flags().GetString("config")
if err != nil {
return nil, fmt.Errorf("failed to get config file: %w", err)
}

return config.ParseConfigFile(configFile)
}
82 changes: 82 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//
// Copyright 2023 Stacklok, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package config provides the frizbee configuration.
package config

import (
"context"
"fmt"
"os"
"path/filepath"

"gopkg.in/yaml.v3"
)

type contextConfigKey struct{}

// ContextConfigKey is the context key for the configuration.
// nolint:gochecknoglobals // this is a context key
var ContextConfigKey = contextConfigKey{}

// FromContext returns the configuration from the context.
func FromContext(ctx context.Context) (*Config, error) {
cfg, ok := ctx.Value(ContextConfigKey).(*Config)
if !ok {
return nil, fmt.Errorf("failed to get config from context")
}

return cfg, nil
}

// Config is the frizbee configuration.
type Config struct {
GHActions GHActions `yaml:"ghactions" mapstructure:"ghactions"`
}

// GHActions is the GitHub Actions configuration.
type GHActions struct {
Filter `yaml:",inline" mapstructure:",inline"`
}

// Filter is a common configuration for filtering out patterns.
type Filter struct {
// Exclude is a list of patterns to exclude.
Exclude []string `yaml:"exclude" mapstructure:"exclude"`
}

// ParseConfigFile parses a configuration file.
func ParseConfigFile(configfile string) (*Config, error) {
cfg := &Config{}
cleancfgfile := filepath.Clean(configfile)
cfgF, err := os.Open(cleancfgfile)
if err != nil {
if os.IsNotExist(err) {
return cfg, nil
}

return nil, fmt.Errorf("failed to open config file: %w", err)
}
// nolint:errcheck // we don't care about the error here
defer cfgF.Close()

dec := yaml.NewDecoder(cfgF)

if err := dec.Decode(cfg); err != nil {
return nil, fmt.Errorf("failed to decode config file: %w", err)
}

return cfg, nil
}
19 changes: 17 additions & 2 deletions pkg/ghactions/ghactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (

"github.com/google/go-github/v56/github"
"gopkg.in/yaml.v3"

"github.com/stacklok/frizbee/pkg/config"
)

// IsLocal returns true if the input is a local path.
Expand Down Expand Up @@ -75,7 +77,7 @@ func GetChecksum(ctx context.Context, ghcli *github.Client, action, ref string)
// all references to tags with the checksum of the tag.
// Note that the given YAML structure is modified in-place.
// The function returns true if any references were modified.
func ModifyReferencesInYAML(ctx context.Context, ghcli *github.Client, node *yaml.Node) (bool, error) {
func ModifyReferencesInYAML(ctx context.Context, ghcli *github.Client, node *yaml.Node, cfg *config.GHActions) (bool, error) {
// `uses` will be immediately before the action
// name in the YAML `Content` array. We use a toggle
// to track if we've found `uses` and then look for
Expand All @@ -97,6 +99,10 @@ func ModifyReferencesInYAML(ctx context.Context, ghcli *github.Client, node *yam
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)
Expand All @@ -116,7 +122,7 @@ func ModifyReferencesInYAML(ctx context.Context, ghcli *github.Client, node *yam
}

// Otherwise recursively look more
m, err := ModifyReferencesInYAML(ctx, ghcli, v)
m, err := ModifyReferencesInYAML(ctx, ghcli, v, cfg)
if err != nil {
return m, err
}
Expand Down Expand Up @@ -182,3 +188,12 @@ func parseValue(val string) (*Action, error) {
Ref: ref,
}, nil
}

func shouldExclude(cfg *config.GHActions, input string) bool {
for _, e := range cfg.Exclude {
if e == input {
return true
}
}
return false
}

0 comments on commit 30218a2

Please sign in to comment.