build: add container labels and annotations (#4071)
This adds a new helper which retrieves the build metadata, uses it to generate container labels, and refactors XFlags uses to utilize the same machinery. Co-authored-by: James Elliott <james-d-elliott@users.noreply.github.com>pull/4079/head
parent
a7a217a036
commit
e3f5a574fe
|
@ -40,7 +40,7 @@ func cmdBuildRun(cobraCmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
cmdCleanRun(cobraCmd, args)
|
cmdCleanRun(cobraCmd, args)
|
||||||
|
|
||||||
xflags, err := getXFlags(branch, os.Getenv("BUILDKITE_BUILD_NUMBER"), "")
|
buildMetaData, err := getBuild(branch, os.Getenv("BUILDKITE_BUILD_NUMBER"), "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -62,11 +62,11 @@ func cmdBuildRun(cobraCmd *cobra.Command, args []string) {
|
||||||
if buildkite {
|
if buildkite {
|
||||||
log.Info("Building Authelia Go binaries with gox...")
|
log.Info("Building Authelia Go binaries with gox...")
|
||||||
|
|
||||||
buildAutheliaBinaryGOX(xflags)
|
buildAutheliaBinaryGOX(buildMetaData.XFlags())
|
||||||
} else {
|
} else {
|
||||||
log.Info("Building Authelia Go binary...")
|
log.Info("Building Authelia Go binary...")
|
||||||
|
|
||||||
buildAutheliaBinaryGO(xflags)
|
buildAutheliaBinaryGO(buildMetaData.XFlags())
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanAssets()
|
cleanAssets()
|
||||||
|
|
|
@ -13,15 +13,17 @@ import (
|
||||||
|
|
||||||
var container string
|
var container string
|
||||||
|
|
||||||
var containers = []string{"dev", "coverage"}
|
var (
|
||||||
var defaultContainer = "dev"
|
containers = []string{"dev", "coverage"}
|
||||||
var ciBranch = os.Getenv("BUILDKITE_BRANCH")
|
defaultContainer = "dev"
|
||||||
var ciPullRequest = os.Getenv("BUILDKITE_PULL_REQUEST")
|
ciBranch = os.Getenv("BUILDKITE_BRANCH")
|
||||||
var ciTag = os.Getenv("BUILDKITE_TAG")
|
ciPullRequest = os.Getenv("BUILDKITE_PULL_REQUEST")
|
||||||
var dockerTags = regexp.MustCompile(`v(?P<Patch>(?P<Minor>(?P<Major>\d+)\.\d+)\.\d+.*)`)
|
ciTag = os.Getenv("BUILDKITE_TAG")
|
||||||
var ignoredSuffixes = regexp.MustCompile("alpha|beta")
|
dockerTags = regexp.MustCompile(`v(?P<Patch>(?P<Minor>(?P<Major>\d+)\.\d+)\.\d+.*)`)
|
||||||
var publicRepo = regexp.MustCompile(`.*:.*`)
|
ignoredSuffixes = regexp.MustCompile("alpha|beta")
|
||||||
var tags = dockerTags.FindStringSubmatch(ciTag)
|
publicRepo = regexp.MustCompile(`.*:.*`)
|
||||||
|
tags = dockerTags.FindStringSubmatch(ciTag)
|
||||||
|
)
|
||||||
|
|
||||||
func newDockerCmd() (cmd *cobra.Command) {
|
func newDockerCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
|
@ -143,13 +145,12 @@ func dockerBuildOfficialImage(arch string) error {
|
||||||
filename := "Dockerfile"
|
filename := "Dockerfile"
|
||||||
dockerfile := fmt.Sprintf("%s.%s", filename, arch)
|
dockerfile := fmt.Sprintf("%s.%s", filename, arch)
|
||||||
|
|
||||||
flags, err := getXFlags(ciBranch, os.Getenv("BUILDKITE_BUILD_NUMBER"), "")
|
buildMetaData, err := getBuild(ciBranch, os.Getenv("BUILDKITE_BUILD_NUMBER"), "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return docker.Build(IntermediateDockerImageName, dockerfile, ".",
|
return docker.Build(IntermediateDockerImageName, dockerfile, ".", buildMetaData)
|
||||||
strings.Join(flags, " "))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func login(docker *Docker, registry string) {
|
func login(docker *Docker, registry string) {
|
||||||
|
|
|
@ -2,66 +2,63 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authelia/authelia/v4/internal/utils"
|
"github.com/authelia/authelia/v4/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getXFlags(branch, build, extra string) (flags []string, err error) {
|
func getBuild(branch, buildNumber, extra string) (b *Build, err error) {
|
||||||
if branch == "" {
|
var out string
|
||||||
out, _, err := utils.RunCommandAndReturnOutput("git rev-parse --abbrev-ref HEAD")
|
|
||||||
if err != nil {
|
b = &Build{
|
||||||
return flags, fmt.Errorf("error getting branch with git rev-parse: %w", err)
|
Branch: branch,
|
||||||
|
Extra: extra,
|
||||||
|
}
|
||||||
|
|
||||||
|
if buildNumber != "" {
|
||||||
|
if b.Number, err = strconv.Atoi(buildNumber); err != nil {
|
||||||
|
return nil, fmt.Errorf("error parsing provided build number: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.Branch == "" {
|
||||||
|
if out, _, err = utils.RunCommandAndReturnOutput("git rev-parse --abbrev-ref HEAD"); err != nil {
|
||||||
|
return nil, fmt.Errorf("error getting branch with git rev-parse: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if out == "" {
|
if out == "" {
|
||||||
branch = "master"
|
b.Branch = "master"
|
||||||
} else {
|
} else {
|
||||||
branch = out
|
b.Branch = out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gitTagCommit, _, err := utils.RunCommandAndReturnOutput("git rev-list --tags --max-count=1")
|
var (
|
||||||
if err != nil {
|
gitTagCommit string
|
||||||
return flags, fmt.Errorf("error getting tag commit with git rev-list: %w", err)
|
)
|
||||||
|
|
||||||
|
if gitTagCommit, _, err = utils.RunCommandAndReturnOutput("git rev-list --tags --max-count=1"); err != nil {
|
||||||
|
return nil, fmt.Errorf("error getting tag commit with git rev-list: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tag, _, err := utils.RunCommandAndReturnOutput(fmt.Sprintf("git describe --tags --abbrev=0 %s", gitTagCommit))
|
if b.Tag, _, err = utils.RunCommandAndReturnOutput(fmt.Sprintf("git describe --tags --abbrev=0 %s", gitTagCommit)); err != nil {
|
||||||
if err != nil {
|
return nil, fmt.Errorf("error getting tag with git describe: %w", err)
|
||||||
return flags, fmt.Errorf("error getting tag with git describe: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commit, _, err := utils.RunCommandAndReturnOutput("git rev-parse HEAD")
|
if b.Commit, _, err = utils.RunCommandAndReturnOutput("git rev-parse HEAD"); err != nil {
|
||||||
if err != nil {
|
return nil, fmt.Errorf("error getting commit with git rev-parse: %w", err)
|
||||||
return flags, fmt.Errorf("error getting commit with git rev-parse: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var states []string
|
if gitTagCommit == b.Commit {
|
||||||
|
b.Tagged = true
|
||||||
if gitTagCommit == commit {
|
|
||||||
states = append(states, "tagged")
|
|
||||||
} else {
|
|
||||||
states = append(states, "untagged")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, exitCode, _ := utils.RunCommandAndReturnOutput("git diff --quiet"); exitCode != 0 {
|
if _, exitCode, _ := utils.RunCommandAndReturnOutput("git diff --quiet"); exitCode == 0 {
|
||||||
states = append(states, "dirty")
|
b.Clean = true
|
||||||
} else {
|
|
||||||
states = append(states, "clean")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if build == "" {
|
b.Date = time.Now()
|
||||||
build = "manual"
|
|
||||||
}
|
|
||||||
|
|
||||||
return []string{
|
return b, nil
|
||||||
fmt.Sprintf(fmtLDFLAGSX, "BuildBranch", branch),
|
|
||||||
fmt.Sprintf(fmtLDFLAGSX, "BuildTag", tag),
|
|
||||||
fmt.Sprintf(fmtLDFLAGSX, "BuildCommit", commit),
|
|
||||||
fmt.Sprintf(fmtLDFLAGSX, "BuildDate", time.Now().Format("Mon, 02 Jan 2006 15:04:05 -0700")),
|
|
||||||
fmt.Sprintf(fmtLDFLAGSX, "BuildState", strings.Join(states, " ")),
|
|
||||||
fmt.Sprintf(fmtLDFLAGSX, "BuildExtra", extra),
|
|
||||||
fmt.Sprintf(fmtLDFLAGSX, "BuildNumber", build),
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/authelia/authelia/v4/internal/utils"
|
"github.com/authelia/authelia/v4/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -8,11 +15,20 @@ import (
|
||||||
type Docker struct{}
|
type Docker struct{}
|
||||||
|
|
||||||
// Build build a docker image.
|
// Build build a docker image.
|
||||||
func (d *Docker) Build(tag, dockerfile, target, ldflags string) error {
|
func (d *Docker) Build(tag, dockerfile, target string, buildMetaData *Build) error {
|
||||||
return utils.CommandWithStdout(
|
args := []string{"build", "-t", tag, "-f", dockerfile, "--progress=plain"}
|
||||||
"docker", "build", "-t", tag, "-f", dockerfile,
|
|
||||||
"--progress=plain", "--build-arg", "LDFLAGS_EXTRA="+ldflags,
|
for label, value := range buildMetaData.ContainerLabels() {
|
||||||
target).Run()
|
if value == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args, "--label", fmt.Sprintf("%s=%s", label, value))
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args, "--build-arg", "LDFLAGS_EXTRA="+strings.Join(buildMetaData.XFlags(), " "), target)
|
||||||
|
|
||||||
|
return utils.CommandWithStdout("docker", args...).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tag tag a docker image.
|
// Tag tag a docker image.
|
||||||
|
@ -27,10 +43,101 @@ func (d *Docker) Login(username, password, registry string) error {
|
||||||
|
|
||||||
// Manifest push a docker manifest to dockerhub.
|
// Manifest push a docker manifest to dockerhub.
|
||||||
func (d *Docker) Manifest(tag1, tag2 string) error {
|
func (d *Docker) Manifest(tag1, tag2 string) error {
|
||||||
return utils.CommandWithStdout("docker", "build", "-t", tag1, "-t", tag2, "--platform", "linux/amd64,linux/arm/v7,linux/arm64", "--builder", "buildx", "--push", ".").Run()
|
args := []string{"build", "-t", tag1, "-t", tag2}
|
||||||
|
annotations := ""
|
||||||
|
|
||||||
|
buildMetaData, err := getBuild(ciBranch, os.Getenv("BUILDKITE_BUILD_NUMBER"), "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for label, value := range buildMetaData.ContainerLabels() {
|
||||||
|
if value == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
annotations += fmt.Sprintf("annotation.%s=%s,", label, value)
|
||||||
|
args = append(args, "--label", fmt.Sprintf("%s=%s", label, value))
|
||||||
|
}
|
||||||
|
|
||||||
|
var baseImageTag string
|
||||||
|
|
||||||
|
from, err := getDockerfileDirective("Dockerfile", "FROM")
|
||||||
|
if err == nil {
|
||||||
|
baseImageTag = from[strings.IndexRune(from, ':')+1:]
|
||||||
|
args = append(args, "--label", "org.opencontainers.image.base.name=docker.io/library/alpine:"+baseImageTag)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.Get("https://hub.docker.com/v2/repositories/library/alpine/tags/" + baseImageTag + "/images")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
images := DockerImages{}
|
||||||
|
|
||||||
|
if err = json.NewDecoder(resp.Body).Decode(&images); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
digestAMD64, digestARM, digestARM64 string
|
||||||
|
)
|
||||||
|
|
||||||
|
for _, platform := range []string{"linux/amd64", "linux/arm/v7", "linux/arm64"} {
|
||||||
|
for _, image := range images {
|
||||||
|
if !image.Match(platform) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch platform {
|
||||||
|
case "linux/amd64":
|
||||||
|
digestAMD64 = image.Digest
|
||||||
|
case "linux/arm/v7":
|
||||||
|
digestARM = image.Digest
|
||||||
|
case "linux/arm64":
|
||||||
|
digestARM64 = image.Digest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
finalArgs := make([]string, len(args))
|
||||||
|
|
||||||
|
copy(finalArgs, args)
|
||||||
|
|
||||||
|
finalArgs = append(finalArgs, "--output", "type=image,\"name="+dockerhub+"/"+DockerImageName+","+ghcr+"/"+DockerImageName+"\","+annotations+"annotation.org.opencontainers.image.base.name=docker.io/library/alpine:"+baseImageTag+",annotation[linux/amd64].org.opencontainers.image.base.digest="+digestAMD64+",annotation[linux/arm/v7].org.opencontainers.image.base.digest="+digestARM+",annotation[linux/arm64].org.opencontainers.image.base.digest="+digestARM64, "--platform", "linux/amd64,linux/arm/v7,linux/arm64", "--builder", "buildx", "--push", ".")
|
||||||
|
|
||||||
|
if err = utils.CommandWithStdout("docker", finalArgs...).Run(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublishReadme push README.md to dockerhub.
|
// PublishReadme push README.md to dockerhub.
|
||||||
func (d *Docker) PublishReadme() error {
|
func (d *Docker) PublishReadme() error {
|
||||||
return utils.CommandWithStdout("bash", "-c", `token=$(curl -fs --retry 3 -H "Content-Type: application/json" -X "POST" -d '{"username": "'$DOCKER_USERNAME'", "password": "'$DOCKER_PASSWORD'"}' https://hub.docker.com/v2/users/login/ | jq -r .token) && jq -n --arg msg "$(cat README.md | sed -r 's/(\<img\ src\=\")(\.\/)/\1https:\/\/github.com\/authelia\/authelia\/raw\/master\//' | sed 's/\.\//https:\/\/github.com\/authelia\/authelia\/blob\/master\//g' | sed '/start \[contributing\]/ a <a href="https://github.com/authelia/authelia/graphs/contributors"><img src="https://opencollective.com/authelia-sponsors/contributors.svg?width=890" /></a>' | sed '/Thanks goes to/,/### Backers/{/### Backers/!d}')" '{"registry":"registry-1.docker.io","full_description": $msg }' | curl -fs --retry 3 -o /dev/null -L -X "PATCH" -H "Content-Type: application/json" -H "Authorization: JWT $token" -d @- https://hub.docker.com/v2/repositories/authelia/authelia/`).Run()
|
return utils.CommandWithStdout("bash", "-c", `token=$(curl -fs --retry 3 -H "Content-Type: application/json" -X "POST" -d '{"username": "'$DOCKER_USERNAME'", "password": "'$DOCKER_PASSWORD'"}' https://hub.docker.com/v2/users/login/ | jq -r .token) && jq -n --arg msg "$(cat README.md | sed -r 's/(\<img\ src\=\")(\.\/)/\1https:\/\/github.com\/authelia\/authelia\/raw\/master\//' | sed 's/\.\//https:\/\/github.com\/authelia\/authelia\/blob\/master\//g' | sed '/start \[contributing\]/ a <a href="https://github.com/authelia/authelia/graphs/contributors"><img src="https://opencollective.com/authelia-sponsors/contributors.svg?width=890" /></a>' | sed '/Thanks goes to/,/### Backers/{/### Backers/!d}')" '{"registry":"registry-1.docker.io","full_description": $msg }' | curl -fs --retry 3 -o /dev/null -L -X "PATCH" -H "Content-Type: application/json" -H "Authorization: JWT $token" -d @- https://hub.docker.com/v2/repositories/authelia/authelia/`).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getDockerfileDirective(filePath, directive string) (from string, err error) {
|
||||||
|
var f *os.File
|
||||||
|
|
||||||
|
if f, err = os.Open(filePath); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
s := bufio.NewScanner(f)
|
||||||
|
|
||||||
|
for s.Scan() {
|
||||||
|
data := s.Text()
|
||||||
|
|
||||||
|
if strings.HasPrefix(data, directive+" ") {
|
||||||
|
return data[5:], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,130 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/v4/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
// HostEntry represents an entry in /etc/hosts.
|
// HostEntry represents an entry in /etc/hosts.
|
||||||
type HostEntry struct {
|
type HostEntry struct {
|
||||||
Domain string
|
Domain string
|
||||||
IP string
|
IP string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DockerImages represents some of the data from the docker images API.
|
||||||
|
type DockerImages []DockerImage
|
||||||
|
|
||||||
|
// DockerImage represents some of the data from the docker images API.
|
||||||
|
type DockerImage struct {
|
||||||
|
Architecture string `json:"architecture"`
|
||||||
|
Variant interface{} `json:"variant"`
|
||||||
|
Digest string `json:"digest"`
|
||||||
|
OS string `json:"os"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match returns true if this image matches the platform.
|
||||||
|
func (d DockerImage) Match(platform string) bool {
|
||||||
|
parts := []string{d.OS, d.Architecture}
|
||||||
|
|
||||||
|
if strings.Join(parts, "/") == platform {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.Variant == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
parts = append(parts, d.Variant.(string))
|
||||||
|
|
||||||
|
return strings.Join(parts, "/") == platform
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build represents a builds metadata.
|
||||||
|
type Build struct {
|
||||||
|
Branch string
|
||||||
|
Tag string
|
||||||
|
Commit string
|
||||||
|
Tagged bool
|
||||||
|
Clean bool
|
||||||
|
Extra string
|
||||||
|
Number int
|
||||||
|
Date time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// States returns the state tags for this Build.
|
||||||
|
func (b Build) States() []string {
|
||||||
|
var states []string
|
||||||
|
|
||||||
|
if b.Tagged {
|
||||||
|
states = append(states, "tagged")
|
||||||
|
} else {
|
||||||
|
states = append(states, "untagged")
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.Clean {
|
||||||
|
states = append(states, "clean")
|
||||||
|
} else {
|
||||||
|
states = append(states, "dirty")
|
||||||
|
}
|
||||||
|
|
||||||
|
return states
|
||||||
|
}
|
||||||
|
|
||||||
|
// State returns the state tags string for this Build.
|
||||||
|
func (b Build) State() string {
|
||||||
|
return strings.Join(b.States(), " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// XFlags returns the XFlags for this Build.
|
||||||
|
func (b Build) XFlags() []string {
|
||||||
|
return []string{
|
||||||
|
fmt.Sprintf(fmtLDFLAGSX, "BuildBranch", b.Branch),
|
||||||
|
fmt.Sprintf(fmtLDFLAGSX, "BuildTag", b.Tag),
|
||||||
|
fmt.Sprintf(fmtLDFLAGSX, "BuildCommit", b.Commit),
|
||||||
|
fmt.Sprintf(fmtLDFLAGSX, "BuildDate", b.Date.Format("Mon, 02 Jan 2006 15:04:05 -0700")),
|
||||||
|
fmt.Sprintf(fmtLDFLAGSX, "BuildState", b.State()),
|
||||||
|
fmt.Sprintf(fmtLDFLAGSX, "BuildExtra", b.Extra),
|
||||||
|
fmt.Sprintf(fmtLDFLAGSX, "BuildNumber", strconv.Itoa(b.Number)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerLabels returns the container labels for this Build.
|
||||||
|
func (b Build) ContainerLabels() (labels map[string]string) {
|
||||||
|
var version string
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case b.Clean && b.Tagged:
|
||||||
|
version = utils.VersionAdv(b.Tag, b.State(), b.Commit, b.Branch, b.Extra)
|
||||||
|
case b.Clean:
|
||||||
|
version = fmt.Sprintf("%s-pre+%s.%s", b.Tag, b.Branch, b.Commit)
|
||||||
|
case b.Tagged:
|
||||||
|
version = fmt.Sprintf("%s-dirty", b.Tag)
|
||||||
|
default:
|
||||||
|
version = fmt.Sprintf("%s-dirty+%s.%s", b.Tag, b.Branch, b.Commit)
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(version, "v") && len(version) > 1 {
|
||||||
|
version = version[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
labels = map[string]string{
|
||||||
|
"org.opencontainers.image.created": b.Date.Format(time.RFC3339),
|
||||||
|
"org.opencontainers.image.authors": "",
|
||||||
|
"org.opencontainers.image.url": "https://github.com/authelia/authelia/pkgs/container/authelia",
|
||||||
|
"org.opencontainers.image.documentation": "https://www.authelia.com",
|
||||||
|
"org.opencontainers.image.source": fmt.Sprintf("https://github.com/authelia/authelia/tree/%s", b.Commit),
|
||||||
|
"org.opencontainers.image.version": version,
|
||||||
|
"org.opencontainers.image.revision": b.Commit,
|
||||||
|
"org.opencontainers.image.vendor": "Authelia",
|
||||||
|
"org.opencontainers.image.licenses": "Apache-2.0",
|
||||||
|
"org.opencontainers.image.ref.name": "",
|
||||||
|
"org.opencontainers.image.title": "authelia",
|
||||||
|
"org.opencontainers.image.description": "Authelia is an open-source authentication and authorization server providing two-factor authentication and single sign-on (SSO) for your applications via a web portal.",
|
||||||
|
}
|
||||||
|
|
||||||
|
return labels
|
||||||
|
}
|
||||||
|
|
|
@ -37,10 +37,10 @@ func cmdXFlagsRun(cobraCmd *cobra.Command, _ []string) {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
flags, err := getXFlags("", build, extra)
|
buildMetaData, err := getBuild("", build, extra)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(strings.Join(flags, " "))
|
fmt.Println(strings.Join(buildMetaData.XFlags(), " "))
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,10 +35,11 @@ var BuildNumber = "0"
|
||||||
// BuildTag i.e. v1.0.0. If dirty and tagged are present it returns <BuildTag>-dirty. Otherwise, the following is the
|
// BuildTag i.e. v1.0.0. If dirty and tagged are present it returns <BuildTag>-dirty. Otherwise, the following is the
|
||||||
// format: untagged-<BuildTag>-dirty-<BuildExtra> (<BuildBranch>, <BuildCommit>).
|
// format: untagged-<BuildTag>-dirty-<BuildExtra> (<BuildBranch>, <BuildCommit>).
|
||||||
func Version() (versionString string) {
|
func Version() (versionString string) {
|
||||||
return version(BuildTag, BuildState, BuildCommit, BuildBranch, BuildExtra)
|
return VersionAdv(BuildTag, BuildState, BuildCommit, BuildBranch, BuildExtra)
|
||||||
}
|
}
|
||||||
|
|
||||||
func version(tag, state, commit, branch, extra string) (version string) {
|
// VersionAdv takes inputs to generate the version.
|
||||||
|
func VersionAdv(tag, state, commit, branch, extra string) (version string) {
|
||||||
b := strings.Builder{}
|
b := strings.Builder{}
|
||||||
|
|
||||||
states := strings.Split(state, " ")
|
states := strings.Split(state, " ")
|
||||||
|
|
|
@ -15,27 +15,27 @@ func TestVersionDefault(t *testing.T) {
|
||||||
func TestVersion(t *testing.T) {
|
func TestVersion(t *testing.T) {
|
||||||
var v string
|
var v string
|
||||||
|
|
||||||
v = version("v4.90.0", "tagged clean", "50d8b4a941c26b89482c94ab324b5a274f9ced66", "master", "")
|
v = VersionAdv("v4.90.0", "tagged clean", "50d8b4a941c26b89482c94ab324b5a274f9ced66", "master", "")
|
||||||
assert.Equal(t, "v4.90.0", v)
|
assert.Equal(t, "v4.90.0", v)
|
||||||
|
|
||||||
v = version("v4.90.0", "tagged clean", "50d8b4a941c26b89482c94ab324b5a274f9ced66", "master", "freshports")
|
v = VersionAdv("v4.90.0", "tagged clean", "50d8b4a941c26b89482c94ab324b5a274f9ced66", "master", "freshports")
|
||||||
assert.Equal(t, "v4.90.0-freshports", v)
|
assert.Equal(t, "v4.90.0-freshports", v)
|
||||||
|
|
||||||
v = version("v4.90.0", "tagged dirty", "50d8b4a941c26b89482c94ab324b5a274f9ced66", "master", "")
|
v = VersionAdv("v4.90.0", "tagged dirty", "50d8b4a941c26b89482c94ab324b5a274f9ced66", "master", "")
|
||||||
assert.Equal(t, "v4.90.0-dirty", v)
|
assert.Equal(t, "v4.90.0-dirty", v)
|
||||||
|
|
||||||
v = version("v4.90.0", "untagged dirty", "50d8b4a941c26b89482c94ab324b5a274f9ced66", "master", "")
|
v = VersionAdv("v4.90.0", "untagged dirty", "50d8b4a941c26b89482c94ab324b5a274f9ced66", "master", "")
|
||||||
assert.Equal(t, "untagged-v4.90.0-dirty (master, 50d8b4a)", v)
|
assert.Equal(t, "untagged-v4.90.0-dirty (master, 50d8b4a)", v)
|
||||||
|
|
||||||
v = version("v4.90.0", "untagged clean", "50d8b4a941c26b89482c94ab324b5a274f9ced66", "master", "")
|
v = VersionAdv("v4.90.0", "untagged clean", "50d8b4a941c26b89482c94ab324b5a274f9ced66", "master", "")
|
||||||
assert.Equal(t, "untagged-v4.90.0 (master, 50d8b4a)", v)
|
assert.Equal(t, "untagged-v4.90.0 (master, 50d8b4a)", v)
|
||||||
|
|
||||||
v = version("v4.90.0", "untagged clean", "50d8b4a941c26b89482c94ab324b5a274f9ced66", "master", "freshports")
|
v = VersionAdv("v4.90.0", "untagged clean", "50d8b4a941c26b89482c94ab324b5a274f9ced66", "master", "freshports")
|
||||||
assert.Equal(t, "untagged-v4.90.0-freshports (master, 50d8b4a)", v)
|
assert.Equal(t, "untagged-v4.90.0-freshports (master, 50d8b4a)", v)
|
||||||
|
|
||||||
v = version("v4.90.0", "untagged clean", "", "master", "")
|
v = VersionAdv("v4.90.0", "untagged clean", "", "master", "")
|
||||||
assert.Equal(t, "untagged-v4.90.0 (master, unknown)", v)
|
assert.Equal(t, "untagged-v4.90.0 (master, unknown)", v)
|
||||||
|
|
||||||
v = version("v4.90.0", "", "50d8b4a941c26b89482c94ab324b5a274f9ced66", "master", "")
|
v = VersionAdv("v4.90.0", "", "50d8b4a941c26b89482c94ab324b5a274f9ced66", "master", "")
|
||||||
assert.Equal(t, "untagged-v4.90.0-dirty (master, 50d8b4a)", v)
|
assert.Equal(t, "untagged-v4.90.0-dirty (master, 50d8b4a)", v)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue