Skip to content

Commit

Permalink
Add version flag to output build information
Browse files Browse the repository at this point in the history
Generating the version number before building and embedding it into the
executable so that it can be outputted by the following command:

`uipath --version`

`uipathcli v1.0.0 (windows, amd64)`
  • Loading branch information
thschmitt committed Oct 8, 2024
1 parent 4b701e3 commit 6da4d97
Show file tree
Hide file tree
Showing 9 changed files with 183 additions and 65 deletions.
14 changes: 12 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ env:
jobs:
build:
runs-on: ubuntu-latest
outputs:
UIPATHCLI_VERSION: ${{ steps.version.outputs.UIPATHCLI_VERSION }}
env:
CGO_ENABLED: "0"
steps:
Expand All @@ -17,10 +19,16 @@ jobs:
with:
go-version: '1.22.2'
cache: true
- name: Version
id: version
run: |
UIPATHCLI_VERSION=$(./version.sh "$UIPATHCLI_BASE_VERSION")
echo "UIPATHCLI_VERSION=$(echo $UIPATHCLI_VERSION)" >> $GITHUB_ENV
echo "UIPATHCLI_VERSION=$(echo $UIPATHCLI_VERSION)" >> $GITHUB_OUTPUT
- name: Install dependencies
run: go get .
- name: Build
run: go build .
run: go build -ldflags="-X github.com/UiPath/uipathcli/commandline.Version=$UIPATHCLI_VERSION" .
- name: Lint
run: |
go install github.com/golangci/golangci-lint/cmd/[email protected]
Expand Down Expand Up @@ -74,6 +82,8 @@ jobs:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
env:
UIPATHCLI_VERSION: ${{ needs.build.outputs.UIPATHCLI_VERSION }}
steps:
- name: Checkout
uses: actions/checkout@v3
Expand All @@ -83,6 +93,6 @@ jobs:
name: packages
path: build/packages/
- name: Publish
run: ./publish.sh "$UIPATHCLI_BASE_VERSION"
run: ./publish.sh "$UIPATHCLI_VERSION"
env:
GITHUB_TOKEN: ${{ github.token }}
12 changes: 6 additions & 6 deletions build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@ New-Item -ItemType Directory -Force -Path build | out-null
Copy-Item README.md -Destination build/README.md

Write-Host "Building Linux (amd64) executable"
pwsh -Command { $env:GOOS = "linux"; $env:GOARCH = "amd64"; go build -o build/uipath-linux-amd64 }
pwsh -Command { $env:GOOS = "linux"; $env:GOARCH = "amd64"; go build -ldflags="-X github.com/UiPath/uipathcli/commandline.Version=$env:UIPATHCLI_VERSION" -o build/uipath-linux-amd64 }

Write-Host "Building Windows (amd64) executable"
pwsh -Command { $env:GOOS = "windows"; $env:GOARCH = "amd64"; go build -o build/uipath-windows-amd64.exe }
pwsh -Command { $env:GOOS = "windows"; $env:GOARCH = "amd64"; go build -ldflags="-X github.com/UiPath/uipathcli/commandline.Version=$env:UIPATHCLI_VERSION" -o build/uipath-windows-amd64.exe }

Write-Host "Building MacOS (amd64) executable"
pwsh -Command { $env:GOOS = "darwin"; $env:GOARCH = "amd64"; go build -o build/uipath-darwin-amd64 }
pwsh -Command { $env:GOOS = "darwin"; $env:GOARCH = "amd64"; go build -ldflags="-X github.com/UiPath/uipathcli/commandline.Version=$env:UIPATHCLI_VERSION" -o build/uipath-darwin-amd64 }

Write-Host "Building Linux (arm64) executable"
pwsh -Command { $env:GOOS = "linux"; $env:GOARCH = "arm64"; go build -o build/uipath-linux-arm64 }
pwsh -Command { $env:GOOS = "linux"; $env:GOARCH = "arm64"; go build -ldflags="-X github.com/UiPath/uipathcli/commandline.Version=$env:UIPATHCLI_VERSION" -o build/uipath-linux-arm64 }

Write-Host "Building Windows (arm64) executable"
pwsh -Command { $env:GOOS = "windows"; $env:GOARCH = "arm64"; go build -o build/uipath-windows-arm64.exe }
pwsh -Command { $env:GOOS = "windows"; $env:GOARCH = "arm64"; go build -ldflags="-X github.com/UiPath/uipathcli/commandline.Version=$env:UIPATHCLI_VERSION" -o build/uipath-windows-arm64.exe }

