func()

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
}