Skip to content

Commit

Permalink
Merge pull request #139 from stacklok/refactor
Browse files Browse the repository at this point in the history
Frizbee refactoring - support for Dockerfile, docker:// actions, etc.
  • Loading branch information
rdimitrov authored Jun 4, 2024
2 parents a9e2134 + 4ff1d92 commit 181f156
Show file tree
Hide file tree
Showing 54 changed files with 4,465 additions and 2,330 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,6 @@ jobs:
- name: Frizbee
run: |-
bin/frizbee ghactions --dry-run --error
bin/frizbee actions --dry-run --error
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ dist/

# Go workspace file
go.work

.idea/

frizbee
114 changes: 100 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Frizbee
![image](https://github.com/stacklok/frizbee/assets/16540482/35034046-d962-475d-b8e2-67b7625f2a60)

---
[![Coverage Status](https://coveralls.io/repos/github/stacklok/frizbee/badge.svg?branch=main)](https://coveralls.io/github/stacklok/frizbee?branch=main) | [![License: Apache 2.0](https://img.shields.io/badge/License-Apache2.0-brightgreen.svg)](https://opensource.org/licenses/Apache-2.0) | [![](https://dcbadge.vercel.app/api/server/RkzVuTp3WK?logo=discord&label=Discord&color=5865&style=flat)](https://discord.gg/RkzVuTp3WK)

---
# Frizbee

Frizbee is a tool you may throw a tag at and it comes back with a checksum.

Expand All @@ -14,12 +16,13 @@ It also includes a set of libraries for working with tags and checksums.
## Table of Contents

- [Installation](#installation)
- [Usage](#usage)
- [Usage - CLI](#usage---cli)
- [GitHub Actions](#github-actions)
- [Container Images](#container-images)
- [Usage - Library](#usage---library)
- [GitHub Actions](#github-actions)
- [Container Images](#container-images)
- [Configuration](#configuration)
- [Commands](#commands)
- [Autocompletion](#autocompletion)
- [Contributing](#contributing)
- [License](#license)

Expand All @@ -39,18 +42,18 @@ brew install stacklok/tap/frizbee
winget install stacklok.frizbee
```

## Usage
## Usage - CLI

### GitHub Actions

Frizbee can be used to generate checksums for GitHub Actions. This is useful
for verifying that the contents of a GitHub Action have not changed.

To quickly replace the GitHub Action references for your project, you can use
the `ghactions` command:
the `actions` command:

```bash
frizbee ghactions -d path/to/your/repo/.github/workflows/
frizbee actions path/to/your/repo/.github/workflows/
```

This will write all the replacements to the files in the directory provided.
Expand All @@ -64,28 +67,111 @@ to stdout instead of writing them to the files.
It also supports exiting with a non-zero exit code if any replacements are found.
This is handy for CI/CD pipelines.

If you want to generate the replacement for a single GitHub Action, you can use
the `ghactions one` command:
If you want to generate the replacement for a single GitHub Action, you can use the
same command:

```bash
frizbee ghactions one metal-toolbox/container-push/.github/workflows/container-push.yml@main
frizbee actions metal-toolbox/container-push/.github/workflows/container-push.yml@main
```

This is useful if you're developing and want to quickly test the replacement.

### Container Images

Frizbee can be used to generate checksums for container images. This is useful
for verifying that the contents of a container image have not changed.
for verifying that the contents of a container image have not changed. This works
for all yaml/yml and Dockerfile fies in the directory provided by the `-d` flag.

To get the digest for a single image tag, you can use the `containerimage one` command:
To quickly replace the container image references for your project, you can use
the `image` command:

```bash
frizbee containerimage one quay.io/stacklok/frizbee:latest
frizbee image path/to/your/yaml/files/
```

This will print the image refrence with the digest for the image tag provided.
To get the digest for a single image tag, you can use the same command:

```bash
frizbee image ghcr.io/stacklok/minder/server:latest
```

This will print the image reference with the digest for the image tag provided.

## Usage - Library

Frizbee can also be used as a library. The library provides a set of functions
for working with tags and checksums. Here are a few examples of how you can use
the library:

### GitHub Actions

```go
// Create a new replacer
r := replacer.NewGitHubActionsReplacer(cfg)
...
// Parse a single GitHub Action reference
ret, err := r.ParseString(ctx, ghActionRef)
...
// Parse all GitHub Actions workflow yaml files in a given directory
res, err := r.ParsePath(ctx, dir)
...
// Parse and replace all GitHub Actions references in the provided file system
res, err := r.ParsePathInFS(ctx, bfs, base)
...
// Parse a single yaml file referencing GitHub Actions
res, err := r.ParseFile(ctx, fileHandler)
...
// List all GitHub Actions referenced in the given directory
res, err := r.ListPath(dir)
...
// List all GitHub Actions referenced in the provided file system
res, err := r.ListPathInFS(bfs, base)
...
// List all GitHub Actions referenced in the provided file
res, err := r.ListFile(fileHandler)
```

### Container images

```go
// Create a new replacer
r := replacer.NewContainerImagesReplacer(cfg)
...
// Parse a single container image reference
ret, err := r.ParseString(ctx, ghActionRef)
...
// Parse all files containing container image references in a given directory
res, err := r.ParsePath(ctx, dir)
...
// Parse and replace all container image references in the provided file system
res, err := r.ParsePathInFS(ctx, bfs, base)
...
// Parse a single yaml file referencing container images
res, err := r.ParseFile(ctx, fileHandler)
...
// List all container images referenced in the given directory
res, err := r.ListPath(dir)
...
// List all container images referenced in the provided file system
res, err := r.ListPathInFS(bfs, base)
...
// List all container images referenced in the provided file
res, err := r.ListFile(fileHandler)
```

## Configuration

Frizbee can be configured by setting up a `.frizbee.yml` file.
You can configure Frizbee to skip processing certain actions, i.e.

```yml
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/generator_generic_slsa3.yml

```

## Contributing

Expand Down
110 changes: 110 additions & 0 deletions cmd/actions/actions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//
// Copyright 2024 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 actions provides command-line utilities to work with GitHub Actions.
package actions

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

"github.com/spf13/cobra"

"github.com/stacklok/frizbee/internal/cli"
"github.com/stacklok/frizbee/pkg/interfaces"
"github.com/stacklok/frizbee/pkg/replacer"
"github.com/stacklok/frizbee/pkg/utils/config"
)

// CmdGHActions represents the actions command
func CmdGHActions() *cobra.Command {
cmd := &cobra.Command{
Use: "actions",
Short: "Replace tags in GitHub Actions workflows",
Long: `This utility replaces tag or branch references in GitHub Actions workflows
with the latest commit hash of the referenced tag or branch.
Example:
$ frizbee actions <.github/workflows> or <actions/checkout@v4>
This will replace all tag or branch references in all GitHub Actions workflows
for the given directory. Supports both directories and single references.
` + cli.TokenHelpText + "\n",
Aliases: []string{"ghactions"}, // backwards compatibility
RunE: replaceCmd,
SilenceUsage: true,
Args: cobra.MaximumNArgs(1),
}

// flags
cli.DeclareFrizbeeFlags(cmd, false)

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

return cmd
}

// nolint:errcheck
func replaceCmd(cmd *cobra.Command, args []string) error {
// Set the default directory if not provided
pathOrRef := ".github/workflows"
if len(args) > 0 {
pathOrRef = args[0]
}

// Extract the CLI flags from the cobra command
cliFlags, err := cli.NewHelper(cmd)
if err != nil {
return err
}

// Set up the config
cfg, err := config.FromCommand(cmd)
if err != nil {
return err
}

// Create a new replacer
r := replacer.NewGitHubActionsReplacer(cfg).
WithUserRegex(cliFlags.Regex).
WithGitHubClientFromToken(os.Getenv(cli.GitHubTokenEnvKey))

if cli.IsPath(pathOrRef) {
dir := filepath.Clean(pathOrRef)
// Replace the tags in the given directory
res, err := r.ParsePath(cmd.Context(), dir)
if err != nil {
return err
}
// Process the output files
return cliFlags.ProcessOutput(dir, res.Processed, res.Modified)
}
// Replace the passed reference
res, err := r.ParseString(cmd.Context(), pathOrRef)
if err != nil {
if errors.Is(err, interfaces.ErrReferenceSkipped) {
fmt.Fprintln(cmd.OutOrStdout(), pathOrRef) // nolint:errcheck
return nil
}
return err
}
fmt.Fprintf(cmd.OutOrStdout(), "%s@%s\n", res.Name, res.Ref) // nolint:errcheck
return nil
}
Loading

0 comments on commit 181f156

Please sign in to comment.