mirror of
https://github.com/siderolabs/kres.git
synced 2026-02-05 09:45:35 +01:00
feat: sign with cosign checksums for release
produce signatures for verifying checksums Signed-off-by: Caleb Woodbine <caleb.woodbine@siderolabs.com> Signed-off-by: Noel Georgi <git@frezbo.dev>
This commit is contained in:
committed by
Noel Georgi
parent
5128bc12f8
commit
880678f5a4
11
.github/workflows/ci.yaml
vendored
11
.github/workflows/ci.yaml
vendored
@@ -1,6 +1,6 @@
|
||||
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
|
||||
#
|
||||
# Generated on 2025-06-02T14:41:29Z by kres 9f64b0d-dirty.
|
||||
# Generated on 2025-07-02T13:16:29Z by kres 43deb91-dirty.
|
||||
|
||||
name: default
|
||||
concurrency:
|
||||
@@ -22,6 +22,7 @@ jobs:
|
||||
permissions:
|
||||
actions: read
|
||||
contents: write
|
||||
id-token: write
|
||||
issues: read
|
||||
packages: write
|
||||
pull-requests: read
|
||||
@@ -112,6 +113,13 @@ jobs:
|
||||
PUSH: "true"
|
||||
run: |
|
||||
make image-kres IMAGE_TAG=latest
|
||||
- name: Install Cosign
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: sigstore/cosign-installer@v3
|
||||
- name: Sign artifacts
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
find _out -type f -name _out/kres-* -exec cosign sign-blob --yes --output {}.sig {} \;
|
||||
- name: Generate Checksums
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
@@ -131,3 +139,4 @@ jobs:
|
||||
files: |-
|
||||
_out/kres-*
|
||||
_out/sha*.txt
|
||||
_out/*.sig
|
||||
|
||||
@@ -19,6 +19,10 @@ spec:
|
||||
PLATFORM: linux/amd64,linux/arm64
|
||||
entrypointArgs: ['gen']
|
||||
---
|
||||
kind: common.Release
|
||||
spec:
|
||||
generateSignatures: true
|
||||
---
|
||||
kind: golang.Build
|
||||
spec:
|
||||
outputs:
|
||||
|
||||
@@ -256,6 +256,11 @@ func (o *Output) AddStep(jobName string, steps ...*JobStep) {
|
||||
o.workflows[ciWorkflow].Jobs[jobName].Steps = append(o.workflows[ciWorkflow].Jobs[jobName].Steps, steps...)
|
||||
}
|
||||
|
||||
// AddJobPermissions adds permissions to the job.
|
||||
func (o *Output) AddJobPermissions(jobName, permission, value string) {
|
||||
o.workflows[ciWorkflow].Jobs[jobName].Permissions[permission] = value
|
||||
}
|
||||
|
||||
// AddStepBefore adds step before another step in the job.
|
||||
func (o *Output) AddStepBefore(jobName, beforeStepID string, steps ...*JobStep) {
|
||||
job := o.workflows[ciWorkflow].Jobs[jobName]
|
||||
|
||||
@@ -79,10 +79,11 @@ type CoverageStep struct {
|
||||
|
||||
// ReleaseStep defines options for release steps.
|
||||
type ReleaseStep struct {
|
||||
BaseDirectory string `yaml:"baseDirectory"`
|
||||
ReleaseNotes string `yaml:"releaseNotes"`
|
||||
Artifacts []string `yaml:"artifacts"`
|
||||
GenerateChecksums bool `yaml:"generateChecksums"`
|
||||
BaseDirectory string `yaml:"baseDirectory"`
|
||||
ReleaseNotes string `yaml:"releaseNotes"`
|
||||
Artifacts []string `yaml:"artifacts"`
|
||||
GenerateChecksums bool `yaml:"generateChecksums"`
|
||||
GenerateSignatures bool `yaml:"generateSignatures"`
|
||||
}
|
||||
|
||||
// RegistryLoginStep defines options for registry login steps.
|
||||
@@ -281,7 +282,29 @@ func (gh *GHWorkflow) CompileGitHubWorkflow(o *ghworkflow.Output) error {
|
||||
SetWith("draft", "true").
|
||||
SetWith("files", strings.Join(artifacts, "\n"))
|
||||
|
||||
if step.ReleaseStep.GenerateSignatures {
|
||||
jobDef.Permissions["id-token"] = "write"
|
||||
|
||||
cosignStep := ghworkflow.Step("Install Cosign").
|
||||
SetUses("sigstore/cosign-installer@" + config.CosignInstallActionVerson)
|
||||
|
||||
jobDef.Steps = append(jobDef.Steps, cosignStep)
|
||||
|
||||
signCommands := xslices.Map(artifacts, func(artifact string) string {
|
||||
return fmt.Sprintf("cosign sign-blob --output %s.sig --yes %s", artifact, artifact)
|
||||
})
|
||||
|
||||
signStep := ghworkflow.Step("Sign artifacts").
|
||||
SetCommand(strings.Join(signCommands, "\n"))
|
||||
|
||||
jobDef.Steps = append(jobDef.Steps, signStep)
|
||||
|
||||
releaseStep.SetWith("files", strings.Join(artifacts, "\n")+"\n"+filepath.Join(step.ReleaseStep.BaseDirectory, "*.sig"))
|
||||
}
|
||||
|
||||
if step.ReleaseStep.GenerateChecksums {
|
||||
jobDef.Permissions["id-token"] = "write"
|
||||
|
||||
checkSumCommands := []string{
|
||||
fmt.Sprintf("cd %s", step.ReleaseStep.BaseDirectory),
|
||||
fmt.Sprintf("sha256sum %s > %s", strings.Join(step.ReleaseStep.Artifacts, " "), "sha256sum.txt"),
|
||||
@@ -291,10 +314,29 @@ func (gh *GHWorkflow) CompileGitHubWorkflow(o *ghworkflow.Output) error {
|
||||
checkSumStep := ghworkflow.Step("Generate Checksums").
|
||||
SetCommand(strings.Join(checkSumCommands, "\n"))
|
||||
|
||||
jobDef.Steps = append(jobDef.Steps, checkSumStep)
|
||||
|
||||
releaseStep.
|
||||
SetWith("files", strings.Join(artifacts, "\n")+"\n"+filepath.Join(step.ReleaseStep.BaseDirectory, "sha*.txt"))
|
||||
|
||||
jobDef.Steps = append(jobDef.Steps, checkSumStep)
|
||||
if step.ReleaseStep.GenerateSignatures {
|
||||
checkSumSignCommands := []string{
|
||||
"cosign sign-blob --output sha256sum.txt.sig --yes sha256sum.txt",
|
||||
"cosign sign-blob --output sha512sum.txt.sig --yes sha512sum.txt",
|
||||
}
|
||||
|
||||
signStep := ghworkflow.Step("Sign checksums").
|
||||
SetCommand(strings.Join(checkSumSignCommands, "\n"))
|
||||
|
||||
jobDef.Steps = append(jobDef.Steps, signStep)
|
||||
|
||||
releaseStep.SetWith("files",
|
||||
strings.Join(artifacts, "\n")+
|
||||
"\n"+
|
||||
filepath.Join(step.ReleaseStep.BaseDirectory, "sha*.txt")+"\n"+
|
||||
filepath.Join(step.ReleaseStep.BaseDirectory, "*.sig"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
jobDef.Steps = append(jobDef.Steps, releaseStep)
|
||||
|
||||
@@ -27,7 +27,8 @@ type Release struct {
|
||||
// List of file patterns relative to the ArtifactsPath to include in the release.
|
||||
//
|
||||
// If not specified, defaults to the auto-detected commands.
|
||||
Artifacts []string `yaml:"artifacts"`
|
||||
Artifacts []string `yaml:"artifacts"`
|
||||
GenerateSignatures bool `yaml:"generateSignatures,omitempty"`
|
||||
}
|
||||
|
||||
// NewRelease initializes Release.
|
||||
@@ -88,7 +89,35 @@ func (release *Release) CompileGitHubWorkflow(output *ghworkflow.Output) error {
|
||||
checkSumStep := ghworkflow.Step("Generate Checksums").
|
||||
SetCommand(strings.Join(checkSumCommands, "\n"))
|
||||
|
||||
releaseStep.SetWith("files", strings.Join(artifacts, "\n")+"\n"+filepath.Join(release.meta.ArtifactsPath, "sha*.txt"))
|
||||
artifactsToUpload := strings.Join(artifacts, "\n") + "\n" + filepath.Join(release.meta.ArtifactsPath, "sha*.txt")
|
||||
|
||||
if release.GenerateSignatures {
|
||||
output.AddJobPermissions("default", "id-token", "write")
|
||||
|
||||
cosignStep := ghworkflow.Step("Install Cosign").
|
||||
SetUses("sigstore/cosign-installer@" + config.CosignInstallActionVerson)
|
||||
|
||||
if err := cosignStep.SetConditions("only-on-tag"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
signCommands := xslices.Map(artifacts, func(artifact string) string {
|
||||
return fmt.Sprintf("find %s -type f -name %s -exec cosign sign-blob --yes --output {}.sig {} \\;", release.meta.ArtifactsPath, artifact)
|
||||
})
|
||||
|
||||
signStep := ghworkflow.Step("Sign artifacts").
|
||||
SetCommand(strings.Join(signCommands, "\n"))
|
||||
|
||||
if err := signStep.SetConditions("only-on-tag"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
steps = append(steps, cosignStep, signStep)
|
||||
|
||||
artifactsToUpload += "\n" + filepath.Join(release.meta.ArtifactsPath, "*.sig")
|
||||
}
|
||||
|
||||
releaseStep.SetWith("files", artifactsToUpload)
|
||||
|
||||
if err := checkSumStep.SetConditions("only-on-tag"); err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user