Skip to content

Commit

Permalink
Add ghactions list
Browse files Browse the repository at this point in the history
  • Loading branch information
jhrozek committed Nov 21, 2023
1 parent 5ea9820 commit a8d3003
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 0 deletions.
1 change: 1 addition & 0 deletions cmd/ghactions/ghactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ for the given directory.

// sub-commands
cmd.AddCommand(CmdOne())
cmd.AddCommand(CmdList())

return cmd
}
Expand Down
82 changes: 82 additions & 0 deletions cmd/ghactions/list.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 ghactions

import (
"encoding/json"
"fmt"
"os"
"path/filepath"

"github.com/go-git/go-billy/v5/osfs"
"github.com/google/go-github/v56/github"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"

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

// CmdList represents the one sub-command
func CmdList() *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: "Lists the used github actions",
Long: `This utility lists all the github actions used in the workflows`,
RunE: list,
SilenceUsage: true,
}

cmd.Flags().StringP("dir", "d", ".github/workflows", "workflows directory")

return cmd
}

func list(cmd *cobra.Command, args []string) error {

Check warning on line 47 in cmd/ghactions/list.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 'args' seems to be unused, consider removing or renaming it as _ (revive)
dir := cmd.Flag("dir").Value.String()

ghcli := github.NewClient(nil)

tok := os.Getenv("GITHUB_TOKEN")
if tok != "" {
ghcli = ghcli.WithAuthToken(tok)
}

base := filepath.Base(dir)
bfs := osfs.New(filepath.Dir(dir), osfs.WithBoundOS())
actions := []ghactions.Action{}

err := ghactions.TraverseGitHubActionWorkflows(bfs, base, func(path string, wflow *yaml.Node) error {
wfActions, err := ghactions.ListActionsInYAML(wflow)
if err != nil {
return fmt.Errorf("failed to get actions from YAML file %s: %w", path, err)
}
actions = append(actions, wfActions...)

return nil
})
if err != nil {
return err
}

jsonBytes, err := json.MarshalIndent(actions, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal actions: %w", err)
}
jsonString := string(jsonBytes)

fmt.Println(jsonString)
return nil
}
56 changes: 56 additions & 0 deletions pkg/ghactions/ghactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,59 @@ func ModifyReferencesInYAML(ctx context.Context, ghcli *github.Client, node *yam
}
return modified, nil
}

type Action struct {
Owner string
Repo string
Ref string
}

func ListActionsInYAML(node *yaml.Node) ([]Action, error) {
var uses []Action
foundUses := false

for _, v := range node.Content {
if v.Value == "uses" {
foundUses = true
continue
}

if foundUses {
foundUses = false
a, err := parseValue(v.Value)
if err != nil {
return nil, fmt.Errorf("failed to parse action reference '%s': %w", v.Value, err)
}

uses = append(uses, *a)
continue
}

// Otherwise recursively look more
childUses, err := ListActionsInYAML(v)
if err != nil {
return nil, err
}
uses = append(uses, childUses...)
}

return uses, nil
}

func parseValue(val string) (*Action, error) {
action, ref, err := ParseActionReference(val)
if err != nil {
return nil, fmt.Errorf("failed to parse action reference '%s': %w", val, err)
}

owner, repo, err := parseActionFragments(action)
if err != nil {
return nil, fmt.Errorf("failed to parse action fragments '%s': %w", action, err)
}

return &Action{
Owner: owner,
Repo: repo,
Ref: ref,
}, nil
}

0 comments on commit a8d3003

Please sign in to comment.