Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): context by environment #148

Closed
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Integration Tests

on:
workflow_dispatch:

jobs:
smoke-tests:
permissions:
contents: read
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
-
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you align the yaml formatting like we do in our other workflows?

- name:

I would also love to have this job integrated in our ci workflow.

It should run after the build
but before the job release

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of these tests is to test the released code in a multi-platform context. That's why they don't use local action source but a named release. Do you think that I should use local code only?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using local code we can capture the bug you resolved before cutting out another release. Would be great to have that.

name: Checkout
uses: actions/checkout@v2
-
name: Create artifacts
run: |
mkdir artifacts
echo "onion, tomato, jalapeno, cilantro, lime, salt" > artifacts/salsa.txt
echo "audi, tesla, bmw" > artifacts/cars.txt
-
name: Generate some extra materials (this usually happens as part of the build process)
run: |
echo '[{"uri": "pkg:deb/debian/[email protected]?arch=amd64", "digest": {"sha256": "e1731ae217fcbc64d4c00d707dcead45c828c5f762bcf8cc56d87de511e096fa"}}]' > artifacts/extra-materials.json
-
name: Install cosign
uses: sigstore/[email protected]
with:
cosign-release: 'v1.5.1'
Copy link
Member

@marcofranssen marcofranssen Mar 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bumped cosign yesterday.

Suggested change
cosign-release: 'v1.5.1'
cosign-release: 'v1.6.0'

-
name: Generate provenance from artifacts
uses: phillips/[email protected]
with:
command: generate
subcommand: files
arguments: --artifact-path artifacts --extra-materials artifacts/extra-materials.json --output-path provenance.json
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"


7 changes: 0 additions & 7 deletions action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,8 @@ runs:
id: compose-args
shell: bash
run: |
encoded_github="$(echo ${GITHUB_CONTEXT} | base64 -w 0)"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do note we have added base64 encoding due to an earlier bug that broke the json due to

a commit message with quotes inside. #116

Could you confirm this isn't reintroducing that issue?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably a toJSON(github) error? I'm going to check that. Thank you to point me out to this issue.

encoded_runner="$(echo ${RUNNER_CONTEXT} | base64 -w 0)"

args=(${{ inputs.command }})
args+=(${{ inputs.subcommand }})
args+=(--github-context)
args+=("${encoded_github}")
args+=(--runner-context)
args+=("${encoded_runner}")
args+=(${{ inputs.arguments }})

echo "::set-output name=provenance_args::${args[@]}"
Expand Down
6 changes: 6 additions & 0 deletions cmd/slsa-provenance/cli/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ func RequiredFlagError(flagName string) error {
return fmt.Errorf("no value found for required flag: %s", flagName)
}

// RequiredEnvironmentVariableError creates a required environment variable
// error for the given environment variable name
func RequiredEnvironmentVariableError(envName string) error {
return fmt.Errorf("no value found for required environment variable: %s", envName)
}

