in pkg/anago/stage.go [771:883]
func (d *DefaultStage) StageArtifacts() error {
// Generate the intoto attestation, reloaded with the current run data
statement, err := d.impl.GenerateAttestation(d.state, d.options)
if err != nil {
return errors.Wrap(err, "generating the provenance attestation")
}
// Init push options for provenance document
pushBuildOptions := &build.Options{
Bucket: d.options.Bucket(),
Registry: d.options.ContainerRegistry(),
AllowDup: true,
ValidateRemoteImageDigests: true,
}
if err := d.impl.CheckReleaseBucket(pushBuildOptions); err != nil {
return errors.Wrap(err, "check release bucket access")
}
// Stage the local source tree
if err := d.impl.StageLocalSourceTree(
pushBuildOptions,
workspaceDir,
d.options.BuildVersion,
); err != nil {
return errors.Wrap(err, "staging local source tree")
}
// Add the sources tarball to the attestation
subjects, err := d.impl.GetProvenanceSubjects(
d.options, filepath.Join(workspaceDir, release.SourcesTar),
)
if err != nil {
return errors.Wrap(err, "adding sources tarball to provenance attestation")
}
statement.Subject = append(statement.Subject, subjects...)
for _, version := range d.state.versions.Ordered() {
logrus.Infof("Staging artifacts for version %s", version)
buildDir := filepath.Join(
gitRoot, fmt.Sprintf("%s-%s", release.BuildDir, version),
)
// Set the version-specific option for the push
pushBuildOptions.Version = version
pushBuildOptions.BuildDir = buildDir
// Stage local artifacts and write checksums
if err := d.impl.StageLocalArtifacts(pushBuildOptions); err != nil {
return errors.Wrap(err, "staging local artifacts")
}
gcsPath := filepath.Join(
d.options.Bucket(), release.StagePath, d.options.BuildVersion, version,
)
// Push gcs-stage to GCS
if err := d.impl.PushReleaseArtifacts(
pushBuildOptions,
filepath.Join(buildDir, release.GCSStagePath, version),
filepath.Join(gcsPath, release.GCSStagePath, version),
); err != nil {
return errors.Wrap(err, "pushing release artifacts")
}
// Push container release-images to GCS
if err := d.impl.PushReleaseArtifacts(
pushBuildOptions,
filepath.Join(buildDir, release.ImagesPath),
filepath.Join(gcsPath, release.ImagesPath),
); err != nil {
return errors.Wrap(err, "pushing release artifacts")
}
// Push container images into registry
if err := d.impl.PushContainerImages(pushBuildOptions); err != nil {
return errors.Wrap(err, "pushing container images")
}
// Add artifacts to the attestation, this should get both release-images
// and gcs-stage directories in one call.
subjects, err = d.impl.GetOutputDirSubjects(
d.options, filepath.Join(buildDir), version,
)
if err != nil {
return errors.Wrapf(err, "adding provenance of release-images for version %s", version)
}
statement.Subject = append(statement.Subject, subjects...)
}
// Push the attestation metadata file to the bucket
if err := d.impl.PushAttestation(statement, d.options); err != nil {
return errors.Wrap(err, "writing provenance metadata to disk")
}
// Delete the local source tarball
if err := d.impl.DeleteLocalSourceTarball(pushBuildOptions, workspaceDir); err != nil {
return errors.Wrap(err, "delete source tarball")
}
args := ""
if d.options.NoMock {
args += " --nomock"
}
if d.options.ReleaseType != DefaultOptions().ReleaseType {
args += " --type=" + d.options.ReleaseType
}
if d.options.ReleaseBranch != DefaultOptions().ReleaseBranch {
args += " --branch=" + d.options.ReleaseBranch
}
args += " --build-version=" + d.options.BuildVersion
logrus.Infof(
"To release this staged build, run:\n\n$ krel release%s", args,
)
return nil
}