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
|
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}"
|
BUILD_FLAGS = -ldflags="${LDFLAGS}"
|
||||||
|
|
||||||
# Package name of the generated Python/JavaScript code for the Flamenco API.
|
# 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
|
./addon-packer -filename ${WEB_STATIC}/flamenco3-addon.zip
|
||||||
@echo "Web app has been installed into ${WEB_STATIC}"
|
@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:
|
generate-go:
|
||||||
go generate ./pkg/api/...
|
go generate ./pkg/api/...
|
||||||
@ -99,10 +101,10 @@ generate-py:
|
|||||||
-g python \
|
-g python \
|
||||||
-o addon/ \
|
-o addon/ \
|
||||||
--package-name "${PY_API_PKG_NAME}" \
|
--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 generateSourceCodeOnly=true \
|
||||||
-p projectName=Flamenco \
|
-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,
|
# 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.
|
# though, so it's better to just remove those placeholders.
|
||||||
@ -130,7 +132,7 @@ generate-js:
|
|||||||
-i pkg/api/flamenco-openapi.yaml \
|
-i pkg/api/flamenco-openapi.yaml \
|
||||||
-g javascript \
|
-g javascript \
|
||||||
-o web/_tmp-manager-api-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 projectName=flamenco-manager \
|
||||||
-p projectVersion="0.0.0" \
|
-p projectVersion="0.0.0" \
|
||||||
-p apiPackage="${JS_API_PKG_NAME}" \
|
-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
|
git status --porcelain | grep '^ M web/app/src/manager-api' | cut -d' ' -f3 | xargs unix2dos --keepdate
|
||||||
endif
|
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:
|
version:
|
||||||
@echo "OS : ${OS}"
|
|
||||||
@echo "Package : ${PKG}"
|
@echo "Package : ${PKG}"
|
||||||
@echo "Version : ${VERSION}"
|
@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
|
@echo
|
||||||
@env | grep GO
|
@env | grep GO
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ bl_info = {
|
|||||||
"doc_url": "https://www.flamenco.io/",
|
"doc_url": "https://www.flamenco.io/",
|
||||||
"category": "System",
|
"category": "System",
|
||||||
"support": "COMMUNITY",
|
"support": "COMMUNITY",
|
||||||
|
"warning": "This is version 3.0-dev0 of the add-on, which is not a stable release",
|
||||||
}
|
}
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -72,6 +72,7 @@ func main() {
|
|||||||
log.Logger = log.Output(output)
|
log.Logger = log.Output(output)
|
||||||
log.Info().
|
log.Info().
|
||||||
Str("version", appinfo.ApplicationVersion).
|
Str("version", appinfo.ApplicationVersion).
|
||||||
|
Str("git", appinfo.ApplicationGitHash).
|
||||||
Str("os", runtime.GOOS).
|
Str("os", runtime.GOOS).
|
||||||
Str("arch", runtime.GOARCH).
|
Str("arch", runtime.GOARCH).
|
||||||
Msgf("starting %v", appinfo.ApplicationName)
|
Msgf("starting %v", appinfo.ApplicationName)
|
||||||
|
@ -61,6 +61,7 @@ func main() {
|
|||||||
|
|
||||||
log.Info().
|
log.Info().
|
||||||
Str("version", appinfo.ApplicationVersion).
|
Str("version", appinfo.ApplicationVersion).
|
||||||
|
Str("git", appinfo.ApplicationGitHash).
|
||||||
Str("OS", runtime.GOOS).
|
Str("OS", runtime.GOOS).
|
||||||
Str("ARCH", runtime.GOARCH).
|
Str("ARCH", runtime.GOARCH).
|
||||||
Int("pid", os.Getpid()).
|
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"
|
import "fmt"
|
||||||
|
|
||||||
// ApplicationName contains the application name.
|
// 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"
|
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.
|
// FormattedApplicationInfo returns the application name & version as single string.
|
||||||
func FormattedApplicationInfo() string {
|
func FormattedApplicationInfo() string {
|
||||||
return fmt.Sprintf("%s %s", ApplicationName, ApplicationVersion)
|
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.
|
// UserAgent returns the application name & version suitable for the HTTP User-Agent header.
|
||||||
func UserAgent() string {
|
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