From 50e274af58f55d3906af5ed48b115b63a6b0250c Mon Sep 17 00:00:00 2001
From: Michael Fridman <mf192@icloud.com>
Date: Mon, 3 Jul 2023 08:53:03 -0400
Subject: [PATCH] Update goreleaser and add pre-built binary scripts (#550)

---
 .github/{dependabot.yml => dependabot.yaml} |  0
 .github/workflows/{ci.yml => ci.yaml}       |  0
 .github/workflows/{e2e.yml => e2e.yaml}     |  0
 .github/workflows/{lint.yml => lint.yaml}   |  0
 .github/workflows/release.yaml              | 36 +++++++++++++++
 .gitignore                                  |  3 ++
 .goreleaser.yaml                            | 34 ++++++++++++++
 .goreleaser.yml                             | 51 ---------------------
 CHANGELOG.md                                |  2 +-
 README.md                                   |  2 +-
 cmd/goose/main.go                           | 17 ++++---
 scripts/release-notes.sh                    | 43 +++++++++++++++++
 12 files changed, 126 insertions(+), 62 deletions(-)
 rename .github/{dependabot.yml => dependabot.yaml} (100%)
 rename .github/workflows/{ci.yml => ci.yaml} (100%)
 rename .github/workflows/{e2e.yml => e2e.yaml} (100%)
 rename .github/workflows/{lint.yml => lint.yaml} (100%)
 create mode 100644 .github/workflows/release.yaml
 create mode 100644 .goreleaser.yaml
 delete mode 100644 .goreleaser.yml
 create mode 100755 scripts/release-notes.sh

diff --git a/.github/dependabot.yml b/.github/dependabot.yaml
similarity index 100%
rename from .github/dependabot.yml
rename to .github/dependabot.yaml
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yaml
similarity index 100%
rename from .github/workflows/ci.yml
rename to .github/workflows/ci.yaml
diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yaml
similarity index 100%
rename from .github/workflows/e2e.yml
rename to .github/workflows/e2e.yaml
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yaml
similarity index 100%
rename from .github/workflows/lint.yml
rename to .github/workflows/lint.yaml
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
new file mode 100644
index 0000000..b8bfa84
--- /dev/null
+++ b/.github/workflows/release.yaml
@@ -0,0 +1,36 @@
+name: goreleaser
+
+on:
+  push:
+    tags:
+      - '*'
+
+permissions:
+  contents: write
+
+jobs:
+  goreleaser:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+        with:
+          fetch-depth: 0
+      - run: git fetch --force --tags
+      - uses: actions/setup-go@v4
+        with:
+          go-version: stable
+      # More assembly might be required: Docker logins, GPG, etc. It all depends
+      # on your needs.
+      # ${{ github.ref_name }} or $GITHUB_REF_NAME or ${{env.GITHUB_REF_NAME}} currently.
+      - run: ./scripts/release-notes.sh ${{github.ref_name}} > ./release_notes.txt
+      - uses: goreleaser/goreleaser-action@v4
+        with:
+          # either 'goreleaser' (default) or 'goreleaser-pro':
+          distribution: goreleaser
+          version: latest
+          args: release --clean --release-notes=./release_notes.txt
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          # Your GoReleaser Pro key, if you are using the 'goreleaser-pro'
+          # distribution:
+          # GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
diff --git a/.gitignore b/.gitignore
index 69d484b..3690cfc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,6 @@
 # Local testing
 .envrc
 *.FAIL
+
+dist/
+release_notes.txt
diff --git a/.goreleaser.yaml b/.goreleaser.yaml
new file mode 100644
index 0000000..09e3b94
--- /dev/null
+++ b/.goreleaser.yaml
@@ -0,0 +1,34 @@
+# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
+#
+# See https://goreleaser.com/customization/ for more information.
+project_name: goose
+
+before:
+  hooks:
+    # You may remove this if you don't use go modules.
+    - go mod tidy
+builds:
+  - env:
+      - CGO_ENABLED=0
+    binary: goose
+    main: ./cmd/goose
+    goos:
+      - linux
+      - windows
+      - darwin
+    goarch:
+      - amd64
+      - arm64
+    ldflags:
+      - -s -w
+
+archives:
+  - format: binary
+    name_template: >-
+      {{ .ProjectName }}_{{- tolower .Os }}_{{- if eq .Arch "amd64" }}x86_64{{- else }}{{ .Arch }}{{ end }}
+checksum:
+  name_template: 'checksums.txt'
+snapshot:
+  name_template: "{{ incpatch .Version }}-next"
+changelog:
+  use: github-native
diff --git a/.goreleaser.yml b/.goreleaser.yml
deleted file mode 100644
index 0f2efdc..0000000
--- a/.goreleaser.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-# Documentation at https://goreleaser.com
-project_name: goose
-
-gomod:
-  proxy: true
-
-builds:
-  - env:
-      - CGO_ENABLED=0
-    main: ./cmd/goose
-    binary: goose
-    goos:
-      - linux
-      - windows
-      - darwin
-    goarch:
-      - amd64
-      - arm64
-    # Custom ldflags templates.
-    # Default is `-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser`.
-    ldflags:
-      - -s -w
-
-# You can disable this pipe in order to not upload any artifacts.
-# Defaults to false.
-release:
-  disable: false
-
-archives:
-  - replacements:
-      386: i386
-      amd64: x86_64
-    name_template: "{{ tolower .Binary }}_{{ tolower .Os }}_{{ tolower .Arch }}"
-    format: binary
-
-checksum:
-  name_template: "checksums.txt"
-
-snapshot:
-  name_template: "{{ incpatch .Version }}-next"
-
-changelog:
-  use: github
-  sort: asc
-  # Commit messages matching the regexp listed here will be removed from
-  # the changelog.
-  filters:
-    exclude:
-      - "^docs:"
-      - "^test:"
-# TODO(mf): add docker support?
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e37f387..c0542b4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,7 @@
 
 ## [Unreleased]
 
-- No changes yet.
+- Add pre-built binaries with GoReleaser.
 
 ## [v3.13.0] - 2023-06-29
 
diff --git a/README.md b/README.md
index ea1538d..9445077 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# goose [![Goose CI](https://github.com/pressly/goose/actions/workflows/ci.yml/badge.svg)](https://github.com/pressly/goose/actions/workflows/ci.yml) [![Go Reference](https://pkg.go.dev/badge/github.com/pressly/goose/v3.svg)](https://pkg.go.dev/github.com/pressly/goose/v3)
+# goose [![Goose CI](https://github.com/pressly/goose/actions/workflows/ci.yaml/badge.svg)](https://github.com/pressly/goose/actions/workflows/ci.yaml) [![Go Reference](https://pkg.go.dev/badge/github.com/pressly/goose/v3.svg)](https://pkg.go.dev/github.com/pressly/goose/v3)
 
 <p align="center">
   <img src="assets/goose_logo.png" width="125"">
diff --git a/cmd/goose/main.go b/cmd/goose/main.go
index 359299f..af29bca 100644
--- a/cmd/goose/main.go
+++ b/cmd/goose/main.go
@@ -8,7 +8,6 @@ import (
 	"log"
 	"os"
 	"path/filepath"
-	"runtime/debug"
 	"sort"
 	"strconv"
 	"strings"
@@ -27,7 +26,7 @@ var (
 	table        = flags.String("table", "goose_db_version", "migrations table name")
 	verbose      = flags.Bool("v", false, "enable verbose mode")
 	help         = flags.Bool("h", false, "print help")
-	version      = flags.Bool("version", false, "print version")
+	versionFlag  = flags.Bool("version", false, "print version")
 	certfile     = flags.String("certfile", "", "file path to root CA's certificates in pem format (only support on mysql)")
 	sequential   = flags.Bool("s", false, "use sequential numbering for new migrations")
 	allowMissing = flags.Bool("allow-missing", false, "applies missing (out-of-order) migrations")
@@ -37,7 +36,11 @@ var (
 	noColor      = flags.Bool("no-color", false, "disable color output (NO_COLOR env variable supported)")
 )
 var (
-	gooseVersion = "v3.14.0-dev"
+	// These variables are populated via GoReleaser ldflags.
+	// See https://goreleaser.com/cookbooks/using-main.version/
+	version = "(devel)"
+	// commit  = "none"
+	// date    = "unknown"
 )
 
 func main() {
@@ -47,12 +50,8 @@ func main() {
 		return
 	}
 
-	if *version {
-		buildInfo, ok := debug.ReadBuildInfo()
-		if ok && buildInfo != nil && buildInfo.Main.Version != "(devel)" {
-			gooseVersion = buildInfo.Main.Version
-		}
-		fmt.Printf("goose version: %s\n", gooseVersion)
+	if *versionFlag {
+		fmt.Printf("goose version: %s\n", version)
 		return
 	}
 	if *verbose {
diff --git a/scripts/release-notes.sh b/scripts/release-notes.sh
new file mode 100755
index 0000000..ec7fed6
--- /dev/null
+++ b/scripts/release-notes.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+set -euo pipefail
+
+# Check if the required argument is provided
+if [ $# -lt 1 ]; then
+  echo "Usage: $0 <semver version> [<changelog file>]"
+  exit 1
+fi
+
+version="$1"
+changelog_file="${2:-CHANGELOG.md}"
+
+# Check if the CHANGELOG.md file exists
+if [ ! -f "$changelog_file" ]; then
+  echo "Error: $changelog_file does not exist"
+  exit 1
+fi
+
+CAPTURE=0
+items=""
+while IFS= read -r LINE; do
+    if [[ "${LINE}" == "##"* ]] && [[ "${CAPTURE}" -eq 1 ]]; then
+        break
+    fi
+    if [[ "${LINE}" == "## [${version}]"* ]] && [[ "${CAPTURE}" -eq 0 ]]; then
+        CAPTURE=1
+        continue
+    fi
+    if [[ "${CAPTURE}" -eq 1 ]]; then
+        items+="$(echo "${LINE}" | xargs)"
+         # if items is not empty, add a newline
+        if [[ -n "$items" ]]; then
+          items+=$'\n'
+        fi
+    fi
+done <"${changelog_file}"
+
+if [[ -n "$items" ]]; then
+    echo "${items%$'\n'}"
+else
+  echo "No changelog items found for version $version"
+fi