// New creates a new instance of the slsa-provenance commandline interface
func New() *cobra.Command {
cmd := &cobra.Command{
Expand Down
6 changes: 3 additions & 3 deletions cmd/slsa-provenance/cli/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ func OCI() *cobra.Command {
Use: "container",
Short: "Generate provenance on container assets",
RunE: func(cmd *cobra.Command, args []string) error {
outputPath, err := o.GetOutputPath()
gh, err := o.GetGitHubContext()
if err != nil {
return err
}

gh, err := o.GetGitHubContext()
runner, err := o.GetRunnerContext()
if err != nil {
return err
}

runner, err := o.GetRunnerContext()
outputPath, err := o.GetOutputPath()
if err != nil {
return err
}
Expand Down
149 changes: 118 additions & 31 deletions cmd/slsa-provenance/cli/container_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package cli_test

import (
"encoding/base64"
"fmt"
"os"
"path"
"runtime"
Expand All @@ -14,87 +14,174 @@ import (

func TestGenerateContainerCliOptions(t *testing.T) {
_, filename, _, _ := runtime.Caller(0)
rootDir := path.Join(path.Dir(filename), "../../..")
provenanceFile := path.Join(path.Dir(filename), "provenance.json")

base64GitHubContext := base64.StdEncoding.EncodeToString([]byte(githubContext))
base64RunnerContext := base64.StdEncoding.EncodeToString([]byte(runnerContext))

testCases := []struct {
name string
err error
arguments []string
name string
err error
arguments []string
environment map[string]string
}{
{
name: "without commandline flags",
err: cli.RequiredFlagError("github-context"),
arguments: make([]string, 0),
name: "no environment variables",
err: cli.RequiredEnvironmentVariableError("GITHUB_CONTEXT"),
arguments: []string{},
environment: map[string]string{},
},
{
name: "only github-context given",
err: cli.RequiredFlagError("runner-context"),
name: "only github-context given",
err: cli.RequiredEnvironmentVariableError("RUNNER_CONTEXT"),
arguments: []string{},
environment: map[string]string{
"GITHUB_CONTEXT": githubContext,
},
},
{
name: "only contexts given",
err: cli.RequiredFlagError("repository"),
arguments: []string{},
environment: map[string]string{
"GITHUB_CONTEXT": githubContext,
"RUNNER_CONTEXT": runnerContext,
},
},
{
name: "invalid --output-path",
err: fmt.Errorf("no value found for required flag: output-path"),
arguments: []string{
"--github-context",
base64GitHubContext,
"--output-path",
"",
},
environment: map[string]string{
"GITHUB_CONTEXT": githubContext,
"RUNNER_CONTEXT": runnerContext,
},
},
{
name: "only context flags given",
name: "With extra materials",
err: cli.RequiredFlagError("repository"),
arguments: []string{
"--github-context",
base64GitHubContext,
"--runner-context",
base64RunnerContext,
"--output-path",
provenanceFile,
"--extra-materials",
path.Join(rootDir, "test-data/materials-valid.json"),
},
environment: map[string]string{
"GITHUB_CONTEXT": githubContext,
"RUNNER_CONTEXT": runnerContext,
},
},
{
name: "With broken extra materials",
err: fmt.Errorf("failed retrieving extra materials for %s: unexpected EOF", path.Join(rootDir, "test-data/materials-broken.not-json")),
arguments: []string{
"--output-path",
provenanceFile,
"--extra-materials",
path.Join(rootDir, "test-data/materials-broken.not-json"),
},
environment: map[string]string{
"GITHUB_CONTEXT": githubContext,
"RUNNER_CONTEXT": runnerContext,
},
},
{
name: "With non-existent extra materials",
err: fmt.Errorf("failed retrieving extra materials: open %s: no such file or directory", unknownFile),
arguments: []string{
"--output-path",
provenanceFile,
"--extra-materials",
fmt.Sprintf("%s,%s", path.Join(rootDir, "test-data/materials-valid.json"), unknownFile),
},
environment: map[string]string{
"GITHUB_CONTEXT": githubContext,
"RUNNER_CONTEXT": runnerContext,
},
},
{
name: "With broken extra materials (no uri)",
err: fmt.Errorf("failed retrieving extra materials for %s: empty or missing \"uri\" for material", path.Join(rootDir, "test-data/materials-no-uri.json")),
arguments: []string{
"--output-path",
provenanceFile,
"--extra-materials",
path.Join(rootDir, "test-data/materials-no-uri.json"),
},
environment: map[string]string{
"GITHUB_CONTEXT": githubContext,
"RUNNER_CONTEXT": runnerContext,
},
},
{
name: "With broken extra materials (no digest)",
err: fmt.Errorf("failed retrieving extra materials for %s: empty or missing \"digest\" for material", path.Join(rootDir, "test-data/materials-no-digest.json")),
arguments: []string{
"--output-path",
provenanceFile,
"--extra-materials",
path.Join(rootDir, "test-data/materials-no-digest.json"),
},
environment: map[string]string{
"GITHUB_CONTEXT": githubContext,
"RUNNER_CONTEXT": runnerContext,
},
},
{
name: "contexts and tags given",
err: cli.RequiredFlagError("repository"),
arguments: []string{
"--github-context",
base64GitHubContext,
"--runner-context",
base64RunnerContext,
"--tags",
"v0.4.0,33ba3da2213c83ce02df0f2f6ba925ec79037f9d",
},
environment: map[string]string{
"GITHUB_CONTEXT": githubContext,
"RUNNER_CONTEXT": runnerContext,
},
},
{
name: "contexts, repo and tags given",
err: cli.RequiredFlagError("digest"),
arguments: []string{
"--github-context",
base64GitHubContext,
"--runner-context",
base64RunnerContext,
"--repository",
"ghcr.io/philips-labs/slsa-provenance",
"--tags",
"v0.4.0,33ba3da2213c83ce02df0f2f6ba925ec79037f9d",
},
environment: map[string]string{
"GITHUB_CONTEXT": githubContext,
"RUNNER_CONTEXT": runnerContext,
},
},
{
name: "all flags given",
err: nil,
arguments: []string{
"--github-context",
base64GitHubContext,
"--runner-context",
base64RunnerContext,
"--repository",
"ghcr.io/philips-labs/slsa-provenance",
"--tags",
"v0.4.0,33ba3da2213c83ce02df0f2f6ba925ec79037f9d",
"--digest",
"sha256:194b471a878add368bf02a7935fa099024576c029491bcefaeb87f81efa093a3",
},
environment: map[string]string{
"GITHUB_CONTEXT": githubContext,
"RUNNER_CONTEXT": runnerContext,
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(tt *testing.T) {
assert := assert.New(tt)

// Set environment
os.Clearenv()
for k, v := range tc.environment {
os.Setenv(k, v)
}

output, err := executeCommand(cli.OCI(), tc.arguments...)
defer func() {
_ = os.Remove(provenanceFile)
Expand Down
10 changes: 5 additions & 5 deletions cmd/slsa-provenance/cli/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@ func Files() *cobra.Command {
Use: "files",
Short: "Generate provenance on file assets",
RunE: func(cmd *cobra.Command, args []string) error {
artifactPath, err := o.GetArtifactPath()
gh, err := o.GetGitHubContext()
if err != nil {
return err
}
outputPath, err := o.GetOutputPath()

runner, err := o.GetRunnerContext()
if err != nil {
return err
}

gh, err := o.GetGitHubContext()
artifactPath, err := o.GetArtifactPath()
if err != nil {
return err
}

runner, err := o.GetRunnerContext()
outputPath, err := o.GetOutputPath()
if err != nil {
return err
}
Expand Down
Loading