Skip to content

Commit

Permalink
Fix Go release facet
Browse files Browse the repository at this point in the history
This updates the SLSA SourceBundleFacet for Go to include docker
correctly and templatize a few things in the right places.
  • Loading branch information
mlieberman85 committed Mar 2, 2024
1 parent ffb13ae commit a57692d
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 9 deletions.
55 changes: 48 additions & 7 deletions skootrs-lib/src/service/facet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,11 @@ impl SourceBundleContentGenerator for GoGithubSourceBundleContentHandler {
) -> Result<SourceBundleContent, SkootError> {
match params.facet_type {
SupportedFacetType::Gitignore => self.generate_gitignore_content(params),
// TODO: Rename this to something like SecureBuild.
// This also does a bunch of other stuff like setting up releases, generating SBOM, etc.
// So for now just we just use it instead of creating multiple facets.
// The better option is to probably set up some mapping of properties like SLSA, SBOMGenerating, etc.
// to a single SecureBuild facet.
SupportedFacetType::SLSABuild => self.generate_slsa_build_content(params),
SupportedFacetType::DependencyUpdateTool => {
self.generate_dependency_update_tool_content(params)
Expand Down Expand Up @@ -581,21 +586,55 @@ impl GoGithubSourceBundleContentHandler {
// Note: Content mostly taken from https://github.com/guacsec/guac/blob/f1703bd4ca3c0ec0fa55c5a3401d50578fb1680e/.github/workflows/release.yaml
fn generate_slsa_build_content(
&self,
_params: &SourceBundleFacetParams,
params: &SourceBundleFacetParams,
) -> Result<SourceBundleContent, SkootError> {
// TODO: This should really be a struct that serializes to yaml instead of just a file template
#[derive(Template)]
#[template(path = "go.releases.yml", escape = "none")]
struct SLSABuildTemplateParams {}
struct ReleaseTemplateParams {}

#[derive(Template)]
#[template(path = "Dockerfile.goreleaser", escape = "none")]
struct DockerfileTemplateParams {
project_name: String,
}

let slsa_build_template_params = SLSABuildTemplateParams {};
let content = slsa_build_template_params.render()?;
#[derive(Template)]
#[template(path = "goreleaser.yml", escape = "none")]
struct GoReleaserTemplateParams {
project_name: String,
module_name: String,
}

let module = match &params.common.ecosystem {
InitializedEcosystem::Go(go) => go.module(),
_ => unreachable!("Ecosystem should be Go"),
};

let slsa_build_template_params = ReleaseTemplateParams {};
let dockerfile_template_params = DockerfileTemplateParams {
project_name: params.common.project_name.clone(),
};
let goreleaser_template_params = GoReleaserTemplateParams {
project_name: params.common.project_name.clone(),
module_name: module,
};

Ok(SourceBundleContent {
source_files_content: vec![SourceFileContent {
name: "releases.yml".to_string(),
path: ".github/workflows/".to_string(),
content,
content: slsa_build_template_params.render()?,
},
SourceFileContent {
name: "Dockerfile.goreleaser".to_string(),
path: "./".to_string(),
content: dockerfile_template_params.render()?,
},
SourceFileContent {
name: ".goreleaser.yml".to_string(),
path: "./".to_string(),
content: goreleaser_template_params.render()?,
}],
facet_type: SupportedFacetType::SLSABuild,
})
Expand Down Expand Up @@ -726,7 +765,7 @@ impl FacetSetParamsGenerator {
common_params: &CommonFacetParams,
) -> Result<FacetSetParams, SkootError> {
use SupportedFacetType::{
DefaultSourceCode, DependencyUpdateTool, Fuzzing, Gitignore, License, Readme,
DefaultSourceCode, DependencyUpdateTool, Gitignore, License, Readme,
SLSABuild, Scorecard, SecurityInsights, SecurityPolicy, SAST,
};
let supported_facets = [
Expand All @@ -739,7 +778,9 @@ impl FacetSetParamsGenerator {
// SBOMGenerator, // Handled by the SLSABuild facet
// StaticCodeAnalysis,
DependencyUpdateTool,
Fuzzing,
// TODO: Fuzzing right now requires a bunch of resources that are unavailable to most projects without
// some sort of manual intervention. This is disabled until some option becomes available.
// Fuzzing,
Scorecard,
// PublishPackages,
// PinnedDependencies,
Expand Down
8 changes: 8 additions & 0 deletions skootrs-lib/templates/Dockerfile.goreleaser
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM --platform=$BUILDPLATFORM alpine:latest@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b as certs
RUN apk --update add ca-certificates

FROM --platform=$BUILDPLATFORM alpine:latest@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b
COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
RUN apk --update --no-cache add wget && rm -rf /var/cache/apk/*

workdir /{{ project_name }}
7 changes: 5 additions & 2 deletions skootrs-lib/templates/go.releases.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{% raw %}

#
# Copyright 2022 The GUAC Authors.
#
Expand Down Expand Up @@ -107,6 +108,9 @@ jobs:
sbom-container:
# generate sbom for container as goreleaser can't - https://goreleaser.com/customization/sbom/#limitations
permissions:
id-token: write
packages: write
name: generate sbom for container
runs-on: ubuntu-latest
needs: [goreleaser]
Expand All @@ -132,8 +136,7 @@ jobs:
run: |
#!/usr/bin/env bash
set -euo pipefail
cosign attach sbom --sbom spdx.sbom.json ${IMAGE_URI_DIGEST}
cosign sign -a git_sha=$GITHUB_SHA --attachment sbom ${IMAGE_URI_DIGEST} --yes
cosign attest --predicate spdx.sbom.json ${IMAGE_URI_DIGEST} --yes
shell: bash
env:
IMAGE_URI_DIGEST: ${{ needs.goreleaser.outputs.image }}@${{ needs.goreleaser.outputs.digest }}
Expand Down
137 changes: 137 additions & 0 deletions skootrs-lib/templates/goreleaser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
project_name: {{ project_name }}


env:
- CGO_ENABLED=0
- PKG={{ module_name }}
{% raw %}

dockers:
# see details at https://goreleaser.com/customization/docker/
- use: buildx
goos: linux
goarch: amd64
image_templates:
- "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Tag }}-amd64"
dockerfile: Dockerfile.goreleaser
build_flag_templates:
- "--platform=linux/amd64"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.name={{.ProjectName}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Version}}"
- "--label=org.opencontainers.image.source={{.GitURL}}"
- "--builder={{ .Env.DOCKER_CONTEXT }}"
- use: buildx
goos: linux
goarch: arm64
image_templates:
- "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Tag }}-arm64"
dockerfile: Dockerfile.goreleaser
build_flag_templates:
- "--platform=linux/arm64"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.name={{.ProjectName}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Version}}"
- "--label=org.opencontainers.image.source={{.GitURL}}"
- "--builder={{ .Env.DOCKER_CONTEXT }}"

docker_manifests:
- name_template: "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Tag }}"
image_templates:
- "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Tag }}-amd64"
- "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Tag }}-arm64"

docker_signs:
- cmd: cosign
artifacts: all
output: true
args:
- "sign"
- "--a"
- "git_sha={{.FullCommit}}"
- "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}@${digest}"
- "--yes"

before:
hooks:
- go mod tidy
- go generate ./...

builds:
- main: ./
id: main
binary: main-{{ .Os }}-{{ .Arch }}
ldflags:
# See https://goreleaser.com/customization/templates/#common-fields for field definitions
- -X {{.Env.PKG}}.Commit={{.FullCommit}}
- -X {{.Env.PKG}}.Date={{.Date}}
- -X {{.Env.PKG}}.Version={{.Summary}}
goos: [ 'darwin', 'linux', 'windows' ]
goarch:
- amd64
- arm64
- arm
ignore:
- goos: windows
goarch: arm64
- goos: windows
goarch: arm

universal_binaries:
- replace: true
name_template: main
id: main
ids:
- main

sboms:
- id: bins
artifacts: binary
documents:
- "${artifact}.spdx.sbom.json"

signs:
- id: cosign-keyless
artifacts: checksum
signature: "${artifact}-keyless.sig"
certificate: "${artifact}-keyless.pem"
cmd: cosign
args:
- "sign-blob"
- "--yes"
- "--output-signature"
- "${artifact}-keyless.sig"
- "--output-certificate"
- "${artifact}-keyless.pem"
- "${artifact}"
output: true

archives:
- format: binary
name_template: "{{ .Binary }}"
allow_different_binary_count: true

checksum:
name_template: "{{ .ProjectName }}_checksums.txt"

snapshot:
name_template: SNAPSHOT-{{ .ShortCommit }}

changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"

release:
prerelease: auto
draft: false
replace_existing_draft: true
# The lines beneath this are called `modelines`. See `:help modeline`
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
{% endraw %}

0 comments on commit a57692d

Please sign in to comment.