Adding line numbers for rest of Token-Permessions (and by extension, (#1381)

Packaging)
This commit is contained in:
Chris McGehee 2021-12-13 20:14:35 -08:00 committed by GitHub
parent ca97581538
commit f991fee32d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 723 additions and 186 deletions

View File

@ -22,6 +22,7 @@ import (
"github.com/rhysd/actionlint"
"github.com/ossf/scorecard/v3/checker"
sce "github.com/ossf/scorecard/v3/errors"
)
@ -59,6 +60,59 @@ func IsStepExecKind(step *actionlint.Step, kind actionlint.ExecKind) bool {
return step.Exec.Kind() == kind
}
// GetLineNumber returns the line number for this position.
func GetLineNumber(pos *actionlint.Pos) int {
if pos == nil {
return checker.OffsetDefault
}
return pos.Line
}
// GetUses returns the 'uses' statement in this step or nil if this step does not have one.
func GetUses(step *actionlint.Step) *actionlint.String {
if step == nil {
return nil
}
if !IsStepExecKind(step, actionlint.ExecKindAction) {
return nil
}
execAction, ok := step.Exec.(*actionlint.ExecAction)
if !ok || execAction == nil {
return nil
}
return execAction.Uses
}
// getWith returns the 'with' statement in this step or nil if this step does not have one.
func getWith(step *actionlint.Step) map[string]*actionlint.Input {
if step == nil {
return nil
}
if !IsStepExecKind(step, actionlint.ExecKindAction) {
return nil
}
execAction, ok := step.Exec.(*actionlint.ExecAction)
if !ok || execAction == nil {
return nil
}
return execAction.Inputs
}
// getRun returns the 'run' statement in this step or nil if this step does not have one.
func getRun(step *actionlint.Step) *actionlint.String {
if step == nil {
return nil
}
if !IsStepExecKind(step, actionlint.ExecKindRun) {
return nil
}
execAction, ok := step.Exec.(*actionlint.ExecRun)
if !ok || execAction == nil {
return nil
}
return execAction.Run
}
func getExecRunShell(execRun *actionlint.ExecRun) string {
if execRun != nil && execRun.Shell != nil {
return execRun.Shell.Value
@ -250,3 +304,80 @@ func IsGitHubOwnedAction(actionName string) bool {
c := strings.HasPrefix(actionName, "github/")
return a || c
}
// JobMatcher is rule for matching a job.
type JobMatcher struct {
// The text to be logged when a job match is found.
LogText string
// Each step in this field has a matching step in the job.
Steps []*JobMatcherStep
}
// JobMatcherStep is a single step that needs to be matched.
type JobMatcherStep struct {
// If set, the step's 'Uses' must match this field. Checks that the action name is the same.
Uses string
// If set, the step's 'With' have the keys and values that are in this field.
With map[string]string
// If set, the step's 'Run' must match this field. Does a regex match using this field.
Run string
}
// Matches returns true if the job matches the job matcher.
func (m *JobMatcher) Matches(job *actionlint.Job) bool {
for _, stepToMatch := range m.Steps {
hasMatch := false
for _, step := range job.Steps {
if stepsMatch(stepToMatch, step) {
hasMatch = true
break
}
}
if !hasMatch {
return false
}
}
return true
}
// stepsMatch returns true if the fields on 'stepToMatch' match what's in 'step'.
func stepsMatch(stepToMatch *JobMatcherStep, step *actionlint.Step) bool {
// Make sure 'uses' matches if present.
if stepToMatch.Uses != "" {
uses := GetUses(step)
if uses == nil {
return false
}
if !strings.HasPrefix(uses.Value, stepToMatch.Uses+"@") {
return false
}
}
// Make sure 'with' matches if present.
if len(stepToMatch.With) > 0 {
with := getWith(step)
if with == nil {
return false
}
for keyToMatch, valToMatch := range stepToMatch.With {
input, ok := with[keyToMatch]
if !ok || input == nil || input.Value == nil || input.Value.Value != valToMatch {
return false
}
}
}
// Make sure 'run' matches if present.
if stepToMatch.Run != "" {
run := getRun(step)
if run == nil {
return false
}
r := regexp.MustCompile(stepToMatch.Run)
if !r.MatchString(run.Value) {
return false
}
}
return true
}

View File

@ -17,10 +17,12 @@ package checks
import (
"fmt"
"path/filepath"
"regexp"
"strings"
"github.com/rhysd/actionlint"
"github.com/ossf/scorecard/v3/checker"
"github.com/ossf/scorecard/v3/checks/fileparser"
sce "github.com/ossf/scorecard/v3/errors"
)
@ -51,7 +53,12 @@ func Packaging(c *checker.CheckRequest) checker.CheckResult {
return checker.CreateRuntimeErrorResult(CheckPackaging, e)
}
if !isPackagingWorkflow(string(fc), fp, c.Dlogger) {
workflow, errs := actionlint.Parse(fc)
if len(errs) > 0 && workflow == nil {
e := fileparser.FormatActionlintError(errs)
return checker.CreateRuntimeErrorResult(CheckPackaging, e)
}
if !isPackagingWorkflow(workflow, fp, c.Dlogger) {
continue
}
@ -87,147 +94,135 @@ func Packaging(c *checker.CheckRequest) checker.CheckResult {
}
// A packaging workflow.
func isPackagingWorkflow(s, fp string, dl checker.DetailLogger) bool {
// Nodejs packages.
if strings.Contains(s, "actions/setup-node@") {
r1 := regexp.MustCompile(`(?s)registry-url.*https://registry\.npmjs\.org`)
r2 := regexp.MustCompile(`(?s)npm.*publish`)
func isPackagingWorkflow(workflow *actionlint.Workflow, fp string, dl checker.DetailLogger) bool {
jobMatchers := []fileparser.JobMatcher{
{
Steps: []*fileparser.JobMatcherStep{
{
Uses: "actions/setup-node",
With: map[string]string{"registry-url": "https://registry.npmjs.org"},
},
{
Run: "npm.*publish",
},
},
LogText: "candidate node publishing workflow using npm",
},
{
// Java packages with maven.
Steps: []*fileparser.JobMatcherStep{
{
Uses: "actions/setup-java",
},
{
Run: "mvn.*deploy",
},
},
LogText: "candidate java publishing workflow using maven",
},
{
// Java packages with gradle.
Steps: []*fileparser.JobMatcherStep{
{
Uses: "actions/setup-java",
},
{
Run: "gradle.*publish",
},
},
LogText: "candidate java publishing workflow using gradle",
},
{
// Ruby packages.
Steps: []*fileparser.JobMatcherStep{
{
Run: "gem.*push",
},
},
LogText: "candidate ruby publishing workflow using gem",
},
{
// NuGet packages.
Steps: []*fileparser.JobMatcherStep{
{
Run: "nuget.*push",
},
},
LogText: "candidate nuget publishing workflow",
},
{
// Docker packages.
Steps: []*fileparser.JobMatcherStep{
{
Run: "docker.*push",
},
},
LogText: "candidate docker publishing workflow",
},
{
// Docker packages.
Steps: []*fileparser.JobMatcherStep{
{
Uses: "docker/build-push-action",
},
},
LogText: "candidate docker publishing workflow",
},
{
// Python packages.
Steps: []*fileparser.JobMatcherStep{
{
Uses: "actions/setup-python",
},
{
Uses: "pypa/gh-action-pypi-publish",
},
},
LogText: "candidate python publishing workflow using pypi",
},
{
// Go packages.
Steps: []*fileparser.JobMatcherStep{
{
Uses: "actions/setup-go",
},
{
Uses: "goreleaser/goreleaser-action",
},
},
LogText: "candidate golang publishing workflow",
},
{
// Rust packages. https://doc.rust-lang.org/cargo/reference/publishing.html
Steps: []*fileparser.JobMatcherStep{
{
Run: "cargo.*publish",
},
},
LogText: "candidate rust publishing workflow using cargo",
},
}
for _, job := range workflow.Jobs {
for _, matcher := range jobMatchers {
if !matcher.Matches(job) {
continue
}
if r1.MatchString(s) && r2.MatchString(s) {
dl.Info3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
// Source file must have line number > 0.
Offset: 1,
Text: "candidate node publishing workflow using npm",
Path: fp,
Type: checker.FileTypeSource,
Offset: fileparser.GetLineNumber(job.Pos),
Text: matcher.LogText,
})
return true
}
}
// Java packages.
if strings.Contains(s, "actions/setup-java@") {
// Java packages with maven.
r1 := regexp.MustCompile(`(?s)mvn.*deploy`)
if r1.MatchString(s) {
dl.Info3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
// Source file must have line number > 0.
Offset: 1,
Text: "candidate java publishing workflow using maven",
})
return true
}
// Java packages with gradle.
r2 := regexp.MustCompile(`(?s)gradle.*publish`)
if r2.MatchString(s) {
dl.Info3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
// Source file must have line number > 0.
Offset: 1,
Text: "candidate java publishing workflow using gradle",
})
return true
}
}
// Ruby packages.
r := regexp.MustCompile(`(?s)gem.*push`)
if r.MatchString(s) {
dl.Info3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
// Source file must have line number > 0.
Offset: 1,
Text: "candidate ruby publishing workflow using gem",
})
return true
}
// NuGet packages.
r = regexp.MustCompile(`(?s)nuget.*push`)
if r.MatchString(s) {
dl.Info3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
// Source file must have line number > 0.
Offset: 1,
Text: "candidate nuget publishing workflow",
})
return true
}
// Docker packages.
if strings.Contains(s, "docker/build-push-action@") {
dl.Info3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
// Source file must have line number > 0.
Offset: 1,
Text: "candidate docker publishing workflow",
})
return true
}
r = regexp.MustCompile(`(?s)docker.*push`)
if r.MatchString(s) {
dl.Info3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
// Source file must have line number > 0.
Offset: 1,
Text: "candidate docker publishing workflow",
})
return true
}
// Python packages.
if strings.Contains(s, "actions/setup-python@") && strings.Contains(s, "pypa/gh-action-pypi-publish@master") {
dl.Info3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
// Source file must have line number > 0.
Offset: 1,
Text: "candidate python publishing workflow using pypi",
})
return true
}
// Go packages.
if strings.Contains(s, "actions/setup-go") &&
strings.Contains(s, "goreleaser/goreleaser-action@") {
dl.Info3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
// Source file must have line number > 0.
Offset: 1,
Text: "candidate golang publishing workflow",
})
return true
}
// Rust packages.
// https://doc.rust-lang.org/cargo/reference/publishing.html.
r = regexp.MustCompile(`(?s)cargo.*publish`)
if r.MatchString(s) {
dl.Info3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
// Source file must have line number > 0.
Offset: 1,
Text: "candidate rust publishing workflow using cargo",
})
return true
}
dl.Debug3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
// Source file must have line number > 0.
Offset: 1,
Path: fp,
Type: checker.FileTypeSource,
Offset: checker.OffsetDefault,
Text: "not a publishing workflow",
})
return false