Write-Host "Building MacOS (arm64) executable"
pwsh -Command { $env:GOOS = "darwin"; $env:GOARCH = "arm64"; go build -o build//uipath-darwin-arm64 }
pwsh -Command { $env:GOOS = "darwin"; $env:GOARCH = "arm64"; go build -ldflags="-X github.com/UiPath/uipathcli/commandline.Version=$env:UIPATHCLI_VERSION" -o build//uipath-darwin-arm64 }

Write-Host "Successfully completed"
12 changes: 6 additions & 6 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ mkdir -p build
cp README.md build/README.md

echo "Building Linux (amd64) executable"
GOOS=linux GOARCH=amd64 go build -o build/uipath-linux-amd64
GOOS=linux GOARCH=amd64 go build -ldflags="-X github.com/UiPath/uipathcli/commandline.Version=$UIPATHCLI_VERSION" -o build/uipath-linux-amd64

echo "Building Windows (amd64) executable"
GOOS=windows GOARCH=amd64 go build -o build/uipath-windows-amd64.exe
GOOS=windows GOARCH=amd64 go build -ldflags="-X github.com/UiPath/uipathcli/commandline.Version=$UIPATHCLI_VERSION" -o build/uipath-windows-amd64.exe

echo "Building MacOS (amd64) executable"
GOOS=darwin GOARCH=amd64 go build -o build/uipath-darwin-amd64
GOOS=darwin GOARCH=amd64 go build -ldflags="-X github.com/UiPath/uipathcli/commandline.Version=$UIPATHCLI_VERSION" -o build/uipath-darwin-amd64

echo "Building Linux (arm64) executable"
GOOS=linux GOARCH=arm64 go build -o build/uipath-linux-arm64
GOOS=linux GOARCH=arm64 go build -ldflags="-X github.com/UiPath/uipathcli/commandline.Version=$UIPATHCLI_VERSION" -o build/uipath-linux-arm64

echo "Building Windows (arm64) executable"
GOOS=windows GOARCH=arm64 go build -o build/uipath-windows-arm64.exe
GOOS=windows GOARCH=arm64 go build -ldflags="-X github.com/UiPath/uipathcli/commandline.Version=$UIPATHCLI_VERSION" -o build/uipath-windows-arm64.exe

echo "Building MacOS (arm64) executable"
GOOS=darwin GOARCH=arm64 go build -o build/uipath-darwin-arm64
GOOS=darwin GOARCH=arm64 go build -ldflags="-X github.com/UiPath/uipathcli/commandline.Version=$UIPATHCLI_VERSION" -o build/uipath-darwin-arm64

echo "Successfully completed"
10 changes: 10 additions & 0 deletions commandline/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func (c Cli) run(args []string, input utils.Stream) error {

flags := NewFlagBuilder().
AddDefaultFlags(false).
AddVersionFlag().
Build()

commands, err := CommandBuilder.Create(args)
Expand All @@ -62,6 +63,15 @@ func (c Cli) run(args []string, input utils.Stream) error {
HideVersion: true,
HideHelpCommand: true,
DisableSliceFlagSeparator: true,
Action: func(context *cli.Context) error {
if context.IsSet(FlagNameVersion) {
handler := newVersionCommandHandler(c.stdOut)
handler.Execute()
return nil
}
cli.ShowAppHelp(context)

Check failure on line 72 in commandline/cli.go

View workflow job for this annotation

GitHub Actions / build

Error return value of `cli.ShowAppHelp` is not checked (errcheck)
return nil
},
}
return app.Run(args)
}
Expand Down
12 changes: 12 additions & 0 deletions commandline/flag_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const FlagNameFile = "file"
const FlagNameIdentityUri = "identity-uri"
const FlagNameServiceVersion = "service-version"
const FlagNameHelp = "help"
const FlagNameVersion = "version"

const FlagValueFromStdIn = "-"
const FlagValueOutputFormatJson = "json"
Expand All @@ -40,6 +41,7 @@ var FlagNamesPredefined = []string{
FlagNameIdentityUri,
FlagNameServiceVersion,
FlagNameHelp,
FlagNameVersion,
}

// The FlagBuilder can be used to prepare a list of flags for a CLI command.
Expand Down Expand Up @@ -75,6 +77,11 @@ func (b *FlagBuilder) AddHelpFlag() *FlagBuilder {
return b
}

func (b *FlagBuilder) AddVersionFlag() *FlagBuilder {
b.AddFlag(b.versionFlag())
return b
}

func (b *FlagBuilder) AddServiceVersionFlag(hidden bool) *FlagBuilder {
b.AddFlag(b.serviceVersionFlag(hidden))
return b
Expand Down Expand Up @@ -134,6 +141,11 @@ func (b FlagBuilder) defaultFlags(hidden bool) []*FlagDefinition {
}
}

func (b FlagBuilder) versionFlag() *FlagDefinition {
return NewFlag(FlagNameVersion, "Display the build version", FlagTypeBoolean).
WithHidden(true)
}

func (b FlagBuilder) serviceVersionFlag(hidden bool) *FlagDefinition {
return NewFlag(FlagNameServiceVersion, "Specific service version", FlagTypeString).
WithEnvVarName("UIPATH_SERVICE_VERSION").
Expand Down
30 changes: 30 additions & 0 deletions commandline/version_command_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package commandline

import (
"fmt"
"io"
"runtime"
)

// This Version variable is overridden during build time
// by providing the linker flag:
// -ldflags="-X github.com/UiPath/uipathcli/commandline.Version=1.2.3"
var Version = "main"

// The VersionCommandHandler outputs the build information
//
// Example:
// uipath --version
//
// uipathcli v1.0.0 (windows, amd64)
type versionCommandHandler struct {
StdOut io.Writer
}

func (h versionCommandHandler) Execute() {
fmt.Fprintf(h.StdOut, "uipathcli %s (%s, %s)\n", Version, runtime.GOOS, runtime.GOARCH)
}

func newVersionCommandHandler(stdOut io.Writer) *versionCommandHandler {
return &versionCommandHandler{stdOut}
}
65 changes: 14 additions & 51 deletions publish.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
# Publishes a new version of the uipathcli on GitHub
#
# DESCRIPTION:
# This scripts retrieves the latest tag, increments the
# version and creates a new release on GitHub.
# This scripts publishes a tag with the latest version and
# creates a new release on GitHub.
############################################################

set -o pipefail
Expand All @@ -22,43 +22,6 @@ declare -a RELEASE_FILES=(
"build/packages/uipathcli-darwin-arm64.tar.gz"
)

############################################################
# Retrieves the latest version by sorting the git tags
#
# Returns:
# The latest git tag
############################################################
function get_latest_version()
{
local version_filter="$1"

git fetch --all --tags --quiet
git tag | sort -V | grep "^$version_filter.*" | tail -1 || echo "$version_filter"
}

############################################################
# Increment patch version on the provided semver string
#
# Arguments:
# - The version (semver format, e.g. 1.0.0)
#
# Returns:
# Incremented patch version (e.g. 1.0.1)
############################################################
function increment_patch_version()
{
local version="$1"

local array
local IFS='.'; read -r -a array <<< "$version"
if [ -z "${array[2]}" ]; then
array[2]="0"
else
array[2]=$((array[2]+1))
fi
echo "$(local IFS='.'; echo "${array[*]}")"
}

############################################################
# Create new tag and push it to remote
#
Expand All @@ -69,7 +32,7 @@ function create_tag()
{
local tag_name="$1"

git tag "$tag_name"
git tag "$tag_name" || true
git push --tags --quiet
}

Expand Down Expand Up @@ -127,17 +90,17 @@ function upload_release_file()
############################################################
function main()
{
local base_version="$1"
local latest_version
local new_version

latest_version=$(get_latest_version "$base_version")
new_version=$(increment_patch_version "$latest_version")
echo "=================================="
echo "Releasing new version of uipathcli"
echo "Current version is: $latest_version"
echo "Creating new release: $new_version"
echo "=================================="
local new_version="$1"

if [ -z "${new_version}" ]; then
echo "Please provide the new version to publish!"
exit 1
fi

echo "==================================="
echo "Releasing new version of uipathcli:"
echo "$new_version"
echo "==================================="

local release_id
create_tag "$new_version"
Expand Down
17 changes: 17 additions & 0 deletions test/version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package test

import (
"strings"
"testing"
)

func TestVersionOutput(t *testing.T) {
context := NewContextBuilder().
Build()

result := RunCli([]string{"--version"}, context)

if !strings.HasPrefix(result.StdOut, "uipathcli main") {
t.Errorf("Did not return version information, got: %v", result.StdOut)
}
}
76 changes: 76 additions & 0 deletions version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#! /bin/bash
############################################################
# Generates the next version to publish
#
# DESCRIPTION:
# This scripts retrieves the latest tag, increments the
# version and creates a new release on GitHub.
############################################################

set -o pipefail
set -e

############################################################
# Retrieves the latest version by sorting the git tags
#
# Returns:
# The latest git tag
############################################################
function get_latest_version()
{
local version_filter="$1"

git fetch --all --tags --quiet
git tag | sort -V | grep "^$version_filter.*" | tail -1 || echo "$version_filter"
}

############################################################
# Increment patch version on the provided semver string
#
# Arguments:
# - The version (semver format, e.g. 1.0.0)
#
# Returns:
# Incremented patch version (e.g. 1.0.1)
############################################################
function increment_patch_version()
{
local version="$1"

local array
local IFS='.'; read -r -a array <<< "$version"
if [ -z "${array[2]}" ]; then
array[2]="0"
else
array[2]=$((array[2]+1))
fi
echo "$(local IFS='.'; echo "${array[*]}")"
}

############################################################
# Create new tag
#
# Arguments:
# - The tag name
############################################################
function create_tag()
{
local tag_name="$1"

git tag "$tag_name"
}

############################################################
# Main
############################################################
function main()
{
local base_version="$1"
local latest_version
local new_version

latest_version=$(get_latest_version "$base_version")
new_version=$(increment_patch_version "$latest_version")
echo "$new_version"
}
main "$1"

0 comments on commit 6da4d97

Please sign in to comment.