From 96dda8810dad2d7b9d755e10fac65507d060217b Mon Sep 17 00:00:00 2001 From: Marko Date: Tue, 27 Oct 2020 13:54:53 +0100 Subject: [PATCH] ci: add goreleaser (#5527) Co-authored-by: Erik Grinaker Co-authored-by: Alessio Treglia --- .circleci/config.yml | 87 ------------------- .github/workflows/release.yml | 30 +++++++ .goreleaser.yml | 27 ++++++ CONTRIBUTING.md | 62 +++++++++---- Makefile | 3 +- cmd/tendermint/commands/version.go | 2 +- proxy/version.go | 2 +- release_notes.md | 1 + scripts/dist.sh | 4 +- scripts/publish.sh | 20 ----- scripts/release.sh | 53 ----------- scripts/release_management/README.md | 64 -------------- scripts/release_management/bump-semver.py | 62 ------------- scripts/release_management/github-draft.py | 61 ------------- scripts/release_management/github-openpr.py | 52 ----------- .../github-public-newbranch.bash | 28 ------ scripts/release_management/github-publish.py | 53 ----------- scripts/release_management/github-upload.py | 68 --------------- scripts/release_management/sha-files.py | 35 -------- scripts/release_management/zip-file.py | 44 ---------- tools/tm-signer-harness/Makefile | 3 +- tools/tm-signer-harness/main.go | 2 +- version/version.go | 21 +---- 23 files changed, 114 insertions(+), 670 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 .goreleaser.yml create mode 100644 release_notes.md delete mode 100755 scripts/publish.sh delete mode 100755 scripts/release.sh delete mode 100644 scripts/release_management/README.md delete mode 100755 scripts/release_management/bump-semver.py delete mode 100755 scripts/release_management/github-draft.py delete mode 100755 scripts/release_management/github-openpr.py delete mode 100644 scripts/release_management/github-public-newbranch.bash delete mode 100755 scripts/release_management/github-publish.py delete mode 100755 scripts/release_management/github-upload.py delete mode 100755 scripts/release_management/sha-files.py delete mode 100755 scripts/release_management/zip-file.py diff --git a/.circleci/config.yml b/.circleci/config.yml index cfcd25756..a387846a8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -118,70 +118,6 @@ jobs: paths: - "/go/pkg/mod" - build_artifacts: - executor: golang - parallelism: 5 - steps: - - restore_cache: - name: "Restore source code cache" - keys: - - go-src-v1-{{ .Revision }} - - checkout - - restore_cache: - name: "Restore release dependencies cache" - keys: - - v2-release-deps-{{ checksum "go.sum" }} - - attach_workspace: - at: /tmp/workspace - - run: - name: Build artifact - command: | - # Setting CIRCLE_TAG because we do not tag the release ourselves. - source /tmp/workspace/release-version.source - if test ${CIRCLE_NODE_INDEX:-0} == 0 ;then export GOOS=linux GOARCH=amd64 && export OUTPUT=build/tendermint_${GOOS}_${GOARCH} && make build && python -u scripts/release_management/zip-file.py ;fi - if test ${CIRCLE_NODE_INDEX:-0} == 1 ;then export GOOS=darwin GOARCH=amd64 && export OUTPUT=build/tendermint_${GOOS}_${GOARCH} && make build && python -u scripts/release_management/zip-file.py ;fi - if test ${CIRCLE_NODE_INDEX:-0} == 2 ;then export GOOS=windows GOARCH=amd64 && export OUTPUT=build/tendermint_${GOOS}_${GOARCH} && make build && python -u scripts/release_management/zip-file.py ;fi - if test ${CIRCLE_NODE_INDEX:-0} == 3 ;then export GOOS=linux GOARCH=arm && export OUTPUT=build/tendermint_${GOOS}_${GOARCH} && make build && python -u scripts/release_management/zip-file.py ;fi - if test ${CIRCLE_NODE_INDEX:-0} == 4 ;then export GOOS=linux GOARCH=arm64 && export OUTPUT=build/tendermint_${GOOS}_${GOARCH} && make build && python -u scripts/release_management/zip-file.py ;fi - - persist_to_workspace: - root: build - paths: - - "*.zip" - - "tendermint_linux_amd64" - - release_artifacts: - executor: golang - steps: - - restore_cache: - name: "Restore source code cache" - keys: - - go-src-v1-{{ .Revision }} - - checkout - - attach_workspace: - at: /tmp/workspace - - run: - name: "Deploy to GitHub" - command: | - # Setting CIRCLE_TAG because we do not tag the release ourselves. - source /tmp/workspace/release-version.source - echo "---" - ls -la /tmp/workspace/*.zip - echo "---" - python -u scripts/release_management/sha-files.py - echo "---" - cat /tmp/workspace/SHA256SUMS - echo "---" - export RELEASE_ID="`python -u scripts/release_management/github-draft.py`" - echo "Release ID: ${RELEASE_ID}" - #Todo: Parallelize uploads - export GOOS=linux GOARCH=amd64 && python -u scripts/release_management/github-upload.py --id "${RELEASE_ID}" - export GOOS=darwin GOARCH=amd64 && python -u scripts/release_management/github-upload.py --id "${RELEASE_ID}" - export GOOS=windows GOARCH=amd64 && python -u scripts/release_management/github-upload.py --id "${RELEASE_ID}" - export GOOS=linux GOARCH=arm && python -u scripts/release_management/github-upload.py --id "${RELEASE_ID}" - export GOOS=linux GOARCH=arm64 && python -u scripts/release_management/github-upload.py --id "${RELEASE_ID}" - python -u scripts/release_management/github-upload.py --file "/tmp/workspace/SHA256SUMS" --id "${RELEASE_ID}" - python -u scripts/release_management/github-publish.py --id "${RELEASE_ID}" - # # Test RPC implementation against the swagger documented specs # contract_tests: # working_directory: /home/circleci/.go_workspace/src/github.com/tendermint/tendermint @@ -230,26 +166,3 @@ workflows: # - contract_tests: # requires: # - setup_dependencies - - release: - jobs: - - prepare_build: - filters: - branches: - only: - - /v[0-9]+\.[0-9]+/ - - build_artifacts: - requires: - - prepare_build - filters: - branches: - only: - - /v[0-9]+\.[0-9]+/ - - release_artifacts: - requires: - - prepare_build - - build_artifacts - filters: - branches: - only: - - /v[0-9]+\.[0-9]+/ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..f4aecbab0 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,30 @@ +name: "Release" + +on: + push: + tags: + - "v[0-9]+.[0-9]+.[0-9]+" # Push events to matching v*, i.e. v1.0, v20.15.10 + +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.15 + + - run: echo https://github.com/tendermint/tendermint/blob/${GITHUB_REF#refs/tags/}/CHANGELOG.md#${GITHUB_REF#refs/tags/} > ../release_notes.md + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v2 + with: + version: latest + args: release --rm-dist --release-notes=../release_notes.md + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 000000000..9fb5933af --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,27 @@ +project_name: Tendermint + +env: + # Require use of Go modules. + - GO111MODULE=on + +builds: + - id: "Tendermint" + main: ./cmd/tendermint/main.go + ldflags: + - -s -w -X github.com/tendermint/tendermint/version.TMCoreSemVer={{ .Version }} + env: + - CGO_ENABLED=0 + goos: + - darwin + - linux + goarch: + - amd64 + - arm + - arm64 + +checksum: + name_template: SHA256SUMS-{{.Version}}.txt + algorithm: sha256 + +release: + name_template: "{{.Version}} (WARNING: BETA SOFTWARE)" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 809767651..cabaf8b3c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -246,22 +246,26 @@ Each PR should have one commit once it lands on `master`; this can be accomplish #### Major Release -1. start on `master` -2. run integration tests (see `test_integrations` in Makefile) -3. prepare release in a pull request against `master` (to be squash merged): - - copy `CHANGELOG_PENDING.md` to top of `CHANGELOG.md` - - run `python ./scripts/linkify_changelog.py CHANGELOG.md` to add links for +1. Start on `master` +2. Run integration tests (see `test_integrations` in Makefile) +3. Prepare release in a pull request against `master` (to be squash merged): + - Copy `CHANGELOG_PENDING.md` to top of `CHANGELOG.md`; if this release + had release candidates, squash all the RC updates into one + - Run `python ./scripts/linkify_changelog.py CHANGELOG.md` to add links for all issues - run `bash ./scripts/authors.sh` to get a list of authors since the latest release, and add the github aliases of external contributors to the top of the changelog. To lookup an alias from an email, try `bash ./scripts/authors.sh ` - - reset the `CHANGELOG_PENDING.md` - - bump Tendermint version in `version.go` - - bump P2P and block protocol versions in `version.go`, if necessary - - bump ABCI protocol version in `version.go`, if necessary - - make sure all significant breaking changes are covered in `UPGRADING.md` -4. push your changes with prepared release details to `vX.X` (this will trigger the release `vX.X.0`) -5. merge back to master (don't squash merge!) + - Reset the `CHANGELOG_PENDING.md` + - Bump P2P and block protocol versions in `version.go`, if necessary + - Bump ABCI protocol version in `version.go`, if necessary + - Make sure all significant breaking changes are covered in `UPGRADING.md` + - Add any release notes you would like to be added to the body of the release to `release_notes.md`. +4. Push a tag with prepared release details (this will trigger the release `vX.X.0`) + - `git tag -a vX.X.x -m 'Release vX.X.x'` + - `git push origin vX.X.x` +5. Update the changelog.md file on master with the releases changelog. +6. Delete any RC branches and tags for this release (if applicable) #### Minor Release @@ -274,15 +278,17 @@ Minor releases are done differently from major releases: They are built off of l - run `python ./scripts/linkify_changelog.py CHANGELOG.md` to add links for all issues - run `bash ./scripts/authors.sh` to get a list of authors since the latest release, and add the GitHub aliases of external contributors to the top of the CHANGELOG. To lookup an alias from an email, try `bash ./scripts/authors.sh ` - reset the `CHANGELOG_PENDING.md` - - bump Tendermint version in `version.go` - bump P2P and block protocol versions in `version.go`, if necessary - bump ABCI protocol version in `version.go`, if necessary - make sure all significant breaking changes are covered in `UPGRADING.md` + - Add any release notes you would like to be added to the body of the release to `release_notes.md`. 4. Create a release branch `release/vX.X.x` off the release candidate branch: - `git checkout -b release/vX.X.x` - `git push -u origin release/vX.X.x` - Note that all branches prefixed with `release` are protected once pushed. You will need admin help to make any changes to the branch. -5. Open a pull request of the new minor release branch onto the latest major release branch `vX.X` and then rebase to merge. This will start the release process. +5. Once the release branch has been approved, make sure to pull it locally, then push a tag. + - `git tag -a vX.X.x -m 'Release vX.X.x'` + - `git push origin vX.X.x` 6. Create a pull request back to master with the CHANGELOG & version changes from the latest release. - Remove all `R:minor` labels from the pull requests that were included in the release. - Do not merge the release branch into master. @@ -293,10 +299,30 @@ Minor releases are done differently from major releases: They are built off of l 1. start from the existing release branch you want to backport changes to (e.g. v0.30) Branch to a release/vX.X.X branch locally (e.g. release/v0.30.7) -2. cherry pick the commit(s) that contain the changes you want to backport (usually these commits are from squash-merged PRs which were already reviewed) -3. steps 2 and 3 from [Major Release](#major-release) -4. push changes to release/vX.X.X branch -5. open a PR against the existing vX.X branch +2. Cherry pick the commit(s) that contain the changes you want to backport (usually these commits are from squash-merged PRs which were already reviewed) +3. Follow steps 2 and 3 from [Major Release](#major-release) +4. Push changes to release/vX.X.X branch +5. Open a PR against the existing vX.X branch + +#### Release Candidates + +Before creating an official release, especially a major release, we may want to create a +release candidate (RC) for our friends and partners to test out. We use git tags to +create RCs, and we build them off of RC branches. RC branches typically have names formatted +like `RCX/vX.X.X` (or, concretely, `RC0/v0.34.0`), while the tags themselves follow +the "standard" release naming conventions, with `-rcX` at the end (`vX.X.X-rcX`). + +(Note that branches and tags _cannot_ have the same names, so it's important that these branches +have distinct names from the tags/release names.) + +1. Start from the RC branch (e.g. `RC0/v0.34.0`). +2. Create the new tag, specifying a name and a tag "message": + `git tag -a v0.34.0-rc0 -m "Release Candidate v0.34.0-rc0` +3. Push the tag back up to origin: + `git push origin v0.34.0-rc4` + Now the tag should be available on the repo's releases page. +4. Create a new release candidate branch for any possible updates to the RC: + `git checkout -b RC1/v0.34.0; git push origin RC1/v0.34.0` ## Testing diff --git a/Makefile b/Makefile index 5ecb52700..e7111551b 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,8 @@ PACKAGES=$(shell go list ./...) OUTPUT?=build/tendermint BUILD_TAGS?=tendermint -LD_FLAGS = -X github.com/tendermint/tendermint/version.GitCommit=`git rev-parse --short=8 HEAD` +VERSION := $(shell git describe --always) +LD_FLAGS = -X github.com/tendermint/tendermint/version.TMCoreSemVer=$(VERSION) BUILD_FLAGS = -mod=readonly -ldflags "$(LD_FLAGS)" HTTPS_GIT := https://github.com/tendermint/tendermint.git DOCKER_BUF := docker run -v $(shell pwd):/workspace --workdir /workspace bufbuild/buf diff --git a/cmd/tendermint/commands/version.go b/cmd/tendermint/commands/version.go index f9f545e59..d1a7fba58 100644 --- a/cmd/tendermint/commands/version.go +++ b/cmd/tendermint/commands/version.go @@ -13,6 +13,6 @@ var VersionCmd = &cobra.Command{ Use: "version", Short: "Show version info", Run: func(cmd *cobra.Command, args []string) { - fmt.Println(version.Version) + fmt.Println(version.TMCoreSemVer) }, } diff --git a/proxy/version.go b/proxy/version.go index 2109a45eb..be890e12e 100644 --- a/proxy/version.go +++ b/proxy/version.go @@ -9,7 +9,7 @@ import ( // the abci.RequestInfo message during handshake with the app. // It contains only compile-time version information. var RequestInfo = abci.RequestInfo{ - Version: version.Version, + Version: version.TMCoreSemVer, BlockVersion: version.BlockProtocol, P2PVersion: version.P2PProtocol, } diff --git a/release_notes.md b/release_notes.md new file mode 100644 index 000000000..a537871c5 --- /dev/null +++ b/release_notes.md @@ -0,0 +1 @@ + diff --git a/scripts/dist.sh b/scripts/dist.sh index 81fdf9813..234380403 100755 --- a/scripts/dist.sh +++ b/scripts/dist.sh @@ -20,7 +20,7 @@ rm -rf build/pkg mkdir -p build/pkg # Get the git commit -GIT_COMMIT="$(git rev-parse --short=8 HEAD)" +VERSION := "$(shell git describe --always)" GIT_IMPORT="github.com/tendermint/tendermint/version" # Determine the arch/os combos we're building for @@ -41,7 +41,7 @@ for arch in "${arch_list[@]}"; do for os in "${os_list[@]}"; do if [[ "$XC_EXCLUDE" != *" $os/$arch "* ]]; then echo "--> $os/$arch" - GOOS=${os} GOARCH=${arch} go build -ldflags "-s -w -X ${GIT_IMPORT}.GitCommit=${GIT_COMMIT}" -tags="${BUILD_TAGS}" -o "build/pkg/${os}_${arch}/tendermint" ./cmd/tendermint + GOOS=${os} GOARCH=${arch} go build -ldflags "-s -w -X ${GIT_IMPORT}.TMCoreSemVer=${VERSION}" -tags="${BUILD_TAGS}" -o "build/pkg/${os}_${arch}/tendermint" ./cmd/tendermint fi done done diff --git a/scripts/publish.sh b/scripts/publish.sh deleted file mode 100755 index 7da299aaf..000000000 --- a/scripts/publish.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -set -e - -VERSION=$1 -DIST_DIR=./build/dist - -# Get the version from the environment, or try to figure it out. -if [ -z $VERSION ]; then - VERSION=$(awk -F\" 'TMCoreSemVer =/ { print $2; exit }' < version/version.go) -fi -if [ -z "$VERSION" ]; then - echo "Please specify a version." - exit 1 -fi -echo "==> Copying ${DIST_DIR} to S3..." - -# copy to s3 -aws s3 cp --recursive ${DIST_DIR} s3://tendermint/binaries/tendermint/v${VERSION} --acl public-read - -exit 0 diff --git a/scripts/release.sh b/scripts/release.sh deleted file mode 100755 index 8c40d36b6..000000000 --- a/scripts/release.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash -set -e - -# Get the version from the environment, or try to figure it out. -if [ -z $VERSION ]; then - VERSION=$(awk -F\" 'TMCoreSemVer =/ { print $2; exit }' < version/version.go) -fi -if [ -z "$VERSION" ]; then - echo "Please specify a version." - exit 1 -fi -echo "==> Releasing version $VERSION..." - -# Get the parent directory of where this script is. -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done -DIR="$( cd -P "$( dirname "$SOURCE" )/.." && pwd )" - -# Change into that dir because we expect that. -cd "$DIR" - -# Building binaries -sh -c "'$DIR/scripts/dist.sh'" - -# Pushing binaries to S3 -sh -c "'$DIR/scripts/publish.sh'" - -# echo "==> Crafting a Github release" -# today=$(date +"%B-%d-%Y") -# ghr -b "https://github.com/tendermint/tendermint/blob/master/CHANGELOG.md#${VERSION//.}-${today,}" "v$VERSION" "$DIR/build/dist" - -# Build and push Docker image - -## Get SHA256SUM of the linux archive -SHA256SUM=$(shasum -a256 "${DIR}/build/dist/tendermint_${VERSION}_linux_amd64.zip" | awk '{print $1;}') - -## Replace TM_VERSION and TM_SHA256SUM with the new values -sed -i -e "s/TM_VERSION .*/TM_VERSION $VERSION/g" "$DIR/DOCKER/Dockerfile" -sed -i -e "s/TM_SHA256SUM .*/TM_SHA256SUM $SHA256SUM/g" "$DIR/DOCKER/Dockerfile" -git commit -m "update Dockerfile" -a "$DIR/DOCKER/Dockerfile" -echo "==> TODO: update DOCKER/README.md (latest Dockerfile's hash is $(git rev-parse HEAD)) and copy it's content to https://store.docker.com/community/images/tendermint/tendermint" - -pushd "$DIR/DOCKER" - -## Build Docker image -TAG=$VERSION sh -c "'./build.sh'" - -## Push Docker image -TAG=$VERSION sh -c "'./push.sh'" - -popd - -exit 0 diff --git a/scripts/release_management/README.md b/scripts/release_management/README.md deleted file mode 100644 index c0d49e2e8..000000000 --- a/scripts/release_management/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# Release management scripts - -## Overview -The scripts in this folder are used for release management in CircleCI. Although the scripts are fully configurable using input parameters, -the default settings were modified to accommodate CircleCI execution. - -# Build scripts -These scripts help during the build process. They prepare the release files. - -## bump-semver.py -Bumps the semantic version of the input `--version`. Versions are expected in vMAJOR.MINOR.PATCH format or vMAJOR.MINOR format. - -In vMAJOR.MINOR format, the result will be patch version 0 of that version, for example `v1.2 -> v1.2.0`. - -In vMAJOR.MINOR.PATCH format, the result will be a bumped PATCH version, for example `v1.2.3 -> v1.2.4`. - -If the PATCH number contains letters, it is considered a development version, in which case, the result is the non-development version of that number. -The patch number will not be bumped, only the "-dev" or similar additional text will be removed. For example: `v1.2.6-rc1 -> v1.2.6`. - -## zip-file.py -Specialized ZIP command for release management. Special features: -1. Uses Python ZIP libaries, so the `zip` command does not need to be installed. -1. Can only zip one file. -1. Optionally gets file version, Go OS and architecture. -1. By default all inputs and output is formatted exactly how CircleCI needs it. - -By default, the command will try to ZIP the file at `build/tendermint_${GOOS}_${GOARCH}`. -This can be changed with the `--file` input parameter. - -By default, the command will output the ZIP file to `build/tendermint_${CIRCLE_TAG}_${GOOS}_${GOARCH}.zip`. -This can be changed with the `--destination` (folder), `--version`, `--goos` and `--goarch` input parameters respectively. - -## sha-files.py -Specialized `shasum` command for release management. Special features: -1. Reads all ZIP files in the given folder. -1. By default all inputs and output is formatted exactly how CircleCI needs it. - -By default, the command will look up all ZIP files in the `build/` folder. - -By default, the command will output results into the `build/SHA256SUMS` file. - -# GitHub management -Uploading build results to GitHub requires at least these steps: -1. Create a new release on GitHub with content -2. Upload all binaries to the release -3. Publish the release -The below scripts help with these steps. - -## github-draft.py -Creates a GitHub release and fills the content with the CHANGELOG.md link. The version number can be changed by the `--version` parameter. - -By default, the command will use the tendermint/tendermint organization/repo, which can be changed using the `--org` and `--repo` parameters. - -By default, the command will get the version number from the `${CIRCLE_TAG}` variable. - -Returns the GitHub release ID. - -## github-upload.py -Upload a file to a GitHub release. The release is defined by the mandatory `--id` (release ID) input parameter. - -By default, the command will upload the file `/tmp/workspace/tendermint_${CIRCLE_TAG}_${GOOS}_${GOARCH}.zip`. This can be changed by the `--file` input parameter. - -## github-publish.py -Publish a GitHub release. The release is defined by the mandatory `--id` (release ID) input parameter. diff --git a/scripts/release_management/bump-semver.py b/scripts/release_management/bump-semver.py deleted file mode 100755 index ce56d8d7c..000000000 --- a/scripts/release_management/bump-semver.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python - -# Bump the release number of a semantic version number and print it. --version is required. -# Version is -# - vA.B.C, in which case vA.B.C+1 will be returned -# - vA.B.C-devorwhatnot in which case vA.B.C will be returned -# - vA.B in which case vA.B.0 will be returned - -import re -import argparse -import sys - - -def semver(ver): - if re.match('v[0-9]+\.[0-9]+',ver) is None: - ver="v0.0" - #raise argparse.ArgumentTypeError('--version must be a semantic version number with major, minor and patch numbers') - return ver - - -def get_tendermint_version(): - """Extracts the current Tendermint version from version/version.go""" - pattern = re.compile(r"TMCoreSemVer = \"(?P([0-9.]+)+)\"") - with open("version/version.go", "rt") as version_file: - for line in version_file: - m = pattern.search(line) - if m: - return m.group('version') - - return None - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--version", help="Version number to bump, e.g.: v1.0.0", required=True, type=semver) - args = parser.parse_args() - - found = re.match('(v[0-9]+\.[0-9]+)(\.(.+))?', args.version) - majorminorprefix = found.group(1) - patch = found.group(3) - if patch is None: - patch = "0-new" - - if re.match('[0-9]+$',patch) is None: - patchfound = re.match('([0-9]+)',patch) - patch = int(patchfound.group(1)) - else: - patch = int(patch) + 1 - - expected_version = "{0}.{1}".format(majorminorprefix, patch) - # if we're doing a release - if expected_version != "v0.0.0": - cur_version = get_tendermint_version() - if not cur_version: - print("Failed to obtain Tendermint version from version/version.go") - sys.exit(1) - expected_version_noprefix = expected_version.lstrip("v") - if expected_version_noprefix != "0.0.0" and expected_version_noprefix != cur_version: - print("Expected version/version.go#TMCoreSemVer to be {0}, but was {1}".format(expected_version_noprefix, cur_version)) - sys.exit(1) - - print(expected_version) diff --git a/scripts/release_management/github-draft.py b/scripts/release_management/github-draft.py deleted file mode 100755 index 8a189d53e..000000000 --- a/scripts/release_management/github-draft.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python - -# Create a draft release on GitHub. By default in the tendermint/tendermint repo. -# Optimized for CircleCI - -import argparse -import httplib -import json -import os -from base64 import b64encode - -def request(org, repo, data): - user_and_pass = b64encode(b"{0}:{1}".format(os.environ['GITHUB_USERNAME'], os.environ['GITHUB_TOKEN'])).decode("ascii") - headers = { - 'User-Agent': 'tenderbot', - 'Accept': 'application/vnd.github.v3+json', - 'Authorization': 'Basic %s' % user_and_pass - } - - conn = httplib.HTTPSConnection('api.github.com', timeout=5) - conn.request('POST', '/repos/{0}/{1}/releases'.format(org,repo), data, headers) - response = conn.getresponse() - if response.status < 200 or response.status > 299: - print("{0}: {1}".format(response.status, response.reason)) - conn.close() - raise IOError(response.reason) - responsedata = response.read() - conn.close() - return json.loads(responsedata) - - -def create_draft(org,repo,branch,version): - draft = { - 'tag_name': version, - 'target_commitish': '{0}'.format(branch), - 'name': '{0} (WARNING: ALPHA SOFTWARE)'.format(version), - 'body': 'https://github.com/{0}/{1}/blob/{2}/CHANGELOG.md#{3}'.format(org,repo,branch,version.replace('.','')), - 'draft': True, - 'prerelease': False - } - data=json.dumps(draft) - return request(org, repo, data) - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--org", default="tendermint", help="GitHub organization") - parser.add_argument("--repo", default="tendermint", help="GitHub repository") - parser.add_argument("--branch", default=os.environ.get('CIRCLE_BRANCH'), help="Branch to build from, e.g.: v1.0") - parser.add_argument("--version", default=os.environ.get('CIRCLE_TAG'), help="Version number for binary, e.g.: v1.0.0") - args = parser.parse_args() - - if not os.environ.has_key('GITHUB_USERNAME'): - raise parser.error('environment variable GITHUB_USERNAME is required') - - if not os.environ.has_key('GITHUB_TOKEN'): - raise parser.error('environment variable GITHUB_TOKEN is required') - - release = create_draft(args.org,args.repo,args.branch,args.version) - - print(release["id"]) - diff --git a/scripts/release_management/github-openpr.py b/scripts/release_management/github-openpr.py deleted file mode 100755 index af0434f02..000000000 --- a/scripts/release_management/github-openpr.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python - -# Open a PR against the develop branch. --branch required. -# Optimized for CircleCI - -import json -import os -import argparse -import httplib -from base64 import b64encode - - -def request(org, repo, data): - user_and_pass = b64encode(b"{0}:{1}".format(os.environ['GITHUB_USERNAME'], os.environ['GITHUB_TOKEN'])).decode("ascii") - headers = { - 'User-Agent': 'tenderbot', - 'Accept': 'application/vnd.github.v3+json', - 'Authorization': 'Basic %s' % user_and_pass - } - - conn = httplib.HTTPSConnection('api.github.com', timeout=5) - conn.request('POST', '/repos/{0}/{1}/pulls'.format(org,repo), data, headers) - response = conn.getresponse() - if response.status < 200 or response.status > 299: - print(response) - conn.close() - raise IOError(response.reason) - responsedata = response.read() - conn.close() - return json.loads(responsedata) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--org", default="tendermint", help="GitHub organization. Defaults to tendermint.") - parser.add_argument("--repo", default="tendermint", help="GitHub repository. Defaults to tendermint.") - parser.add_argument("--head", help="The name of the branch where your changes are implemented.", required=True) - parser.add_argument("--base", help="The name of the branch you want the changes pulled into.", required=True) - parser.add_argument("--title", default="Security release {0}".format(os.environ.get('CIRCLE_TAG')), help="The title of the pull request.") - args = parser.parse_args() - - if not os.environ.has_key('GITHUB_USERNAME'): - raise parser.error('GITHUB_USERNAME not set.') - - if not os.environ.has_key('GITHUB_TOKEN'): - raise parser.error('GITHUB_TOKEN not set.') - - if os.environ.get('CIRCLE_TAG') is None: - raise parser.error('CIRCLE_TAG not set.') - - result = request(args.org, args.repo, data=json.dumps({'title':"{0}".format(args.title),'head':"{0}".format(args.head),'base':"{0}".format(args.base),'body':""})) - print(result['html_url']) diff --git a/scripts/release_management/github-public-newbranch.bash b/scripts/release_management/github-public-newbranch.bash deleted file mode 100644 index ca2fa1314..000000000 --- a/scripts/release_management/github-public-newbranch.bash +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -# github-public-newbranch.bash - create public branch from the security repository - -set -euo pipefail - -# Create new branch -BRANCH="${CIRCLE_TAG:-v0.0.0}-security-`date -u +%Y%m%d%H%M%S`" -# Check if the patch release exist already as a branch -if [ -n "`git branch | grep '${BRANCH}'`" ]; then - echo "WARNING: Branch ${BRANCH} already exists." -else - echo "Creating branch ${BRANCH}." - git branch "${BRANCH}" -fi - -# ... and check it out -git checkout "${BRANCH}" - -# Add entry to public repository -git remote add tendermint-origin git@github.com:tendermint/tendermint.git - -# Push branch and tag to public repository -git push tendermint-origin -git push tendermint-origin --tags - -# Create a PR from the public branch to the assumed release branch in public (release branch has to exist) -python -u scripts/release_management/github-openpr.py --head "${BRANCH}" --base "${BRANCH:%.*}" diff --git a/scripts/release_management/github-publish.py b/scripts/release_management/github-publish.py deleted file mode 100755 index 31071aecd..000000000 --- a/scripts/release_management/github-publish.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python - -# Publish an existing GitHub draft release. --id required. -# Optimized for CircleCI - -import json -import os -import argparse -import httplib -from base64 import b64encode - - -def request(org, repo, id, data): - user_and_pass = b64encode(b"{0}:{1}".format(os.environ['GITHUB_USERNAME'], os.environ['GITHUB_TOKEN'])).decode("ascii") - headers = { - 'User-Agent': 'tenderbot', - 'Accept': 'application/vnd.github.v3+json', - 'Authorization': 'Basic %s' % user_and_pass - } - - conn = httplib.HTTPSConnection('api.github.com', timeout=5) - conn.request('POST', '/repos/{0}/{1}/releases/{2}'.format(org,repo,id), data, headers) - response = conn.getresponse() - if response.status < 200 or response.status > 299: - print(response) - conn.close() - raise IOError(response.reason) - responsedata = response.read() - conn.close() - return json.loads(responsedata) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--org", default="tendermint", help="GitHub organization") - parser.add_argument("--repo", default="tendermint", help="GitHub repository") - parser.add_argument("--id", help="GitHub release ID", required=True, type=int) - parser.add_argument("--version", default=os.environ.get('CIRCLE_TAG'), help="Version number for the release, e.g.: v1.0.0") - args = parser.parse_args() - - if not os.environ.has_key('GITHUB_USERNAME'): - raise parser.error('GITHUB_USERNAME not set.') - - if not os.environ.has_key('GITHUB_TOKEN'): - raise parser.error('GITHUB_TOKEN not set.') - - try: - result = request(args.org, args.repo, args.id, data=json.dumps({'draft':False,'tag_name':"{0}".format(args.version)})) - except IOError as e: - print(e) - result = request(args.org, args.repo, args.id, data=json.dumps({'draft':False,'tag_name':"{0}-autorelease".format(args.version)})) - - print(result['name']) diff --git a/scripts/release_management/github-upload.py b/scripts/release_management/github-upload.py deleted file mode 100755 index 77c76a755..000000000 --- a/scripts/release_management/github-upload.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python - -# Upload a file to a GitHub draft release. --id and --file are required. -# Optimized for CircleCI - -import json -import os -import re -import argparse -import mimetypes -import httplib -from base64 import b64encode - - -def request(baseurl, path, mimetype, mimeencoding, data): - user_and_pass = b64encode(b"{0}:{1}".format(os.environ['GITHUB_USERNAME'], os.environ['GITHUB_TOKEN'])).decode("ascii") - - headers = { - 'User-Agent': 'tenderbot', - 'Accept': 'application/vnd.github.v3.raw+json', - 'Authorization': 'Basic %s' % user_and_pass, - 'Content-Type': mimetype, - 'Content-Encoding': mimeencoding - } - - conn = httplib.HTTPSConnection(baseurl, timeout=5) - conn.request('POST', path, data, headers) - response = conn.getresponse() - if response.status < 200 or response.status > 299: - print(response) - conn.close() - raise IOError(response.reason) - responsedata = response.read() - conn.close() - return json.loads(responsedata) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--id", help="GitHub release ID", required=True, type=int) - parser.add_argument("--file", default="/tmp/workspace/tendermint_{0}_{1}_{2}.zip".format(os.environ.get('CIRCLE_TAG'),os.environ.get('GOOS'),os.environ.get('GOARCH')), help="File to upload") - parser.add_argument("--return-id-only", help="Return only the release ID after upload to GitHub.", action='store_true') - args = parser.parse_args() - - if not os.environ.has_key('GITHUB_USERNAME'): - raise parser.error('GITHUB_USERNAME not set.') - - if not os.environ.has_key('GITHUB_TOKEN'): - raise parser.error('GITHUB_TOKEN not set.') - - mimetypes.init() - filename = os.path.basename(args.file) - mimetype,mimeencoding = mimetypes.guess_type(filename, strict=False) - if mimetype is None: - mimetype = 'application/zip' - if mimeencoding is None: - mimeencoding = 'utf8' - - with open(args.file,'rb') as f: - asset = f.read() - - result = request('uploads.github.com', '/repos/tendermint/tendermint/releases/{0}/assets?name={1}'.format(args.id, filename), mimetype, mimeencoding, asset) - - if args.return_id_only: - print(result['id']) - else: - print(result['browser_download_url']) - diff --git a/scripts/release_management/sha-files.py b/scripts/release_management/sha-files.py deleted file mode 100755 index 2a9ee0d59..000000000 --- a/scripts/release_management/sha-files.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python - -# Create SHA256 summaries from all ZIP files in a folder -# Optimized for CircleCI - -import re -import os -import argparse -import zipfile -import hashlib - - -BLOCKSIZE = 65536 - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--folder", default="/tmp/workspace", help="Folder to look for, for ZIP files") - parser.add_argument("--shafile", default="/tmp/workspace/SHA256SUMS", help="SHA256 summaries File") - args = parser.parse_args() - - for filename in os.listdir(args.folder): - if re.search('\.zip$',filename) is None: - continue - if not os.path.isfile(os.path.join(args.folder, filename)): - continue - with open(args.shafile,'a+') as shafile: - hasher = hashlib.sha256() - with open(os.path.join(args.folder, filename),'r') as f: - buf = f.read(BLOCKSIZE) - while len(buf) > 0: - hasher.update(buf) - buf = f.read(BLOCKSIZE) - shafile.write("{0} {1}\n".format(hasher.hexdigest(),filename)) - diff --git a/scripts/release_management/zip-file.py b/scripts/release_management/zip-file.py deleted file mode 100755 index 5d2f5b2c8..000000000 --- a/scripts/release_management/zip-file.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python - -# ZIP one file as "tendermint" into a ZIP like tendermint_VERSION_OS_ARCH.zip -# Use environment variables CIRCLE_TAG, GOOS and GOARCH for easy input parameters. -# Optimized for CircleCI - -import os -import argparse -import zipfile -import hashlib - - -BLOCKSIZE = 65536 - - -def zip_asset(file,destination,arcname,version,goos,goarch): - filename = os.path.basename(file) - output = "{0}/{1}_{2}_{3}_{4}.zip".format(destination,arcname,version,goos,goarch) - - with zipfile.ZipFile(output,'w') as f: - f.write(filename=file,arcname=arcname) - f.comment=filename - return output - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--file", default="build/tendermint_{0}_{1}".format(os.environ.get('GOOS'),os.environ.get('GOARCH')), help="File to zip") - parser.add_argument("--destination", default="build", help="Destination folder for files") - parser.add_argument("--version", default=os.environ.get('CIRCLE_TAG'), help="Version number for binary, e.g.: v1.0.0") - parser.add_argument("--goos", default=os.environ.get('GOOS'), help="GOOS parameter") - parser.add_argument("--goarch", default=os.environ.get('GOARCH'), help="GOARCH parameter") - args = parser.parse_args() - - if args.version is None: - raise parser.error("argument --version is required") - if args.goos is None: - raise parser.error("argument --goos is required") - if args.goarch is None: - raise parser.error("argument --goarch is required") - - file = zip_asset(args.file,args.destination,"tendermint",args.version,args.goos,args.goarch) - print(file) - diff --git a/tools/tm-signer-harness/Makefile b/tools/tm-signer-harness/Makefile index 47cd03650..1c404ebf8 100644 --- a/tools/tm-signer-harness/Makefile +++ b/tools/tm-signer-harness/Makefile @@ -2,7 +2,8 @@ TENDERMINT_VERSION?=latest BUILD_TAGS?='tendermint' -BUILD_FLAGS = -ldflags "-X github.com/tendermint/tendermint/version.GitCommit=`git rev-parse --short=8 HEAD`" +VERSION := $(shell git describe --always) +BUILD_FLAGS = -ldflags "-X github.com/tendermint/tendermint/version.TMCoreSemVer=$(VERSION) .DEFAULT_GOAL := build diff --git a/tools/tm-signer-harness/main.go b/tools/tm-signer-harness/main.go index 06b7000cc..d624234ae 100644 --- a/tools/tm-signer-harness/main.go +++ b/tools/tm-signer-harness/main.go @@ -181,7 +181,7 @@ func main() { } extractKey(flagTMHome, flagKeyOutputPath) case "version": - fmt.Println(version.Version) + fmt.Println(version.TMCoreSemVer) default: fmt.Printf("Unrecognized command: %s\n", flag.Arg(0)) os.Exit(1) diff --git a/version/version.go b/version/version.go index e87ceba78..5082d73c1 100644 --- a/version/version.go +++ b/version/version.go @@ -1,27 +1,12 @@ package version var ( - // GitCommit is the current HEAD set using ldflags. - GitCommit string - - // Version is the built softwares version. - Version = TMCoreSemVer -) - -func init() { - if GitCommit != "" { - Version += "-" + GitCommit - } -} - -const ( // TMCoreSemVer is the current version of Tendermint Core. // It's the Semantic Version of the software. - // Must be a string because scripts like dist.sh read this file. - // XXX: Don't change the name of this variable or you will break - // automation :) - TMCoreSemVer = "0.34.0" + TMCoreSemVer string +) +const ( // ABCISemVer is the semantic version of the ABCI library ABCISemVer = "0.17.0"