110
checks/packaging_test.go Normal file
View File

@ -0,0 +1,110 @@
// Copyright 2021 Security Scorecard Authors
//
// 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 checks
import (
"fmt"
"os"
"testing"
"github.com/rhysd/actionlint"
scut "github.com/ossf/scorecard/v3/utests"
)
func TestIsPackagingWorkflow(t *testing.T) {
t.Parallel()
tests := []struct {
name string
filename string
expected bool
}{
{
name: "npmjs.org publish",
filename: "./testdata/github-workflow-packaging-npm.yaml",
expected: true,
},
{
name: "npm github publish",
filename: "./testdata/github-workflow-packaging-npm-github.yaml",
expected: false, // Should this be false?
},
{
name: "maven publish",
filename: "./testdata/github-workflow-packaging-maven.yaml",
expected: true,
},
{
name: "gradle publish",
filename: "./testdata/github-workflow-packaging-gradle.yaml",
expected: true,
},
{
name: "gem publish",
filename: "./testdata/github-workflow-packaging-gem.yaml",
expected: true,
},
{
name: "nuget publish",
filename: "./testdata/github-workflow-packaging-nuget.yaml",
expected: true,
},
{
name: "docker action publish",
filename: "./testdata/github-workflow-packaging-docker-action.yaml",
expected: true,
},
{
name: "docker push publish",
filename: "./testdata/github-workflow-packaging-docker-push.yaml",
expected: true,
},
{
name: "pypi publish",
filename: "./testdata/github-workflow-packaging-pypi.yaml",
expected: true,
},
{
name: "go publish",
filename: "./testdata/github-workflow-packaging-go.yaml",
expected: true,
},
{
name: "cargo publish",
filename: "./testdata/github-workflow-packaging-cargo.yaml",
expected: true,
},
}
for _, tt := range tests {
tt := tt // Re-initializing variable so it is not changed while executing the closure below
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
content, err := os.ReadFile(tt.filename)
if err != nil {
panic(fmt.Errorf("cannot read file: %w", err))
}
workflow, errs := actionlint.Parse(content)
if len(errs) > 0 && workflow == nil {
panic(fmt.Errorf("cannot parse file: %w", err))
}
dl := scut.TestDetailLogger{}
result := isPackagingWorkflow(workflow, tt.filename, &dl)
if result != tt.expected {
t.Errorf("isPackagingWorkflow() = %v, expected %v", result, tt.expected)
}
})
}
}

