Skip to content

Commit

Permalink
Allow building and publishing images in hashrelease
Browse files Browse the repository at this point in the history
  • Loading branch information
radTuti committed Nov 4, 2024
1 parent 2782112 commit 627de38
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 181 deletions.
6 changes: 4 additions & 2 deletions .semaphore/release/hashrelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@ blocks:
jobs:
- name: Build and publish hashrelease
commands:
- |
if [[ ${SEMAPHORE_PIPELINE_PROMOTION} == "true" ]]; then export BUILD_ARGS="--build-images"; export PUBLISH_ARGS="--skip-publish-images=false"; fi
- make hashrelease
prologue:
commands:
- export GITHUB_TOKEN=${MARVIN_GITHUB_TOKEN}
- cd release
- make build
env_vars:
- name: IS_HASHRELEASE
value: "true"
- name: REGISTRIES
value: docker.io/calico
4 changes: 2 additions & 2 deletions release/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ ci: static-checks
###############################################################################
.PHONY: hashrelease
hashrelease: bin/release var-require-all-GITHUB_TOKEN
@bin/release hashrelease build
@bin/release hashrelease publish
@bin/release hashrelease build ${BUILD_ARGS}
@bin/release hashrelease publish ${PUBLISH_ARGS}

###############################################################################
# Release
Expand Down
82 changes: 68 additions & 14 deletions release/build/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ const (
newBranchFlag = "new-branch-version"

// Configuration flags for the release publish command.
skipPublishImagesFlag = "skip-publish-images"
skipPublishGitTag = "skip-publish-git-tag"
skipPublishGithubRelease = "skip-publish-github-release"
skipPublishImagesFlag = "skip-publish-images"
skipPublishGitTagFlag = "skip-publish-git-tag"
skipPublishGithubReleaseFlag = "skip-publish-github-release"
skipPublishHashreleaseFlag = "skip-publish-hashrelease-server"
)

var (
Expand Down Expand Up @@ -161,7 +162,7 @@ func hashreleaseSubCommands(cfg *config.Config) []*cli.Command {
&cli.BoolFlag{Name: skipValidationFlag, Usage: "Skip all pre-build validation", Value: false},
&cli.BoolFlag{Name: skipBranchCheckFlag, Usage: "Skip check that this is a valid release branch.", Value: false},
&cli.BoolFlag{Name: buildImagesFlag, Usage: "Build images from local codebase. If false, will use images from CI instead.", Value: false},
&cli.StringFlag{Name: imageRegistryFlag, Usage: "Specify image registry to use", Value: ""},
&cli.StringFlag{Name: imageRegistryFlag, Usage: "Specify image registry to use", EnvVars: []string{"REGISTRIES", "DEV_REGISTRIES"}, Value: ""},
&cli.StringFlag{Name: operatorOrgFlag, Usage: "Operator git organization", EnvVars: []string{"OPERATOR_GIT_ORGANIZATION"}, Value: config.OperatorDefaultOrg},
&cli.StringFlag{Name: operatorRepoFlag, Usage: "Operator git repository", EnvVars: []string{"OPERATOR_GIT_REPO"}, Value: config.OperatorDefaultRepo},
&cli.StringFlag{Name: operatorImageFlag, Usage: "Specify the operator image to use", EnvVars: []string{"OPERATOR_IMAGE"}, Value: config.OperatorDefaultImage},
Expand Down Expand Up @@ -285,6 +286,9 @@ func hashreleaseSubCommands(cfg *config.Config) []*cli.Command {
Name: "publish",
Usage: "Publish hashrelease from _output/ to hashrelease server",
Flags: []cli.Flag{
&cli.StringFlag{Name: imageRegistryFlag, Usage: "Specify image registry to use", EnvVars: []string{"REGISTRIES", "DEV_REGISTRIES"}, Value: ""},
&cli.BoolFlag{Name: skipPublishImagesFlag, Usage: "Skip publishing of container images to registry", Value: true},
&cli.BoolFlag{Name: skipPublishHashreleaseFlag, Usage: "Skip publishing to hashrelease server", Value: false},
&cli.BoolFlag{Name: latestFlag, Usage: "Promote this release as the latest for this stream", Value: true},
&cli.BoolFlag{Name: skipValidationFlag, Usage: "Skip pre-build validation", Value: false},
&cli.BoolFlag{Name: skipImageScanFlag, Usage: "Skip sending images to image scan service.", Value: false},
Expand All @@ -298,17 +302,20 @@ func hashreleaseSubCommands(cfg *config.Config) []*cli.Command {
return fmt.Errorf("%s must be set if %s is set", skipImageScanFlag, skipValidationFlag)
}

// Extract the version from pinned-version.yaml.
hash, err := pinnedversion.RetrievePinnedVersionHash(cfg.TmpFolderPath())
// Extract the pinned version as a hashrelease.
hashrel, err := pinnedversion.AsHashrelease(cfg.RepoRootDir, cfg.TmpFolderPath(), dir)
if err != nil {
return err
}
if c.Bool(latestFlag) {
hashrel = hashrel.AsLatest()
}

// Check if the hashrelease has already been published.
if published, err := tasks.HashreleasePublished(cfg, hash); err != nil {
if published, err := tasks.HashreleasePublished(cfg, hashrel.Hash); err != nil {
return err
} else if published {
return fmt.Errorf("hashrelease %s has already been published", hash)
return fmt.Errorf("%s hashrelease (%s) has already been published", hashrel.Name, hashrel.Hash)
}

// Push the operator hashrelease first before validaion
Expand All @@ -322,10 +329,47 @@ func hashreleaseSubCommands(cfg *config.Config) []*cli.Command {
if err := o.Publish(cfg.TmpFolderPath()); err != nil {
return err
}
if !c.Bool(skipValidationFlag) {
tasks.HashreleaseValidate(cfg, c.Bool(skipImageScanFlag))

if !c.Bool(skipValidationFlag) && !c.Bool(buildImagesFlag) {
if err := tasks.HashreleaseValidate(cfg, c.Bool(skipImageScanFlag)); err != nil {
return err
}
}

pubOpts := []calico.PublishOptions{}
if !c.Bool(skipPublishImagesFlag) {
pubOpts = append(pubOpts, calico.PublishImages())
}
if !c.Bool(skipPublishHashreleaseFlag) {
pubOpts = append(pubOpts, calico.PublishHashrelease())
}
opts := []calico.Option{
calico.WithRepoRoot(cfg.RepoRootDir),
calico.IsHashRelease(),
calico.WithVersions(&version.Data{
ProductVersion: version.New(hashrel.ProductVersion),
OperatorVersion: version.New(hashrel.OperatorVersion),
}),
calico.WithGithubOrg(c.String(orgFlag)),
calico.WithRepoName(c.String(repoFlag)),
calico.WithRepoRemote(cfg.GitRemote),
calico.WithHashrelease(*hashrel, cfg.HashreleaseServerConfig),
calico.WithPublishOptions(pubOpts...),
}
if reg := c.String(imageRegistryFlag); reg != "" {
opts = append(opts, calico.WithImageRegistries([]string{reg}))
}
r := calico.NewManager(opts...)
if err := r.PublishRelease(); err != nil {
return err
}

// Send a slack message to notify that the hashrelease has been published.
if !c.Bool(skipPublishHashreleaseFlag) {
if err := tasks.HashreleaseSlackMessage(cfg, hashrel); err != nil {
return err
}
}
tasks.HashreleasePush(cfg, dir, c.Bool(latestFlag))
return nil
},
},
Expand Down Expand Up @@ -428,8 +472,8 @@ func releaseSubCommands(cfg *config.Config) []*cli.Command {
&cli.StringFlag{Name: orgFlag, Usage: "Git organization", EnvVars: []string{"ORGANIZATION"}, Value: config.DefaultOrg},
&cli.StringFlag{Name: repoFlag, Usage: "Git repository", EnvVars: []string{"GIT_REPO"}, Value: config.DefaultRepo},
&cli.BoolFlag{Name: skipPublishImagesFlag, Usage: "Skip publishing of container images to registry", Value: false},
&cli.BoolFlag{Name: skipPublishGitTag, Usage: "Skip publishing of tag to git repository", Value: false},
&cli.BoolFlag{Name: skipPublishGithubRelease, Usage: "Skip publishing of release to Github", Value: false},
&cli.BoolFlag{Name: skipPublishGitTagFlag, Usage: "Skip publishing of tag to git repository", Value: false},
&cli.BoolFlag{Name: skipPublishGithubReleaseFlag, Usage: "Skip publishing of release to Github", Value: false},
&cli.StringFlag{Name: imageRegistryFlag, Usage: "Specify image registry to use", Value: ""},
},
Action: func(c *cli.Context) error {
Expand All @@ -438,14 +482,24 @@ func releaseSubCommands(cfg *config.Config) []*cli.Command {
if err != nil {
return err
}
pubOpts := []calico.PublishOptions{}
if !c.Bool(skipPublishImagesFlag) {
pubOpts = append(pubOpts, calico.PublishImages())
}
if !c.Bool(skipPublishGitTagFlag) {
pubOpts = append(pubOpts, calico.PublishGitTag())
}
if !c.Bool(skipPublishGithubReleaseFlag) {
pubOpts = append(pubOpts, calico.PublishGithubRelease())
}
opts := []calico.Option{
calico.WithRepoRoot(cfg.RepoRootDir),
calico.WithVersions(&version.Data{
ProductVersion: ver,
OperatorVersion: operatorVer,
}),
calico.WithOutputDir(filepath.Join(baseUploadDir, ver.FormattedString())),
calico.WithPublishOptions(!c.Bool(skipPublishImagesFlag), !c.Bool(skipPublishGitTag), !c.Bool(skipPublishGithubRelease)),
calico.WithPublishOptions(pubOpts...),
calico.WithGithubOrg(c.String(orgFlag)),
calico.WithRepoName(c.String(repoFlag)),
calico.WithRepoRemote(cfg.GitRemote),
Expand Down
13 changes: 12 additions & 1 deletion release/internal/hashreleaseserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ type Hashrelease struct {
// Stream is the version the hashrelease is for (e.g master, v3.19)
Stream string

// ProductVersion is the product version in the hashrelease
ProductVersion string

// OperatorVersion is the operator version for the hashreleaseq
OperatorVersion string

// Source is the source of hashrelease content
Source string

Expand All @@ -62,10 +68,15 @@ type Hashrelease struct {
Latest bool
}

func (h Hashrelease) URL() string {
func (h *Hashrelease) URL() string {
return fmt.Sprintf("https://%s.%s", h.Name, BaseDomain)
}

func (h *Hashrelease) AsLatest() *Hashrelease {
h.Latest = true
return h
}

func remoteDocsPath(user string) string {
path := "files"
if user != "root" {
Expand Down
79 changes: 22 additions & 57 deletions release/internal/pinnedversion/pinnedversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,63 +197,6 @@ func RetrievePinnedOperator(outputDir string) (registry.OperatorComponent, error
}, nil
}

// RetrievePinnedOperatorVersion retrieves the operator version from the pinned version file.
func RetrievePinnedOperatorVersion(outputDir string) (string, error) {
operator, err := RetrievePinnedOperator(outputDir)
if err != nil {
return "", err
}
return operator.Version, nil
}

// RetrieveReleaseName retrieves the release name from the pinned version file.
func RetrieveReleaseName(outputDir string) (string, error) {
pinnedVersionPath := pinnedVersionFilePath(outputDir)
var pinnedversion PinnedVersionFile
if pinnedVersionData, err := os.ReadFile(pinnedVersionPath); err != nil {
return "", err
} else if err := yaml.Unmarshal([]byte(pinnedVersionData), &pinnedversion); err != nil {
return "", err
}
return pinnedversion[0].ReleaseName, nil
}

// RetrievePinnedProductVersion retrieves the product version from the pinned version file.
func RetrievePinnedProductVersion(outputDir string) (string, error) {
pinnedVersionPath := pinnedVersionFilePath(outputDir)
var pinnedversion PinnedVersionFile
if pinnedVersionData, err := os.ReadFile(pinnedVersionPath); err != nil {
return "", err
} else if err := yaml.Unmarshal([]byte(pinnedVersionData), &pinnedversion); err != nil {
return "", err
}
return pinnedversion[0].Title, nil
}

// RetrievePinnedVersionNote retrieves the note from the pinned version file.
func RetrievePinnedVersionNote(outputDir string) (string, error) {
pinnedVersionPath := pinnedVersionFilePath(outputDir)
var pinnedversion PinnedVersionFile
if pinnedVersionData, err := os.ReadFile(pinnedVersionPath); err != nil {
return "", err
} else if err := yaml.Unmarshal([]byte(pinnedVersionData), &pinnedversion); err != nil {
return "", err
}
return pinnedversion[0].Note, nil
}

// RetrievePinnedVersionHash retrieves the hash from the pinned version file.
func RetrievePinnedVersionHash(outputDir string) (string, error) {
pinnedVersionPath := pinnedVersionFilePath(outputDir)
var pinnedversion PinnedVersionFile
if pinnedVersionData, err := os.ReadFile(pinnedVersionPath); err != nil {
return "", err
} else if err := yaml.Unmarshal([]byte(pinnedVersionData), &pinnedversion); err != nil {
return "", err
}
return pinnedversion[0].Hash, nil
}

// RetrieveComponentsToValidate retrieves the components to validate from the pinned version file.
func RetrieveComponentsToValidate(outputDir string) (map[string]registry.Component, error) {
pinnedVersionPath := pinnedVersionFilePath(outputDir)
Expand Down Expand Up @@ -284,3 +227,25 @@ func RetrieveComponentsToValidate(outputDir string) (map[string]registry.Compone
}
return components, nil
}

func AsHashrelease(repoRootDir, tmpDir, srcDir string) (*hashreleaseserver.Hashrelease, error) {
productBranch, err := utils.GitBranch(repoRootDir)
if err != nil {
logrus.WithError(err).Errorf("Failed to get %s branch name", utils.ProductName)
return nil, err
}
pinnedVersion, err := RetrievePinnedVersion(tmpDir)
if err != nil {
logrus.WithError(err).Fatal("Failed to get pinned version")
}
return &hashreleaseserver.Hashrelease{
Name: pinnedVersion.ReleaseName,
Hash: pinnedVersion.Hash,
Note: pinnedVersion.Note,
Stream: version.DeterminePublishStream(productBranch, pinnedVersion.Title),
ProductVersion: pinnedVersion.Title,
OperatorVersion: pinnedVersion.TigeraOperator.Version,
Source: srcDir,
Time: time.Now(),
}, nil
}
Loading

0 comments on commit 627de38

Please sign in to comment.