New tool to bump current_versions.sh automatically
This commit contains a new utility that helps to automate a version bump for sandbox. You can run this command to get the vibe of what it does. ``` $ go run cmd/bump-version/main.go -help ``` In order to try it out you can run this command form sandbox root. By default it won't overwrite anything. It will print to stdout a new version of the current_versions.sh file where all the images are calculate cloning the various repositories ``` $ go run cmd/bump-version/main.go ``` If you want to overwrite the current_versions file you can use the flag `-overwrite`. More will come but for now, that's the PoC. Ideally this can be hooked to CI/CD and run periodically, opening a PR that can be evaluated and merged. Signed-off-by: Gianluca Arbezzano <gianarb92@gmail.com>
This commit is contained in:
155
cmd/bump-version/main.go
Normal file
155
cmd/bump-version/main.go
Normal file
@ -0,0 +1,155 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tinkerbell/sandbox/cmd/bump-version/envfile"
|
||||
"github.com/tinkerbell/sandbox/cmd/bump-version/git"
|
||||
"github.com/tinkerbell/sandbox/cmd/bump-version/image"
|
||||
)
|
||||
|
||||
// Config represents the flags that you can configure
|
||||
// when running bump-version
|
||||
type Config struct {
|
||||
// CurrentVersionFile is the path of the envfile that
|
||||
// contains the current version of Tinkerbell stack.
|
||||
// In sandbod it is called current_versions.sh
|
||||
CurrentVersionFile string
|
||||
// Overwrite switched the output of this program from
|
||||
// standard output to the current_versions.sh file.
|
||||
Overwrite bool
|
||||
// Help prints the help command and exists
|
||||
Help bool
|
||||
}
|
||||
|
||||
const help = `
|
||||
bump-version is an utility that reads and update the current_version.sh file.
|
||||
It is designed to be used in CI/CD but it works locally as well.
|
||||
|
||||
Note:
|
||||
* Osie is currently not supported
|
||||
|
||||
Examples:
|
||||
Prints this -help
|
||||
|
||||
$ bump-version -help
|
||||
|
||||
This is how you will normally run this command.
|
||||
bump-version will read the specified current-version-file
|
||||
(./current_version.sh), it will clone the various components in memory
|
||||
checking the latest commit available in the default branch.
|
||||
|
||||
The command will get and validate that a docker image is available for each
|
||||
component and it will print the updated current_version.sh to stdout.
|
||||
|
||||
$ bump-version -current-version-file ./current_versions.sh
|
||||
|
||||
This command does the same as the previous one but it overwrite the content
|
||||
of the original current_version file
|
||||
|
||||
$ bump-version -overwrite
|
||||
`
|
||||
|
||||
const headerFile = `#!/bin/bash
|
||||
|
||||
# This file is generated by an utility called bump-version in
|
||||
# tinkerbell/sandbox.
|
||||
# This file gets used from generate-envrc.sh but it is also used standalone by
|
||||
# automation that wants to get the version of the programs currently supported
|
||||
# in sandbox
|
||||
|
||||
`
|
||||
|
||||
func main() {
|
||||
config := Config{}
|
||||
fs := flag.NewFlagSet("bump-version", flag.ContinueOnError)
|
||||
fs.BoolVar(&config.Help, "help", false, "Display help command and exit")
|
||||
fs.BoolVar(&config.Overwrite, "overwrite", false, "This commands overwrite the current_versions file instead of printing to stdout")
|
||||
fs.StringVar(&config.CurrentVersionFile, "current-version-file", "./current_versions.sh", "Load the current_version.sh file where the current Tinkerbell component versions are specified.")
|
||||
err := fs.Parse(os.Args[1:])
|
||||
if err != nil {
|
||||
fmt.Fprint(os.Stderr, help)
|
||||
log.Fatalf("Err: %s\n\r", err.Error())
|
||||
}
|
||||
if config.Help {
|
||||
fmt.Fprint(os.Stderr, help)
|
||||
os.Exit(0)
|
||||
}
|
||||
// Read the current_versions envfile
|
||||
myEnv, err := envfile.ReadEnvFile(config.CurrentVersionFile)
|
||||
if err != nil {
|
||||
log.Fatal(errors.Wrap(err, "Impossible to read current_file.sh"))
|
||||
}
|
||||
|
||||
tag, err := getImageTagFromRepo("https://github.com/tinkerbell/tink")
|
||||
if err != nil {
|
||||
log.Fatal(errors.Wrap(err, "Impossible to get image tag from tinkerbell/tink repo"))
|
||||
}
|
||||
|
||||
// Set the new versions to the current_versions.sh
|
||||
myEnv["TINKERBELL_TINK_SERVER_IMAGE"] = "quay.io/tinkerbell/tink:" + tag
|
||||
myEnv["TINKERBELL_TINK_WORKER_IMAGE"] = "quay.io/tinkerbell/tink-worker:" + tag
|
||||
myEnv["TINKERBELL_TINK_CLI_IMAGE"] = "quay.io/tinkerbell/tink-cli:" + tag
|
||||
|
||||
tag, err = getImageTagFromRepo("https://github.com/tinkerbell/hegel")
|
||||
if err != nil {
|
||||
log.Fatal(errors.Wrap(err, "Impossible to get image tag from tinkerbell/hegel repo"))
|
||||
}
|
||||
|
||||
myEnv["TINKERBELL_TINK_HEGEL_IMAGE"] = "quay.io/tinkerbell/hegel:" + tag
|
||||
|
||||
tag, err = getImageTagFromRepo("https://github.com/tinkerbell/boots")
|
||||
if err != nil {
|
||||
log.Fatal(errors.Wrap(err, "Impossible to get image tag from tinkerbell/hegel repo"))
|
||||
}
|
||||
|
||||
myEnv["TINKERBELL_TINK_BOOTS_IMAGE"] = "quay.io/tinkerbell/boots:" + tag
|
||||
|
||||
out, err := envfile.Marshal(myEnv)
|
||||
if err != nil {
|
||||
log.Fatal(errors.Wrap(err, "Impossible to render new current_version envfile"))
|
||||
}
|
||||
|
||||
destination := os.Stdout
|
||||
// if the overwrite flag is set to true change the output of the command
|
||||
// from stdout to the original file
|
||||
if config.Overwrite {
|
||||
f, err := os.OpenFile(config.CurrentVersionFile, os.O_WRONLY|os.O_TRUNC, 0)
|
||||
if err != nil {
|
||||
log.Fatal(errors.Wrap(err, "Error overwriting current versions envfile"))
|
||||
}
|
||||
destination = f
|
||||
}
|
||||
|
||||
io.WriteString(destination, headerFile+out+"\n")
|
||||
}
|
||||
|
||||
// getImageTagFromRepo is an utility function that wraps a couple of things
|
||||
// together that technically we need to repeat for each repo.
|
||||
func getImageTagFromRepo(repoName string) (string, error) {
|
||||
// Clone the specified repository in memory
|
||||
repo, err := git.Clone(repoName)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "Impossible to clone the repository")
|
||||
}
|
||||
|
||||
// Get the latest commit from the defautl branch
|
||||
latestCommit, err := repo.GetHeadHash()
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "Impossible to get commit from HEAD")
|
||||
}
|
||||
|
||||
// Calculate the image tag from a commit sha
|
||||
tag, err := image.TagFromSha(latestCommit)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "Impossible to get image tag from commit")
|
||||
}
|
||||
|
||||
return tag, nil
|
||||
|
||||
}
|
Reference in New Issue
Block a user