View File

@ -64,10 +64,7 @@ func validatePermission(permissionKey string, permissionValue *actionlint.Permis
return sce.WithMessage(sce.ErrScorecardInternal, errInvalidGitHubWorkflow.Error())
}
val := permissionValue.Value.Value
lineNumber := checker.OffsetDefault
if permissionValue.Value.Pos != nil {
lineNumber = permissionValue.Value.Pos.Line
}
lineNumber := fileparser.GetLineNumber(permissionValue.Value.Pos)
if strings.EqualFold(val, "write") {
if isPermissionOfInterest(permissionKey, ignoredPermissions) {
dl.Warn3(&checker.LogMessage{
@ -138,11 +135,7 @@ func validatePermissions(permissions *actionlint.Permissions, permLevel, path st
}
if allIsSet {
val := permissions.All.Value
lineNumber := checker.OffsetDefault
if permissions.All.Pos != nil {
lineNumber = permissions.All.Pos.Line
}
lineNumber := fileparser.GetLineNumber(permissions.All.Pos)
if !strings.EqualFold(val, "read-all") && val != "" {
dl.Warn3(&checker.LogMessage{
Path: path,
@ -195,14 +188,10 @@ func validateRunLevelPermissions(workflow *actionlint.Workflow, path string,
// For most workflows, no write permissions are needed,
// so only top-level read-only permissions need to be declared.
if job.Permissions == nil {
lineNumber := checker.OffsetDefault
if job.Pos != nil {
lineNumber = job.Pos.Line
}
dl.Debug3(&checker.LogMessage{
Path: path,
Type: checker.FileTypeSource,
Offset: lineNumber,
Offset: fileparser.GetLineNumber(job.Pos),
Text: fmt.Sprintf("no %s permission defined", runLevelPermission),
})
recordAllPermissionsWrite(pdata.runLevelWritePermissions)
@ -385,7 +374,7 @@ func validateGitHubActionTokenPermissions(path string, content []byte,
// 2. Run-level permission definitions,
// see https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idpermissions.
ignoredPermissions := createIgnoredPermissions(string(content), path, dl)
ignoredPermissions := createIgnoredPermissions(workflow, path, dl)
if err := validateRunLevelPermissions(workflow, path, dl, pdata, ignoredPermissions); err != nil {
return false, err
}
@ -397,15 +386,15 @@ func validateGitHubActionTokenPermissions(path string, content []byte,
return true, nil
}
func createIgnoredPermissions(s, fp string, dl checker.DetailLogger) map[string]bool {
func createIgnoredPermissions(workflow *actionlint.Workflow, fp string, dl checker.DetailLogger) map[string]bool {
ignoredPermissions := make(map[string]bool)
if requiresPackagesPermissions(s, fp, dl) {
if requiresPackagesPermissions(workflow, fp, dl) {
ignoredPermissions["packages"] = true
}
if requiresContentsPermissions(s, fp, dl) {
if requiresContentsPermissions(workflow, fp, dl) {
ignoredPermissions["contents"] = true
}
if isSARIFUploadWorkflow(s, fp, dl) {
if isSARIFUploadWorkflow(workflow, fp, dl) {
ignoredPermissions["security-events"] = true
}
@ -413,12 +402,12 @@ func createIgnoredPermissions(s, fp string, dl checker.DetailLogger) map[string]
}
// Scanning tool run externally and SARIF file uploaded.
func isSARIFUploadWorkflow(s, fp string, dl checker.DetailLogger) bool {
func isSARIFUploadWorkflow(workflow *actionlint.Workflow, fp string, dl checker.DetailLogger) bool {
//nolint
// CodeQl analysis workflow automatically sends sarif file to GitHub.
// https://docs.github.com/en/code-security/secure-coding/integrating-with-code-scanning/uploading-a-sarif-file-to-github#about-sarif-file-uploads-for-code-scanning.
// `The CodeQL action uploads the SARIF file automatically when it completes analysis`.
if isCodeQlAnalysisWorkflow(s, fp, dl) {
if isCodeQlAnalysisWorkflow(workflow, fp, dl) {
return true
}
@ -426,7 +415,7 @@ func isSARIFUploadWorkflow(s, fp string, dl checker.DetailLogger) bool {
// Third-party scanning tools use the SARIF-upload action from code-ql.
// https://docs.github.com/en/code-security/secure-coding/integrating-with-code-scanning/uploading-a-sarif-file-to-github#uploading-a-code-scanning-analysis-with-github-actions
// We only support CodeQl today.
if isSARIFUploadAction(s, fp, dl) {
if isSARIFUploadAction(workflow, fp, dl) {
return true
}
@ -438,22 +427,29 @@ func isSARIFUploadWorkflow(s, fp string, dl checker.DetailLogger) bool {
}
// CodeQl run externally and SARIF file uploaded.
func isSARIFUploadAction(s, fp string, dl checker.DetailLogger) bool {
if strings.Contains(s, "github/codeql-action/upload-sarif@") {
dl.Debug3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
// TODO: set line.
Offset: 1,
Text: "codeql SARIF upload workflow detected",
// TODO: set Snippet.
})
return true
func isSARIFUploadAction(workflow *actionlint.Workflow, fp string, dl checker.DetailLogger) bool {
for _, job := range workflow.Jobs {
for _, step := range job.Steps {
uses := fileparser.GetUses(step)
if uses == nil {
continue
}
if strings.HasPrefix(uses.Value, "github/codeql-action/upload-sarif@") {
dl.Debug3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
Offset: fileparser.GetLineNumber(uses.Pos),
Text: "codeql SARIF upload workflow detected",
// TODO: set Snippet.
})
return true
}
}
}
dl.Debug3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
Offset: 1,
Offset: checker.OffsetDefault,
Text: "not a codeql upload SARIF workflow",
})
return false
@ -463,22 +459,29 @@ func isSARIFUploadAction(s, fp string, dl checker.DetailLogger) bool {
// CodeQl run within GitHub worklow automatically bubbled up to
// security events, see
// https://docs.github.com/en/code-security/secure-coding/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning.
func isCodeQlAnalysisWorkflow(s, fp string, dl checker.DetailLogger) bool {
if strings.Contains(s, "github/codeql-action/analyze@") {
dl.Debug3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
// TODO: set line.
Offset: 1,
Text: "codeql workflow detected",
// TODO: set Snippet.
})
return true
func isCodeQlAnalysisWorkflow(workflow *actionlint.Workflow, fp string, dl checker.DetailLogger) bool {
for _, job := range workflow.Jobs {
for _, step := range job.Steps {
uses := fileparser.GetUses(step)
if uses == nil {
continue
}
if strings.HasPrefix(uses.Value, "github/codeql-action/analyze@") {
dl.Debug3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
Offset: fileparser.GetLineNumber(uses.Pos),
Text: "codeql workflow detected",
// TODO: set Snippet.
})
return true
}
}
}
dl.Debug3(&checker.LogMessage{
Path: fp,
Type: checker.FileTypeSource,
Offset: 1,
Offset: checker.OffsetDefault,
Text: "not a codeql workflow",
})
return false
@ -486,19 +489,19 @@ func isCodeQlAnalysisWorkflow(s, fp string, dl checker.DetailLogger) bool {
// A packaging workflow using GitHub's supported packages:
// https://docs.github.com/en/packages.
func requiresPackagesPermissions(s, fp string, dl checker.DetailLogger) bool {
func requiresPackagesPermissions(workflow *actionlint.Workflow, fp string, dl checker.DetailLogger) bool {
// TODO: add support for GitHub registries.
// Example: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry.
// This feature requires parsing actions properly.
// For now, we just re-use the Packaging check to verify that the
// workflow is a packaging workflow.
return isPackagingWorkflow(s, fp, dl)
return isPackagingWorkflow(workflow, fp, dl)
}
// Note: this needs to be improved.
// Currently we don't differentiate between publishing on GitHub vs
// pubishing on registries. In terms of risk, both are similar, as
// an attacker would gain the ability to push a package.
func requiresContentsPermissions(s, fp string, dl checker.DetailLogger) bool {
return requiresPackagesPermissions(s, fp, dl)
func requiresContentsPermissions(workflow *actionlint.Workflow, fp string, dl checker.DetailLogger) bool {
return requiresPackagesPermissions(workflow, fp, dl)
}

View File

@ -274,6 +274,17 @@ func TestGithubTokenPermissions(t *testing.T) {
NumberOfDebug: 4,
},
},
{
name: "security-events write, codeql comment",
filename: "./testdata/github-workflow-permissions-run-write-codeql-comment.yaml",
expected: scut.TestReturn{
Error: nil,
Score: checker.MaxResultScore - 1,
NumberOfWarn: 1,
NumberOfInfo: 1,
NumberOfDebug: 4,
},
},
}
for _, tt := range tests {
tt := tt // Re-initializing variable so it is not changed while executing the closure below

View File

@ -0,0 +1,20 @@
# Copyright 2021 Security Scorecard Authors
#
# 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.
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: cargo publish

View File

@ -0,0 +1,23 @@
# Copyright 2021 Security Scorecard Authors
#
# 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.
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: docker/build-push-action@v2
with:
push: true
tags: user/app:latest

View File

@ -0,0 +1,20 @@
# Copyright 2021 Security Scorecard Authors
#
# 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.
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: docker push myapp/myimage:latest

View File

@ -0,0 +1,20 @@
# Copyright 2021 Security Scorecard Authors
#
# 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.
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: gem push *.gem

View File

@ -0,0 +1,31 @@
# Copyright 2021 Security Scorecard Authors
#
# 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.
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: actions/setup-go@v2
with:
go-version: 1.17
- uses: goreleaser/goreleaser-action@v2
with:
distribution: goreleaser
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -0,0 +1,21 @@
# Copyright 2021 Security Scorecard Authors
#
# 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.
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
- run: gradle publish

View File

@ -0,0 +1,21 @@
# Copyright 2021 Security Scorecard Authors
#
# 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.
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
- run: mvn deploy

View File

@ -0,0 +1,25 @@
# Copyright 2021 Security Scorecard Authors
#
# 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.
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
registry-url: 'https://npm.pkg.github.com'
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -0,0 +1,34 @@
# Copyright 2021 Security Scorecard Authors
#
# 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.
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14.x'
registry-url: 'https://registry.npmjs.org'
- run: npm install
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- uses: actions/setup-node@v2
with:
registry-url: 'https://npm.pkg.github.com'
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -0,0 +1,20 @@
# Copyright 2021 Security Scorecard Authors
#
# 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.
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: nuget push **\*.nupkg -Source 'https://nuget.pkg.github.com/MyOrg/index.json' -ApiKey ${{secrets.NUGET_TOKEN}}

View File

@ -0,0 +1,26 @@
# Copyright 2021 Security Scorecard Authors
#
# 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.
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
with:
python-version: 3.9
- uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.TEST_PYPI_API_TOKEN }}

View File

@ -22,5 +22,4 @@ jobs:
packages: write
steps:
- name: some name
run: echo "write-and-read workflow"
uses: docker/build-push-action@1.2.3

View File

@ -0,0 +1,27 @@
# Copyright 2021 Security Scorecard Authors
#
# 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.
name: write-and-read workflow
on: [push]
permissions: read-all
jobs:
Explore-GitHub-Actions:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- name: Perform CodeQL Analysis
uses: github/some-action/analyze@v1
run: echo "write-and-read workflow"
# Some comment about github/codeql-action/analyze@v1