Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

consolidate version information #32973

Merged
merged 4 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/scripts/get_product_version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ LDFLAGS="-w -s"
if [[ "$EXPERIMENTS_ENABLED" == 1 ]]; then
LDFLAGS="${LDFLAGS} -X 'main.experimentsAllowed=yes'"
fi
LDFLAGS="${LDFLAGS} -X 'github.com/hashicorp/terraform/version.Version=${BASE_VERSION}'"
LDFLAGS="${LDFLAGS} -X 'github.com/hashicorp/terraform/version.Prerelease=${PRERELEASE}'"
LDFLAGS="${LDFLAGS} -X 'github.com/hashicorp/terraform/version.dev=no'"

echo "Building Terraform CLI ${VERSION}"
if [[ "$EXPERIMENTS_ENABLED" == 1 ]]; then
Expand Down
42 changes: 42 additions & 0 deletions BUILDING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Building from Source

Pre-built binaries are available for download for a variety of supported platforms through the [HashiCorp Releases website](https://releases.hashicorp.com/terraform/).

However, if you'd like to build Terraform yourself, you can do so using the Go build toolchain and the options specified in this document.

## Prerequisites

1. Ensure you've installed the Go language version specified in [`.go-version`](https://github.com/hashicorp/terraform/blob/main/.go-version).
2. Clone this repository to a location of your choice.

## Terraform Build Options

Terraform accepts certain options passed using `ldflags` at build time which control the behavior of the resulting binary.

### Dev Version Reporting

Terraform will include a `-dev` flag when reporting its own version (ex: 1.5.0-dev) unless `version.dev` is set to `no`:

```
go build -ldflags "-w -s -X 'github.com/hashicorp/terraform/version.dev=no'" -o bin/ .
```

### Experimental Features

Experimental features of Terraform will be disabled unless `main.experimentsAllowed` is set to `yes`:
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe worth calling out here that we only do this for alpha release builds, and recommend third-party distributors follow that same convention to reduce confusion.


```
go build -ldflags "-w -s -X 'main.experimentsAllowed=yes'" -o bin/ .
```

In the official build process for Terraform, experiments are only allowed in alpha release builds. We recommend that third-party distributors follow that convention in order to reduce user confusion.

## Go Options

For the most part, the Terraform release process relies on the Go toolchain defaults for the target operating system and processor architecture.

### `CGO_ENABLED`

One exception is the `CGO_ENABLED` option, which is set explicitly when building Terraform binaries. For most platforms, we build with `CGO_ENABLED=0` in order to produce a statically linked binary. For MacOS/Darwin operating systems, we build with `CGO_ENABLED=1` to avoid a platform-specific issue with DNS resolution.


5 changes: 3 additions & 2 deletions scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ export CGO_ENABLED=0
# Set module download mode to readonly to not implicitly update go.mod
export GOFLAGS="-mod=readonly"

# In release mode we don't want debug information in the binary
# In release mode we don't want debug information in the binary and we don't
# want the -dev version marker
if [[ -n "${TF_RELEASE}" ]]; then
LD_FLAGS="-s -w"
LD_FLAGS="-s -w -X 'github.com/hashicorp/terraform/version.dev=no'"
fi

# Ensure all remote modules are downloaded and cached before build so that
Expand Down
2 changes: 1 addition & 1 deletion version/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.6.0-dev
1.6.0-alpha1
39 changes: 29 additions & 10 deletions version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,45 @@
package version

import (
_ "embed"
"fmt"
"strings"

version "github.com/hashicorp/go-version"
)

// The main version number that is being run at the moment.
var Version = "1.6.0"
// rawVersion is the current version as a string, as read from the VERSION
// file. This must be a valid semantic version.
//
//go:embed VERSION
var rawVersion string

// dev determines whether the -dev prerelease marker will
// be included in version info. It is expected to be set to "no" using
// linker flags when building binaries for release.
var dev string = "yes"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
var Prerelease = "dev"
// The main version number that is being run at the moment, populated from the raw version.
var Version string

// SemVer is an instance of version.Version. This has the secondary
// benefit of verifying during tests and init time that our version is a
// proper semantic version, which should always be the case.
// A pre-release marker for the version, populated using a combination of the raw version
// and the dev flag.
var Prerelease string

// SemVer is an instance of version.Version representing the main version
// without any prerelease information.
var SemVer *version.Version

func init() {
SemVer = version.Must(version.NewVersion(Version))
semVerFull := version.Must(version.NewVersion(strings.TrimSpace(rawVersion)))
SemVer = semVerFull.Core()
Version = SemVer.String()

if dev == "no" {
Copy link
Contributor

Choose a reason for hiding this comment

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

If there is already a prelease set in VERSION (e.g -alpha) would the desired behavior for local builds be that this is dropped in favour of -dev or the other way around?

Copy link
Member Author

Choose a reason for hiding this comment

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

Dropping any existing prerelease in favor of -dev! That's been our convention previously, so seemed just as well to stick with it for now.

Prerelease = semVerFull.Prerelease()
} else {
Prerelease = "dev"
}
}

// Header is the header name used to send the current terraform version
Expand Down
30 changes: 30 additions & 0 deletions version/version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package version

import (
"regexp"
"strings"
"testing"
)

// Smoke test to validate that the version file can be read correctly and all exported
// variables include the expected information.
func TestVersion(t *testing.T) {
if match, _ := regexp.MatchString("[^\\d+\\.]", Version); match != false {
t.Fatalf("Version should contain only the main version")
}

if match, _ := regexp.MatchString("[^a-z\\d]", Prerelease); match != false {
t.Fatalf("Prerelease should contain only letters and numbers")
}

if SemVer.Prerelease() != "" {
t.Fatalf("SemVer should not include prerelease information")
}

if !strings.Contains(String(), Prerelease) {
t.Fatalf("Full version string should include prerelease information")
}
}
Loading