From 49e308e57b3972a47743b7d529d4fea670c0cd50 Mon Sep 17 00:00:00 2001 From: CJ Horton Date: Mon, 3 Apr 2023 20:38:30 -0700 Subject: [PATCH 1/4] unify version information Instead of having two different places where we keep the current version which must be manually kept in sync, let's use the same one that the release process uses (version/VERSION). Local builds will remain tagged with -dev by default, and we'll disable this behavior with a linker flag at release time. --- version/version.go | 39 +++++++++++++++++++++++++++++---------- version/version_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 version/version_test.go diff --git a/version/version.go b/version/version.go index 4b98ca41fe98..6ebdd6c56a8d 100644 --- a/version/version.go +++ b/version/version.go @@ -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" { + Prerelease = semVerFull.Prerelease() + } else { + Prerelease = "dev" + } } // Header is the header name used to send the current terraform version diff --git a/version/version_test.go b/version/version_test.go new file mode 100644 index 000000000000..f6db4e67dd17 --- /dev/null +++ b/version/version_test.go @@ -0,0 +1,27 @@ +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") + } +} From 11a68eaa40133480f45096581ecd857e75106306 Mon Sep 17 00:00:00 2001 From: CJ Horton Date: Mon, 10 Apr 2023 15:56:53 -0700 Subject: [PATCH 2/4] set useDevelopmentVersion correctly for release builds --- .github/scripts/get_product_version.sh | 3 +-- scripts/build.sh | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/scripts/get_product_version.sh b/.github/scripts/get_product_version.sh index 3de45ad2d36c..d9cff8a1ca3e 100755 --- a/.github/scripts/get_product_version.sh +++ b/.github/scripts/get_product_version.sh @@ -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 diff --git a/scripts/build.sh b/scripts/build.sh index 1b59bf2cee43..4f12e7ad9f7a 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -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 From 16ae079c223538db89599e047d7e8a15aa4929ec Mon Sep 17 00:00:00 2001 From: CJ Horton Date: Mon, 10 Apr 2023 15:57:24 -0700 Subject: [PATCH 3/4] add documentation on Terraform's available build options --- BUILDING.md | 36 ++++++++++++++++++++++++++++++++++++ version/VERSION | 2 +- version/version_test.go | 3 +++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 BUILDING.md diff --git a/BUILDING.md b/BUILDING.md new file mode 100644 index 000000000000..3c13268a1c27 --- /dev/null +++ b/BUILDING.md @@ -0,0 +1,36 @@ +# 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`: + +``` +go build -ldflags "-w -s -X 'main.experimentsAllowed=yes'" -o bin/ . +``` + +## Go Options + +The Terraform release process uses the Go toolchain defaults for the current operating system and processor architecture. + + diff --git a/version/VERSION b/version/VERSION index bcfbf475d5e0..45d114a2138f 100644 --- a/version/VERSION +++ b/version/VERSION @@ -1 +1 @@ -1.6.0-dev +1.6.0-alpha1 diff --git a/version/version_test.go b/version/version_test.go index f6db4e67dd17..cd889b0ac945 100644 --- a/version/version_test.go +++ b/version/version_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package version import ( From 1e2a6be6895560d58e7af6aa433942a65f4b9b87 Mon Sep 17 00:00:00 2001 From: CJ Horton Date: Mon, 17 Jul 2023 11:56:13 -0700 Subject: [PATCH 4/4] elaborate further on experiments and cgo --- BUILDING.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/BUILDING.md b/BUILDING.md index 3c13268a1c27..66584de4e2da 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -29,8 +29,14 @@ Experimental features of Terraform will be disabled unless `main.experimentsAllo 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 -The Terraform release process uses the Go toolchain defaults for the current operating system and processor architecture. +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.