Add build version/time stamp to Setup page and awp-cli version command
Embeds the git short hash and UTC build timestamp into both binaries via ldflags so it's easy to confirm which build is actually deployed, without needing to hand-maintain a version number. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
7370d1291e
commit
a7ebc192c8
5 changed files with 80 additions and 14 deletions
12
Makefile
12
Makefile
|
|
@ -1,14 +1,18 @@
|
|||
VERSION := $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
||||
BUILDTIME := $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
LDFLAGS := -X github.com/hculpan/areweplaying/pkg/version.Version=$(VERSION) -X github.com/hculpan/areweplaying/pkg/version.BuildTime=$(BUILDTIME)
|
||||
|
||||
all: build
|
||||
|
||||
build:
|
||||
templ generate
|
||||
go build -o areweplaying cmd/web/*.go
|
||||
go build -o awp-cli cmd/cli/*.go
|
||||
go build -ldflags "$(LDFLAGS)" -o areweplaying cmd/web/*.go
|
||||
go build -ldflags "$(LDFLAGS)" -o awp-cli cmd/cli/*.go
|
||||
|
||||
linuxbuild:
|
||||
templ generate
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o areweplaying.linux cmd/web/*.go
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o awp-cli.linux cmd/cli/*.go
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o areweplaying.linux cmd/web/*.go
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o awp-cli.linux cmd/cli/*.go
|
||||
|
||||
clean:
|
||||
rm -rf areweplaying
|
||||
|
|
|
|||
25
cmd/cli/cmd/version.go
Normal file
25
cmd/cli/cmd/version.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
Copyright © 2024 NAME HERE <EMAIL ADDRESS>
|
||||
*/
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hculpan/areweplaying/pkg/version"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// versionCmd represents the version command
|
||||
var versionCmd = &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Print the build version and time",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
fmt.Printf("awp-cli %s (built %s)\n", version.Version, version.BuildTime)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(versionCmd)
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package templates
|
|||
import (
|
||||
"strconv"
|
||||
"github.com/hculpan/areweplaying/pkg/data"
|
||||
"github.com/hculpan/areweplaying/pkg/version"
|
||||
)
|
||||
|
||||
templ Setup(session data.Session) {
|
||||
|
|
@ -197,7 +198,8 @@ templ Setup(session data.Session) {
|
|||
}
|
||||
</script>
|
||||
|
||||
<footer class=" container">
|
||||
<footer class="container text-muted small mt-4">
|
||||
Build: { version.Version } ({ version.BuildTime })
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import templruntime "github.com/a-h/templ/runtime"
|
|||
|
||||
import (
|
||||
"github.com/hculpan/areweplaying/pkg/data"
|
||||
"github.com/hculpan/areweplaying/pkg/version"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
|
@ -49,7 +50,7 @@ func Setup(session data.Session) templ.Component {
|
|||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.Itoa(session.IncrementDays))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 48, Col: 103}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 49, Col: 103}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var2)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
|
@ -67,7 +68,7 @@ func Setup(session data.Session) templ.Component {
|
|||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 89, Col: 44}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 90, Col: 44}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
|
@ -80,7 +81,7 @@ func Setup(session data.Session) templ.Component {
|
|||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(p.Email)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 90, Col: 45}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 91, Col: 45}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
|
@ -103,7 +104,7 @@ func Setup(session data.Session) templ.Component {
|
|||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 100, Col: 58}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 101, Col: 58}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var5)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
|
@ -116,7 +117,7 @@ func Setup(session data.Session) templ.Component {
|
|||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Email)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 101, Col: 60}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 102, Col: 60}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var6)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
|
@ -129,7 +130,7 @@ func Setup(session data.Session) templ.Component {
|
|||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(p.Gm))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 102, Col: 74}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 103, Col: 74}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var7)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
|
@ -142,7 +143,7 @@ func Setup(session data.Session) templ.Component {
|
|||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Attending)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 103, Col: 68}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 104, Col: 68}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var8)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
|
@ -155,7 +156,7 @@ func Setup(session data.Session) templ.Component {
|
|||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 108, Col: 87}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 109, Col: 87}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var9)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
|
@ -166,7 +167,33 @@ func Setup(session data.Session) templ.Component {
|
|||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</tbody></table></div></div></div><!-- Add Player Modal --><div class=\"modal fade\" id=\"addPlayerModal\" tabindex=\"-1\" aria-labelledby=\"addPlayerModalLabel\" aria-hidden=\"true\"><div class=\"modal-dialog\"><div class=\"modal-content bg-dark text-light\"><div class=\"modal-header\"><h5 class=\"modal-title\" id=\"addPlayerModalLabel\">Add Player</h5><button type=\"button\" class=\"btn-close btn-close-white\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div><form action=\"/admin/players/add\" method=\"post\"><div class=\"modal-body\"><div class=\"mb-3\"><label for=\"addName\" class=\"form-label\">Name</label> <input type=\"text\" class=\"form-control\" id=\"addName\" name=\"name\" required></div><div class=\"mb-3\"><label for=\"addEmail\" class=\"form-label\">Email</label> <input type=\"email\" class=\"form-control\" id=\"addEmail\" name=\"email\" required></div><div class=\"form-check\"><input class=\"form-check-input\" type=\"checkbox\" id=\"addGm\" name=\"gm\"> <label class=\"form-check-label\" for=\"addGm\">Game Master</label></div></div><div class=\"modal-footer\"><button type=\"button\" class=\"btn btn-secondary\" data-bs-dismiss=\"modal\">Cancel</button> <button type=\"submit\" class=\"btn btn-primary\">Add Player</button></div></form></div></div></div><!-- Edit Player Modal --><div class=\"modal fade\" id=\"editPlayerModal\" tabindex=\"-1\" aria-labelledby=\"editPlayerModalLabel\" aria-hidden=\"true\"><div class=\"modal-dialog\"><div class=\"modal-content bg-dark text-light\"><div class=\"modal-header\"><h5 class=\"modal-title\" id=\"editPlayerModalLabel\">Edit Player</h5><button type=\"button\" class=\"btn-close btn-close-white\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div><form action=\"/admin/players/edit\" method=\"post\"><input type=\"hidden\" id=\"editOriginalName\" name=\"originalName\"> <input type=\"hidden\" id=\"editAttending\" name=\"attending\"><div class=\"modal-body\"><div class=\"mb-3\"><label for=\"editName\" class=\"form-label\">Name</label> <input type=\"text\" class=\"form-control\" id=\"editName\" name=\"name\" required></div><div class=\"mb-3\"><label for=\"editEmail\" class=\"form-label\">Email</label> <input type=\"email\" class=\"form-control\" id=\"editEmail\" name=\"email\" required></div><div class=\"form-check\"><input class=\"form-check-input\" type=\"checkbox\" id=\"editGm\" name=\"gm\"> <label class=\"form-check-label\" for=\"editGm\">Game Master</label></div></div><div class=\"modal-footer\"><button type=\"button\" class=\"btn btn-secondary\" data-bs-dismiss=\"modal\">Cancel</button> <button type=\"submit\" class=\"btn btn-primary\">Save Changes</button></div></form></div></div></div><script src=\"https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js\" integrity=\"sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM\" crossorigin=\"anonymous\"></script><script>\n function populateEditModal(btn) {\n document.getElementById('editOriginalName').value = btn.dataset.name;\n document.getElementById('editName').value = btn.dataset.name;\n document.getElementById('editEmail').value = btn.dataset.email;\n document.getElementById('editGm').checked = btn.dataset.gm === 'true';\n document.getElementById('editAttending').value = btn.dataset.attending;\n }\n </script><footer class=\"container\"></footer></body></html>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</tbody></table></div></div></div><!-- Add Player Modal --><div class=\"modal fade\" id=\"addPlayerModal\" tabindex=\"-1\" aria-labelledby=\"addPlayerModalLabel\" aria-hidden=\"true\"><div class=\"modal-dialog\"><div class=\"modal-content bg-dark text-light\"><div class=\"modal-header\"><h5 class=\"modal-title\" id=\"addPlayerModalLabel\">Add Player</h5><button type=\"button\" class=\"btn-close btn-close-white\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div><form action=\"/admin/players/add\" method=\"post\"><div class=\"modal-body\"><div class=\"mb-3\"><label for=\"addName\" class=\"form-label\">Name</label> <input type=\"text\" class=\"form-control\" id=\"addName\" name=\"name\" required></div><div class=\"mb-3\"><label for=\"addEmail\" class=\"form-label\">Email</label> <input type=\"email\" class=\"form-control\" id=\"addEmail\" name=\"email\" required></div><div class=\"form-check\"><input class=\"form-check-input\" type=\"checkbox\" id=\"addGm\" name=\"gm\"> <label class=\"form-check-label\" for=\"addGm\">Game Master</label></div></div><div class=\"modal-footer\"><button type=\"button\" class=\"btn btn-secondary\" data-bs-dismiss=\"modal\">Cancel</button> <button type=\"submit\" class=\"btn btn-primary\">Add Player</button></div></form></div></div></div><!-- Edit Player Modal --><div class=\"modal fade\" id=\"editPlayerModal\" tabindex=\"-1\" aria-labelledby=\"editPlayerModalLabel\" aria-hidden=\"true\"><div class=\"modal-dialog\"><div class=\"modal-content bg-dark text-light\"><div class=\"modal-header\"><h5 class=\"modal-title\" id=\"editPlayerModalLabel\">Edit Player</h5><button type=\"button\" class=\"btn-close btn-close-white\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div><form action=\"/admin/players/edit\" method=\"post\"><input type=\"hidden\" id=\"editOriginalName\" name=\"originalName\"> <input type=\"hidden\" id=\"editAttending\" name=\"attending\"><div class=\"modal-body\"><div class=\"mb-3\"><label for=\"editName\" class=\"form-label\">Name</label> <input type=\"text\" class=\"form-control\" id=\"editName\" name=\"name\" required></div><div class=\"mb-3\"><label for=\"editEmail\" class=\"form-label\">Email</label> <input type=\"email\" class=\"form-control\" id=\"editEmail\" name=\"email\" required></div><div class=\"form-check\"><input class=\"form-check-input\" type=\"checkbox\" id=\"editGm\" name=\"gm\"> <label class=\"form-check-label\" for=\"editGm\">Game Master</label></div></div><div class=\"modal-footer\"><button type=\"button\" class=\"btn btn-secondary\" data-bs-dismiss=\"modal\">Cancel</button> <button type=\"submit\" class=\"btn btn-primary\">Save Changes</button></div></form></div></div></div><script src=\"https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js\" integrity=\"sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM\" crossorigin=\"anonymous\"></script><script>\n function populateEditModal(btn) {\n document.getElementById('editOriginalName').value = btn.dataset.name;\n document.getElementById('editName').value = btn.dataset.name;\n document.getElementById('editEmail').value = btn.dataset.email;\n document.getElementById('editGm').checked = btn.dataset.gm === 'true';\n document.getElementById('editAttending').value = btn.dataset.attending;\n }\n </script><footer class=\"container text-muted small mt-4\">Build: ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(version.Version)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 202, Col: 32}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, " (")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(version.BuildTime)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/web/templates/setup.templ`, Line: 202, Col: 55}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, ")</footer></body></html>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
|
|
|||
8
pkg/version/version.go
Normal file
8
pkg/version/version.go
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
package version
|
||||
|
||||
// Set at build time via -ldflags (see Makefile). Defaults are used for
|
||||
// `go run` / unbuilt binaries.
|
||||
var (
|
||||
Version = "dev"
|
||||
BuildTime = "unknown"
|
||||
)
|
||||
Loading…
Reference in a new issue