Version updates via Makefile
Flamenco now no longer uses the Git tags + hash for the application version, but an explicit `VERSION` variable in the `Makefile`. After changing the `VERSION` variable in the `Makefile`, run `make update-version`. Not every part of Flamenco looks at this variable, though. Most importantly: the Blender add-on needs special handling, because that doesn't just take a version string but a tuple of integers. Running `make update-version` updates the add-on's `bl_info` dict with the new version. If the version has any `-blabla` suffix (like `3.0-beta0`) it will also set the `warning` field to explain that it's not a stable release.
This commit is contained in:
parent
a0b4fc18e6
commit
c1a728dc2f
43
Makefile
43
Makefile
@ -1,12 +1,11 @@
|
||||
PKG := git.blender.org/flamenco
|
||||
VERSION := $(shell git describe --tags --dirty --always)
|
||||
# Version used in the OpenAPI-generated code shouldn't contain the '-dirty'
|
||||
# suffix. In the common development workflow, those files will always be dirty
|
||||
# (because they're only committed after locally working, which means the
|
||||
# implementation has already been written).
|
||||
OAPI_VERSION := $(shell git describe --tags --always)
|
||||
|
||||
LDFLAGS := -X ${PKG}/internal/appinfo.ApplicationVersion=${VERSION}
|
||||
# To update the version number in all the relevant places, update the VERSION
|
||||
# variable below and run `make update-version`.
|
||||
VERSION := 3.0-dev0
|
||||
|
||||
GITHASH := $(shell git describe --dirty --always)
|
||||
LDFLAGS := -X ${PKG}/internal/appinfo.ApplicationVersion=${VERSION} -X ${PKG}/internal/appinfo.ApplicationGitHash=${GITHASH}
|
||||
BUILD_FLAGS = -ldflags="${LDFLAGS}"
|
||||
|
||||
# Package name of the generated Python/JavaScript code for the Flamenco API.
|
||||
@ -76,7 +75,10 @@ webapp-static: addon-packer
|
||||
./addon-packer -filename ${WEB_STATIC}/flamenco3-addon.zip
|
||||
@echo "Web app has been installed into ${WEB_STATIC}"
|
||||
|
||||
generate: generate-go generate-py generate-js
|
||||
generate:
|
||||
$(MAKE) generate-go
|
||||
$(MAKE) generate-py
|
||||
$(MAKE) generate-js
|
||||
|
||||
generate-go:
|
||||
go generate ./pkg/api/...
|
||||
@ -99,10 +101,10 @@ generate-py:
|
||||
-g python \
|
||||
-o addon/ \
|
||||
--package-name "${PY_API_PKG_NAME}" \
|
||||
--http-user-agent "Flamenco/${OAPI_VERSION} (Blender add-on)" \
|
||||
--http-user-agent "Flamenco/${VERSION} (Blender add-on)" \
|
||||
-p generateSourceCodeOnly=true \
|
||||
-p projectName=Flamenco \
|
||||
-p packageVersion="${OAPI_VERSION}" > .openapi-generator-py.log
|
||||
-p packageVersion="${VERSION}" > .openapi-generator-py.log
|
||||
|
||||
# The generator outputs files so that we can write our own tests. We don't,
|
||||
# though, so it's better to just remove those placeholders.
|
||||
@ -130,7 +132,7 @@ generate-js:
|
||||
-i pkg/api/flamenco-openapi.yaml \
|
||||
-g javascript \
|
||||
-o web/_tmp-manager-api-javascript \
|
||||
--http-user-agent "Flamenco/${OAPI_VERSION} / webbrowser" \
|
||||
--http-user-agent "Flamenco/${VERSION} / webbrowser" \
|
||||
-p projectName=flamenco-manager \
|
||||
-p projectVersion="0.0.0" \
|
||||
-p apiPackage="${JS_API_PKG_NAME}" \
|
||||
@ -149,11 +151,26 @@ ifeq ($(OS),Windows_NT)
|
||||
git status --porcelain | grep '^ M web/app/src/manager-api' | cut -d' ' -f3 | xargs unix2dos --keepdate
|
||||
endif
|
||||
|
||||
.PHONY:
|
||||
update-version:
|
||||
@echo "--- Updating Flamenco version to ${VERSION}"
|
||||
@echo "--- If this stops with exit status 42, it was already at that version."
|
||||
@echo
|
||||
go run ./cmd/update-version ${VERSION}
|
||||
$(MAKE) generate-py
|
||||
$(MAKE) generate-js
|
||||
@echo
|
||||
@echo 'File replacement done, commit with:'
|
||||
@echo
|
||||
@echo 'git commit -m "Bumped version to ${VERSION}" Makefile addon/flamenco/__init__.py'
|
||||
@echo 'git tag -a -m "Tagged version ${VERSION}" v${VERSION}'
|
||||
|
||||
version:
|
||||
@echo "OS : ${OS}"
|
||||
@echo "Package : ${PKG}"
|
||||
@echo "Version : ${VERSION}"
|
||||
@echo "OAPI Version: ${OAPI_VERSION}"
|
||||
@echo "Git Hash : ${GITHASH}"
|
||||
@echo -n "GOOS : "; go env GOOS
|
||||
@echo -n "GOARCH : "; go env GOARCH
|
||||
@echo
|
||||
@env | grep GO
|
||||
|
||||
|
@ -12,6 +12,7 @@ bl_info = {
|
||||
"doc_url": "https://www.flamenco.io/",
|
||||
"category": "System",
|
||||
"support": "COMMUNITY",
|
||||
"warning": "This is version 3.0-dev0 of the add-on, which is not a stable release",
|
||||
}
|
||||
|
||||
from pathlib import Path
|
||||
|
@ -72,6 +72,7 @@ func main() {
|
||||
log.Logger = log.Output(output)
|
||||
log.Info().
|
||||
Str("version", appinfo.ApplicationVersion).
|
||||
Str("git", appinfo.ApplicationGitHash).
|
||||
Str("os", runtime.GOOS).
|
||||
Str("arch", runtime.GOARCH).
|
||||
Msgf("starting %v", appinfo.ApplicationName)
|
||||
|
@ -61,6 +61,7 @@ func main() {
|
||||
|
||||
log.Info().
|
||||
Str("version", appinfo.ApplicationVersion).
|
||||
Str("git", appinfo.ApplicationGitHash).
|
||||
Str("OS", runtime.GOOS).
|
||||
Str("ARCH", runtime.GOARCH).
|
||||
Int("pid", os.Getpid()).
|
||||
|
65
cmd/update-version/addon.go
Normal file
65
cmd/update-version/addon.go
Normal file
@ -0,0 +1,65 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
const addonVersionFile = "addon/flamenco/__init__.py"
|
||||
|
||||
// updateAddon changes the version number in the Blender add-on.
|
||||
// Returns whether the file actually changed.
|
||||
func updateAddon() bool {
|
||||
// The add-on needs a (x, y, z) tuple as version, and doesn't support suffixes
|
||||
// like `-dev0` or `-beta3`.
|
||||
splitOnDash := strings.SplitN(cliArgs.newVersion, "-", 2)
|
||||
versionWithoutSuffix := splitOnDash[0]
|
||||
|
||||
var warning string
|
||||
if len(splitOnDash) >= 2 {
|
||||
log.Warn().Msg("versions of form `x.y.z-something` will put a warning in the bl_info about the `-something`")
|
||||
warning = fmt.Sprintf("This is version %s of the add-on, which is not a stable release", cliArgs.newVersion)
|
||||
}
|
||||
|
||||
versionParts := strings.Split(versionWithoutSuffix, ".")
|
||||
var versionTuple string
|
||||
switch len(versionParts) {
|
||||
case 0:
|
||||
log.Fatal().Str("versionWithoutSuffix", versionWithoutSuffix).Msg("no dot-separated version number found")
|
||||
case 1:
|
||||
log.Warn().Strs("versionParts", versionParts).Msg("only a major version found, may be the wrong syntax")
|
||||
versionTuple = fmt.Sprintf("(%s, 0)", versionParts[0])
|
||||
case 2:
|
||||
log.Debug().Strs("versionParts", versionParts).Msg("major.minor version found, this is expected")
|
||||
versionTuple = fmt.Sprintf("(%s, %s)", versionParts[0], versionParts[1])
|
||||
case 3:
|
||||
log.Debug().Strs("versionParts", versionParts).Msg("major.minor.micro version found, this is expected")
|
||||
versionTuple = fmt.Sprintf("(%s, %s, %s)", versionParts[0], versionParts[1], versionParts[2])
|
||||
default:
|
||||
log.Warn().Strs("versionParts", versionParts).Msg("more than three (major, minor, micro) version parts found, using only the first three")
|
||||
versionTuple = fmt.Sprintf("(%s, %s, %s)", versionParts[0], versionParts[1], versionParts[2])
|
||||
}
|
||||
|
||||
var blinfoOpened, blinfoClosed bool
|
||||
replacer := func(line string) string {
|
||||
switch {
|
||||
case !blinfoOpened && strings.HasPrefix(line, "bl_info = {"):
|
||||
blinfoOpened = true
|
||||
case blinfoOpened && strings.HasPrefix(line, "}"):
|
||||
blinfoClosed = true
|
||||
case blinfoOpened && !blinfoClosed && strings.HasPrefix(line, " \"version\":"):
|
||||
return fmt.Sprintf(" \"version\": %s,", versionTuple)
|
||||
case blinfoOpened && !blinfoClosed && strings.HasPrefix(line, " \"warning\":"):
|
||||
return fmt.Sprintf(" \"warning\": %q,", warning)
|
||||
}
|
||||
return line
|
||||
}
|
||||
|
||||
fileWasChanged, err := updateLines(addonVersionFile, replacer)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("error updating add-on")
|
||||
}
|
||||
return fileWasChanged
|
||||
}
|
63
cmd/update-version/linereplacer.go
Normal file
63
cmd/update-version/linereplacer.go
Normal file
@ -0,0 +1,63 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// updateLines calls replacer() on each line of the given file, and replaces it
|
||||
// with the returned value.
|
||||
// Returns whether the file changed at all.
|
||||
func updateLines(filename string, replacer func(string) string) (bool, error) {
|
||||
logger := log.With().Str("filename", filename).Logger()
|
||||
logger.Info().Msg("updating file")
|
||||
|
||||
// Read the file contents:
|
||||
input, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("reading from %s: %w", filename, err)
|
||||
}
|
||||
|
||||
// Replace the lines:
|
||||
anythingChanged := false
|
||||
lines := strings.Split(string(input), "\n")
|
||||
for idx := range lines {
|
||||
replaced := replacer(lines[idx])
|
||||
if replaced == lines[idx] {
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Info().
|
||||
Str("old", strings.TrimSpace(lines[idx])).
|
||||
Str("new", strings.TrimSpace(replaced)).
|
||||
Msg("replacing line")
|
||||
lines[idx] = replaced
|
||||
anythingChanged = true
|
||||
}
|
||||
|
||||
if !anythingChanged {
|
||||
logger.Info().Msg("file did not change, will not touch it")
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Write the file contents to a temporary location:
|
||||
output := strings.Join(lines, "\n")
|
||||
tempname := filename + "~"
|
||||
err = os.WriteFile(tempname, []byte(output), 0644)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("writing to %s: %w", tempname, err)
|
||||
}
|
||||
|
||||
// Move the temporary file onto the input filename:
|
||||
if err := os.Remove(filename); err != nil {
|
||||
return false, fmt.Errorf("removing %s: %w", filename, err)
|
||||
}
|
||||
if err := os.Rename(tempname, filename); err != nil {
|
||||
return false, fmt.Errorf("renaming %s to %s: %w", tempname, filename, err)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
87
cmd/update-version/main.go
Normal file
87
cmd/update-version/main.go
Normal file
@ -0,0 +1,87 @@
|
||||
package main
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/mattn/go-colorable"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
var cliArgs struct {
|
||||
// Logging level flags.
|
||||
quiet, debug, trace bool
|
||||
|
||||
newVersion string
|
||||
updateMakefile bool
|
||||
}
|
||||
|
||||
func main() {
|
||||
parseCliArgs()
|
||||
output := zerolog.ConsoleWriter{Out: colorable.NewColorableStdout(), TimeFormat: time.RFC3339}
|
||||
log.Logger = log.Output(output)
|
||||
configLogLevel()
|
||||
|
||||
log.Info().Str("version", cliArgs.newVersion).Msg("updating Flamenco version")
|
||||
|
||||
var anyFileWasChanged bool
|
||||
if cliArgs.updateMakefile {
|
||||
anyFileWasChanged = anyFileWasChanged || updateMakefile()
|
||||
}
|
||||
anyFileWasChanged = anyFileWasChanged || updateAddon()
|
||||
|
||||
if !anyFileWasChanged {
|
||||
log.Warn().Msg("nothing changed")
|
||||
os.Exit(42)
|
||||
return
|
||||
}
|
||||
|
||||
// Lot the result & some easy-to-copy Git commands:
|
||||
commitMsg := fmt.Sprintf("Bumped version to %s", cliArgs.newVersion)
|
||||
tagMsg := fmt.Sprintf("Tagged version %s", cliArgs.newVersion)
|
||||
log.Info().Msg("file replacement done, commit with:")
|
||||
log.Info().Msgf("git commit -m %q %s %s", commitMsg, makefileFile, addonVersionFile)
|
||||
log.Info().Msgf("git tag -a -m %q v%s", tagMsg, cliArgs.newVersion)
|
||||
}
|
||||
|
||||
func parseCliArgs() {
|
||||
flag.BoolVar(&cliArgs.quiet, "quiet", false, "Only log warning-level and worse.")
|
||||
flag.BoolVar(&cliArgs.debug, "debug", false, "Enable debug-level logging.")
|
||||
flag.BoolVar(&cliArgs.trace, "trace", false, "Enable trace-level logging.")
|
||||
flag.BoolVar(&cliArgs.updateMakefile, "makefile", false,
|
||||
"Also update the Makefile. Normally this application is invoked from the Makefile itself, "+
|
||||
"and thus it does not change that file without this CLI argument.")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
cliArgs.newVersion = flag.Arg(0)
|
||||
if cliArgs.newVersion == "" {
|
||||
os.Stderr.WriteString(fmt.Sprintf("Usage: %s [-quiet|-debug|-trace] {new Flamenco version number}\n", os.Args[0]))
|
||||
os.Stderr.WriteString("\n")
|
||||
flag.PrintDefaults()
|
||||
os.Stderr.WriteString("\n")
|
||||
os.Stderr.WriteString("This program updates Makefile and some other files to set the new Flamenco version.\n")
|
||||
os.Stderr.WriteString("\n")
|
||||
os.Exit(47)
|
||||
}
|
||||
}
|
||||
|
||||
func configLogLevel() {
|
||||
var logLevel zerolog.Level
|
||||
switch {
|
||||
case cliArgs.trace:
|
||||
logLevel = zerolog.TraceLevel
|
||||
case cliArgs.debug:
|
||||
logLevel = zerolog.DebugLevel
|
||||
case cliArgs.quiet:
|
||||
logLevel = zerolog.WarnLevel
|
||||
default:
|
||||
logLevel = zerolog.InfoLevel
|
||||
}
|
||||
zerolog.SetGlobalLevel(logLevel)
|
||||
}
|
27
cmd/update-version/makefile.go
Normal file
27
cmd/update-version/makefile.go
Normal file
@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
const makefileFile = "Makefile"
|
||||
|
||||
// updateMakefile changes the version number in Makefile.
|
||||
// Returns whether the file actually changed.
|
||||
func updateMakefile() bool {
|
||||
replacer := func(line string) string {
|
||||
if !strings.HasPrefix(line, "VERSION := ") {
|
||||
return line
|
||||
}
|
||||
return fmt.Sprintf("VERSION := %q", cliArgs.newVersion)
|
||||
}
|
||||
|
||||
fileWasChanged, err := updateLines(makefileFile, replacer)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("error updating Makefile")
|
||||
}
|
||||
return fileWasChanged
|
||||
}
|
@ -5,11 +5,16 @@ package appinfo
|
||||
import "fmt"
|
||||
|
||||
// ApplicationName contains the application name.
|
||||
const ApplicationName = "Flamenco 3"
|
||||
const ApplicationName = "Flamenco"
|
||||
|
||||
// ApplicationVersion has the version number, and is set during the build.
|
||||
// ApplicationVersion is the version number of the application.
|
||||
// It is set during the build.
|
||||
var ApplicationVersion = "set-during-build"
|
||||
|
||||
// ApplicationGitHash has the Git hash of the commit used to create this build.
|
||||
// It is set during the build.
|
||||
var ApplicationGitHash = "set-during-build"
|
||||
|
||||
// FormattedApplicationInfo returns the application name & version as single string.
|
||||
func FormattedApplicationInfo() string {
|
||||
return fmt.Sprintf("%s %s", ApplicationName, ApplicationVersion)
|
||||
@ -17,5 +22,5 @@ func FormattedApplicationInfo() string {
|
||||
|
||||
// UserAgent returns the application name & version suitable for the HTTP User-Agent header.
|
||||
func UserAgent() string {
|
||||
return fmt.Sprintf("%s/%s", ApplicationName, ApplicationVersion)
|
||||
return fmt.Sprintf("%s/%s (%s)", ApplicationName, ApplicationVersion, ApplicationGitHash)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user