Skip to content

Conversation

@radTuti
Copy link
Contributor

@radTuti radTuti commented Dec 16, 2025

Description

This adds creating and publishing an operator version. It aligns the process for both a hashrelease operator version and a release operator version. For release operator version, it creates a github release if indicated.

For hashreleases, there is a new enhancement for creating a hashrelease by providing the calico and/or enterprise version in place of the versions file.

For PR reviewers

A note for code reviewers - all pull requests must have the following:

  • Milestone set according to targeted release.
  • Appropriate labels:
    • kind/bug if this is a bugfix.
    • kind/enhancement if this is a a new feature.
    • enterprise if this PR applies to Calico Enterprise only.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces new build and publish commands to the operator release tooling, unifying the workflow for both release and hashrelease operator versions. It adds support for creating hashreleases by directly specifying Calico/Enterprise versions instead of requiring a versions file, and enables automatic GitHub release creation during the publish process.

Key Changes

  • Added build and publish commands that handle both release and hashrelease workflows with consistent patterns
  • Enhanced hashrelease creation to accept Calico/Enterprise versions directly via new flags (--calico-version, --enterprise-version, etc.)
  • Integrated GitHub release creation into the publish workflow with draft/prerelease support

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
hack/release/build.go New build command implementing image building for releases and hashreleases with version/registry configuration
hack/release/publish.go New publish command handling image publishing and optional GitHub release creation
hack/release/public.go New github/public command for creating or updating GitHub releases independently
hack/release/utils.go Added utility functions for handling trailing slashes, checking prerelease versions, and improved error messages
hack/release/utils_test.go Added test coverage for new utility functions and updated existing tests with new function signatures
hack/release/github.go Added GitHub release creation/update methods with draft and prerelease support
hack/release/flags.go Added new flags for build/publish commands including registry, CRDs directories, and hashrelease-specific options
hack/release/prep.go Updated to use new utility functions and added support for CRDs directory flags
hack/release/from.go Updated error messages and modified to use new repository-aware config retrieval
hack/release/releasenotes.go Added validation for GitHub token and improved output messaging
hack/release/main.go Registered new build, publish, and public commands
hack/release/README.md Added comprehensive documentation for new commands with usage examples
RELEASING.md Updated release process documentation to reflect new tooling workflow
Makefile Simplified release targets to use new CLI commands
go.mod/go.sum Added google/go-containerregistry dependency for image registry interactions
.semaphore/release.yml Updated pipeline name to "Operator Release"
.semaphore/push_images.yml Renamed block from "Push Images / Maybe Release" to "Push Images"
cmd/main.go Updated code comment reference to new build.go location

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@radTuti radTuti changed the title feat(release): feat(release): add build & publish to release tool Dec 16, 2025
@danudey
Copy link
Contributor

danudey commented Dec 19, 2025

Attempted to do a build, got some error messaging:

INFO[0000] Building Operator                             arches="[amd64 arm64 ppc64le s390x]" release=true version=v1.42.0
ERROR[0000] make[1]: Entering directory '/home/dan/source/tigera/operator-master'
make var-require REQUIRED_VARS=VERSION-GIT_VERSION FAIL_NOT_SET=true
make[2]: Entering directory '/home/dan/source/tigera/operator-master'
make[2]: 'var-require' is up to date.
make[2]: Leaving directory '/home/dan/source/tigera/operator-master'
make[1]: Leaving directory '/home/dan/source/tigera/operator-master'  arches="[amd64 arm64 ppc64le s390x]" release=true version=v1.42.0
FATAL[0000] Error running command                         error="building Operator: exit status 2: Makefile:573: *** Attempt to build v1.42.0 from v1.42.0-0.dev-19-ga28a5204246a.  Stop."
make: *** [Makefile:567: release] Error 1

There's no indication of why this is a problem or what to do about it.

Running it again, I now see a different error for some reason:

FATAL[0000] Error running command                         error="building Operator: exit status 2: + uname -m\n+ bash -c 'if [[ \"x86_64\" == \"x86_64\" ]]; then echo amd64; else uname -m; fi'\n+ uname -s\n+ tr A-Z a-z\n+ uname -m\n+ uname -m\n+ echo /home/dan/.local/share/go\n+ cut -d: -f1\n+ id -u dan\n+ echo /home/dan/.local/share/go\n+ cut -d: -f1\n+ find ./pkg -name '*.go'\n+ find ./api -name '*.go'\n+ find ./internal/ -name '*.go'\n+ find ./test -name '*.go'\n+ git describe --tags --dirty --always --abbrev=12\n+ find ./hack/release -type f\n+ find ./hack/gen-versions -type f\n+ ./install-git-hooks\n+ echo '\"'\n+ make var-require REQUIRED_VARS=VERSION-GIT_VERSION FAIL_NOT_SET=true\n+ uname -m\n+ bash -c 'if [[ \"x86_64\" == \"x86_64\" ]]; then echo amd64; else uname -m; fi'\n+ uname -s\n+ tr A-Z a-z\n+ uname -m\n+ uname -m\n+ echo /home/dan/.local/share/go\n+ cut -d: -f1\n+ id -u dan\n+ echo /home/dan/.local/share/go\n+ cut -d: -f1\n+ find ./pkg -name '*.go'\n+ find ./api -name '*.go'\n+ find ./internal/ -name '*.go'\n+ find ./test -name '*.go'\n+ git describe --tags --dirty --always --abbrev=12\n+ find ./hack/release -type f\n+ find ./hack/gen-versions -type f\n+ ./install-git-hooks\n+ echo '\"'\n+ git describe --tags --dirty --always --abbrev=12\n+ git describe --tags --dirty --always --abbrev=12\nMakefile:573: *** Attempt to build v1.42.1 from v1.42.0-0.dev-19-ga28a5204246a.  Stop."

