From 9de73bebbeb06f8023732e4dbbe76ffad6b3e3f4 Mon Sep 17 00:00:00 2001 From: Sung Won Cho Date: Sat, 13 Oct 2018 15:35:03 +1000 Subject: [PATCH] v0.4.5 (#128) * lock dep * Compare checksum and automate release --- .gitignore | 1 + .goreleaser.yml | 42 -------- Gopkg.lock | 18 ++-- Gopkg.toml | 2 +- install.sh | 252 ++++++++++++++++++++++++++++++++------------- scripts/release.sh | 81 +++++++++++++++ 6 files changed, 275 insertions(+), 121 deletions(-) delete mode 100644 .goreleaser.yml create mode 100755 scripts/release.sh diff --git a/.gitignore b/.gitignore index 77f01ca0..0d5ebeb4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ tmp/ /vendor test-dnote /dist +/releases diff --git a/.goreleaser.yml b/.goreleaser.yml deleted file mode 100644 index fb5ebc3c..00000000 --- a/.goreleaser.yml +++ /dev/null @@ -1,42 +0,0 @@ -archive: - format: tar.gz - format_overrides: - - goos: windows - format: zip - name_template: "dnote_{{ .Version }}_{{ .Os }}_{{ .Arch }}" - -checksum: - name_template: 'dnote-{{ .Version }}-checksums.txt' - -builds: -- - binary: dnote - ldflags: - - -X main.apiEndpoint={{ .Env.API_ENDPOINT }} -X main.versionTag={{ .Version }} - goos: - - darwin - - linux - - windows - - openbsd - goarch: - - amd64 - - 386 - -brew: - name: dnote - folder: Formula - github: - owner: dnote - name: homebrew-dnote - commit_author: - name: sungwoncho - email: mikeswcho@gmail.com - homepage: https://dnote.io - description: Capture your learning without leaving the command line - -changelog: - sort: asc - filters: - exclude: - - '^docs:' - - '^refactor:' diff --git a/Gopkg.lock b/Gopkg.lock index b9cf4e2c..b8fab672 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -2,12 +2,12 @@ [[projects]] - branch = "master" digest = "1:cd0089a5b5d872ac1b772087c7ee0ff2e71de50aa3a51826be64a63963a85287" name = "github.com/dnote/actions" packages = ["."] pruneopts = "" - revision = "a1050f3f457804215c4ad50d92fbe1dd2e6b587c" + revision = "60e81aff027d39f4494c5ee5c1db9c3efc015ccf" + version = "v0.2.0" [[projects]] digest = "1:e988ed0ca0d81f4d28772760c02ee95084961311291bdfefc1b04617c178b722" @@ -19,11 +19,11 @@ [[projects]] branch = "master" - digest = "1:b4074c4585d29ae58161b728c7f64709b8a856fd724722e8159c7d5f9c6ab511" + digest = "1:3c62bfc6435a5a004b8b90b6088463d19c825868cadb0cd77ed675d2bd12864f" name = "github.com/google/go-github" packages = ["github"] pruneopts = "" - revision = "71b7a374a5fcfdca56ba35925f6ddba8b890fe60" + revision = "dd29b543e14c33e6373773f2c5ea008b29aeac95" [[projects]] digest = "1:cea4aa2038169ee558bf507d5ea02c94ca85bcca28a4c7bb99fd59b31e43a686" @@ -90,20 +90,20 @@ version = "v0.0.3" [[projects]] - digest = "1:0a52bcb568386d98f4894575d53ce3e456f56471de6897bb8b9de13c33d9340e" + digest = "1:cbaf13cdbfef0e4734ed8a7504f57fe893d471d62a35b982bf6fb3f036449a66" name = "github.com/spf13/pflag" packages = ["."] pruneopts = "" - revision = "9a97c102cda95a86cec2345a6f09f55a939babf5" - version = "v1.0.2" + revision = "298182f68c66c05229eb03ac171abe6e309ee79a" + version = "v1.0.3" [[projects]] branch = "master" - digest = "1:149a432fabebb8221a80f77731b1cd63597197ded4f14af606ebe3a0959004ec" + digest = "1:a4bda6e065eb3ccf1e6adeaa863cb416e0ae6b43e613f20a8931d52d19dc20e2" name = "golang.org/x/sys" packages = ["unix"] pruneopts = "" - revision = "e4b3c5e9061176387e7cea65e4dc5853801f3fb7" + revision = "4497e2df6f9e69048a54498c7affbbec3294ad47" [[projects]] branch = "v2" diff --git a/Gopkg.toml b/Gopkg.toml index de629096..9e1b26cf 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -43,7 +43,7 @@ [[constraint]] name = "github.com/dnote/actions" - branch = "master" + version = "0.2.0" [[constraint]] name = "github.com/mattn/go-sqlite3" diff --git a/install.sh b/install.sh index e55b38ef..0950bb39 100755 --- a/install.sh +++ b/install.sh @@ -1,89 +1,203 @@ #!/bin/sh # -# This script downloads the latest Dnote release from github -# into /usr/bin/local. +# This script installs Dnote into your PATH (/usr/bin/local) +# Use it like this: +# $ curl https://raw.githubusercontent.com/dnote/cli/master/install.sh | sh # set -eu -not_supported() { - echo "OS not supported: ${UNAME}" - echo "Please compile manually from https://github.com/dnote/cli" - exit 1 +BLACK='\033[30;1m' +RED='\033[91;1m' +GREEN='\033[32;1m' +RESET='\033[0m' + +print_step() { + printf "$BLACK%s$RESET\n" "$1" } -get_platform() { - UNAME=$(uname) - - if [ "$UNAME" != "Linux" -a "$UNAME" != "Darwin" -a "$UNAME" != "OpenBSD" ] ; then - not_supported - fi - - if [ "$UNAME" = "Darwin" ]; then - OSX_ARCH=$(uname -m) - if [ "${OSX_ARCH}" = "x86_64" ]; then - platform="darwin_amd64" - else - not_supported - fi - elif [ "$UNAME" = "Linux" ]; then - LINUX_ARCH=$(uname -m) - if [ "${LINUX_ARCH}" = "x86_64" ]; then - platform="linux_amd64" - elif [ "${LINUX_ARCH}" = "i686" ]; then - platform="linux_386" - else - not_supported - fi - elif [ "$UNAME" = "OpenBSD" ]; then - OPENBSD_ARCH=$(uname -m) - if [ "${OPENBSD_ARCH}" = "x86_64" ]; then - platform="openbsd_amd64" - elif [ "${OPENBSD_ARCH}" = "i686" ]; then - platform="openbsd_386" - else - not_supported - fi - fi - - echo $platform +print_error() { + printf "$RED%s$RESET\n" "$1" } -get_version() { - LATEST=$(curl -s https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/tags | grep -Eo '"name":[ ]*"v[0-9]*\.[0-9]*\.[0-9]*",' | head -n 1 | sed 's/[," ]//g' | cut -d ':' -f 2) - if [ -z $LATEST ]; then - echo "Error fetching latest version. Please try again." +print_success() { + printf "$GREEN%s$RESET\n" "$1" +} + +is_command () { + command -v "$1" >/dev/null 2>&1; +} + +http_get() { + url=$1 + + if is_command curl; then + cmd='curl --fail -sSL' + elif is_command wget; then + cmd='wget -q' + else + print_error "unable to find wget or curl. please install and try again." + exit 1 + fi + + $cmd "$url" +} + +http_download() { + dest=$1 + srcURL=$2 + + if is_command curl; then + cmd='curl -L --progress-bar' + destflag='-o' + elif is_command wget; then + cmd='wget -q --show-progress' + destflag='-O' + else + print_error "unable to find wget or curl. please install and try again." + exit 1 + fi + + $cmd $destflag "$dest" "$srcURL" +} + +uname_os() { + os=$(uname -s | tr '[:upper:]' '[:lower:]') + echo "$os" +} + +uname_arch() { + arch=$(uname -m) + case $arch in + x86_64) arch="amd64" ;; + x86) arch="386" ;; + i686) arch="386" ;; + i386) arch="386" ;; + esac + + echo "$arch" +} + +check_platform() { + os=$1 + arch=$2 + platform="$os/$arch" + + found=1 + case "$platform" in + darwin/amd64) found=0;; + darwin/386) found=0 ;; + linux/amd64) found=0 ;; + linux/386) found=0 ;; + freebsd/amd64) found=0 ;; + freebsd/386) found=0 ;; + openbsd/amd64) found=0 ;; + openbsd/386) found=0 ;; + esac + + return $found +} + +hash_sha256() { + TARGET=${1:-/dev/stdin} + if is_command gsha256sum; then + hash=$(gsha256sum "$TARGET") + echo "$hash" | cut -d ' ' -f 1 + elif is_command sha256sum; then + hash=$(sha256sum "$TARGET") + echo "$hash" | cut -d ' ' -f 1 + elif is_command shasum; then + hash=$(shasum -a 256 "$TARGET" 2>/dev/null) + echo "$hash" | cut -d ' ' -f 1 + elif is_command openssl; then + hash=$(openssl -dst openssl dgst -sha256 "$TARGET") + echo "$hash" | cut -d ' ' -f a + else + print_error "could not find a command to compute sha256 hash and verify checksum" + exit 1 + fi +} + +verify_checksum() { + binary_path=$1 + filename=$2 + checksums=$3 + + want=$(grep "${filename}" "${checksums}" 2>/dev/null | cut -d ' ' -f 1) + if [ -z "$want" ]; then + print_error "unable to find checksum for '${filename}' in '${checksums}'" + exit 1 + fi + got=$(hash_sha256 "$binary_path") + if [ "$want" != "$got" ]; then + print_error "checksum for '$binary_path' did not verify ${want} vs $got" + exit 1 + fi +} + +install_dnote() { + os=$(uname_os) + arch=$(uname_arch) + + if ! check_platform "$os" "$arch"; then + print_error "System not supported: $os/$arch" + print_error "Please compile manually from https://github.com/dnote/cli" + exit 1 + fi + + binary=dnote + owner=sungwoncho + repo=goreleaser-issue + github_download="https://github.com/${owner}/${repo}/releases/download" + tmpdir="$(mktemp -d)" + bindir=${bindir:-/usr/local/bin} + + + # get the latest version + resp=$(http_get "https://api.github.com/repos/$owner/$repo/tags") + version=$(echo "$resp" | tr ',' '\n' | grep -m 1 "\"name\":" | cut -f4 -d'"') + + if [ -z "$version" ]; then + print_error "Error fetching latest version. Please try again." exit 1 fi # remove the preceding 'v' - echo ${LATEST#v} + version="${version#v}" + + checksum=${binary}_${version}_checksums.txt + filename=${binary}_${version}_${os}_${arch} + tarball="${filename}.tar.gz" + binary_url="${github_download}/v${version}/${tarball}" + checksum_url="${github_download}/v${version}/${checksum}" + + print_step "Latest release version is v$version." + + print_step "Downloading $binary_url." + http_download "$tmpdir/$tarball" "$binary_url" + + print_step "Downloading the checksum file for v$version" + http_download "$tmpdir/$checksum" "$checksum_url" + + # unzip tar + print_step "Inflating the binary." + (cd "${tmpdir}" && tar -xzf "${tarball}") + + print_step "Comparing checksums for binaries." + verify_checksum "${tmpdir}/${binary}" "$filename" "$tmpdir/$checksum" + + install -d "${bindir}" + install "${tmpdir}/${binary}" "${bindir}/" + + print_success "dnote v${version} was successfully installed in $bindir." } -execute() { - echo "downloading Dnote v${LATEST}..." - echo ${URL} - if curl -L --progress-bar $URL -o "${TMPDIR}/${TARBALL}"; then - (cd "${TMPDIR}" && tar -xzf "${TARBALL}") - install -d "${BINDIR}" - install "${TMPDIR}/${BINARY}" "${BINDIR}/" - - echo "Successfully installed Dnote" - else - echo "Installation failed. You might need elevated permission." - exit 1 +exit_error() { + if [ "$?" -ne 0 ]; then + print_error "A problem occurred while installing Dnote. Please report it on https://github.com/dnote/cli/issues so that we can help you." fi } -REPO_OWNER=dnote -REPO_NAME=cli -PLATFORM=$(get_platform) -LATEST=$(get_version) -TARBALL="dnote_${LATEST}_${PLATFORM}.tar.gz" -URL="https://github.com/${REPO_OWNER}/${REPO_NAME}/releases/download/v${LATEST}/${TARBALL}" -TMPDIR="$(mktemp -d)" -BINDIR=${BINDIR:-/usr/local/bin} -BINARY=dnote - -execute +trap exit_error EXIT +install_dnote diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 00000000..f4bd5b17 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +set -eu + +command_exists () { + command -v "$1" >/dev/null 2>&1; +} + +if [ $# -eq 0 ]; then + echo "no version specified." + exit 1 +fi +if [[ $1 == v* ]]; then + echo "do not prefix version with v" + exit 1 +fi + +if ! command_exists hub; then + echo "please install hub" + exit 1 +fi +if ! command_exists shasum; then + echo "please install shasum" + exit 1 +fi + +binary=dnote +version=$1 +version_tag="v$version" +goos=("linux" "openbsd" "freebsd" "darwin" "windows") +goarch=("386" "amd64") + +rm -rf ./release +mkdir ./release +cp LICENSE ./release/LICENSE +cp README.md ./release/README.md + +echo "* release $version" + +# 1. build +for os in "${goos[@]}"; do + for arch in "${goarch[@]}"; do + filename="${binary}_${version}_${os}_${arch}" + echo "* building $filename" + + goos="$os" goarch="$arch" go build \ + -o "./release/$filename" \ + -ldflags "-X main.apiEndpoint=https://api.dnote.io" \ + -ldflags "-X main.versionTag=$version" + + pushd ./release > /dev/null + cp "$filename" dnote + tar -czvf "$filename.tar.gz" dnote LICENSE README.md + shasum -a 256 "$filename" >> "dnote_${version}_checksums.txt" + popd > /dev/null + done +done + +# 2. push tag +echo "* tagging and pushing the tag" +git tag -a "$version_tag" -m "Release $version_tag" +git push --tags + +# 3. create release +files=(./release/*.tar.gz ./release/*.txt) +file_args=() +for file in "${files[@]}"; do + file_args+=("--attach=$file") +done + +echo "* creating release" +set -x +hub release create \ + "${file_args[@]}" \ + --message="$version_tag"\ + "$version_tag" + +# 4. release on brew + +homebrew_sha256=$(shasum -a 256 "./release/${binary}_${version}_darwin_amd64.tar.gz" | cut -d ' ' -f 1) +(cd "$GOPATH"/src/github.com/dnote/homebrew-dnote && ./release.sh "$version" "$homebrew_sha256")