The "error message concatenated with a bunch of literal '\n'" is nearly impossible to read; is it possible to clean these errors up and print them in a more readable way?

@radTuti
Copy link
Contributor Author

radTuti commented Dec 29, 2025

Attempted to do a build, got some error messaging

@danudey what did you run for the build. Also did you follow the readme?

From the logs you included, it seems like you are trying to do a release build on a git hash with no tag. The second go around switched to using v1.42.1 (from v1.42.0) and not sure what you did to get more info in the error. For non-release build, either the --hashrelease flag must be passed or the env var HASHRELEASE=true must be set.

Both attempt have this:

Makefile:573: *** Attempt to build v1.42.1 from v1.42.0-0.dev-19-ga28a5204246a.  Stop.

This indicated that the failure is coming from the Makefile at line 573 which is a check that has existed in the repo since the release process was established.

@radTuti
Copy link
Contributor Author

radTuti commented Dec 29, 2025

The "error message concatenated with a bunch of literal '\n'" is nearly impossible to read; is it possible to clean these errors up and print them in a more readable way?

I have updated the logrus text formatter to disable quote which should stop newlines from being escaped. However I find readablity is based on personal preferences; while I have made some adjustment in this PR, I think any further changes should be added outside of this PR.

@danudey
Copy link
Contributor

danudey commented Jan 6, 2026

Also did you follow the readme?

Nope, I definitely did not. That said, the readme tells you what commands there are, but it would be nice if it also had sections for "how to publish a hashrelease" (e.g. the steps to get all the correct information, check out calico/calient, etc), "how to publish a release" (what parameters need to be provided, etc.). As an example, it doesn't seem to say anywhere that a tag needs to exist ahead of time, nor does the error message indicate that. I know that that problem is in the Makefile right now, but if we're updating how the release process works then at least updating that error message would be a nice QoL fix - either be more specific about the error or direct the user to the release tool readme.

Comment on lines 44 to 45
Version: version,
Commands: []*cli.Command{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Version: version,
Commands: []*cli.Command{
Version: version,
EnableShellCompletion: true,
Commands: []*cli.Command{


// Build the Operator and verify the build
buildLog.Info("Building Operator")
if out, err := makeInDir(repoRootDir, "release-build", buildEnv...); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be beneficial to add slightly more detail to the process, even without debug. For example, it might be a good idea to have makeInDir log what it's running even if it's as simple as "Running make release-build...".

My thinking is that a lot of these targets can take a long time to run, so knowing what step it's on (or what command to run to duplicate the step) could be very beneficial). I know that if debug logging is enabled then commands get logged in runCommandInDir, but a lot of other output gets logged also, and we don't necessarily want to log every command we run; just adding unconditional logging of args to makeInDir could ease debugging in future.

[--calico-version <calico version> | --calico-versions <path to calico version file> |--enterprise-version <enterprise version> | --enterprise-versions <path to enterprise version file>]
```

#### Examples
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The readme has examples that show creating a build/hashrelease/etc with a Calico version or a Calico Enterprise version. Can both be used? e.g. if I wanted to create a hashrelease which included both the latest Calico and Calient? I'm not sure if this is something we'd ever want, but would it work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is likely not going to be done but it is possible. Will add an example for that.

> [!NOTE]
> At least one of Calico or Calico Enterprise version must be specified.
> [!IMPORTANT]
> One of Calico or Calico Enterprise version must be specified.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only one? Or at least one? The phrasing here implies one xor the other, but we've had enough double-releases recently that I would assume I can specify both?

noteData, err := r.collectReleaseNotes(ctx, useLocal)
if err != nil {
return fmt.Errorf("error collecting release notes: %s", err)
return fmt.Errorf("collecting release notes: %s", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this process still error if we successfully fetch from Github but there are no PRs with release-note-required (i.e. there are no release notes to include)? If not, do we include a note like that in our output?

Also while I'm thinking about it, I have no idea if it's feasible but I wish our release note generation would highlight which new version an Operator release is supporting, e.g. an automatic "This version of Operator is being released to support Calico v3.31.4". Wishlist.

Comment on lines +384 to +386
logrus.Warnf("GitHub release already exists, update manually: %s", got.GetHTMLURL())
return ErrGitHubReleaseExists
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to include some kind of tags in the release notes so that we can find and update an existing release's (or a draft release's) release notes?

<!-- start release notes -->
## Bug fixes

* foo
* bar

<!-- end release notes -->

The example I'm thinking is we generate a release with its release notes and someone wants to fix/update the release note in their PR; it would be nice to be able to kick off the release tool again to say "Go update the release notes for this release and/or show me the diff".

Not necessary for now, but a thought.

This addresses most of the review feedback given.
Release notes related feedback will be handled in a separate PR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants