Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
version: 2

project_name: smartling-cli
dist: bin

env:
- CGO_ENABLED=0

before:
hooks:
- sh -c 'test -n "$GORELEASER_CURRENT_TAG" || { echo "GORELEASER_CURRENT_TAG must be set; use make build"; exit 1; }'

release:
disable: true

builds:
-
binary: smartling-cli

goos:
- linux
- darwin
- windows

goarch:
- amd64
- arm64

flags:
- -trimpath

ldflags:
- -s -w
- -X github.com/Smartling/smartling-cli/cmd/helpers/build.CliVersion={{ .Tag }}
- -X github.com/Smartling/smartling-cli/cmd/helpers/build.CommitID={{ .FullCommit }}
- -X github.com/Smartling/smartling-cli/cmd/helpers/build.Date={{ .Date }}
- -X github.com/Smartling/smartling-cli/cmd/helpers/build.BuiltBy=GoReleaser

snapshot:
version_template: "{{ .Tag }}"

archives:
- formats: [binary]
name_template: "{{ .ProjectName }}_latest_{{ .Os }}_{{ .Arch }}"

nfpms:
- id: smartling
package_name: smartling
file_name_template: "{{ .PackageName }}_latest_{{ .Os }}_{{ .Arch }}"
vendor: Smartling
homepage: https://github.com/Smartling/smartling-cli
maintainer: Alex Koval <akoval@smartling.com>
description: CLI for Smartling Platform
license: MIT
formats:
- deb
- rpm
bindir: /usr/bin
section: unknown
priority: extra
contents:
- src: /usr/bin/smartling-cli
dst: /usr/bin/smartling
type: symlink

checksum:
name_template: "checksums.txt"
24 changes: 12 additions & 12 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,19 @@ The CLI uses dependency injection through service initializers, making it testab
The project uses a Makefile-based build system that cross-compiles for multiple platforms:

```bash
make all # Clean, get dependencies, and build for all platforms
make build # Build for darwin, windows, linux (outputs to bin/ directory)
go build # Build for current platform only
make all # Clean, fetch deps, and run a full release build
make build # Cross-compile via GoReleaser (requires `goreleaser` installed)
go build # Build for current platform only (fast dev iteration)
```

**Build outputs:**
- `bin/smartling.darwin` - macOS binary
- `bin/smartling.windows.exe` - Windows binary
- `bin/smartling.linux` - Linux binary
`make build` invokes GoReleaser configured via `.goreleaser.yml`. It cross-compiles for linux/darwin/windows × amd64/arm64 and, for linux, also produces `.deb` and `.rpm` packages via nfpms.

**Build time:** Typically takes 10-30 seconds depending on whether dependencies need to be downloaded.
**Build outputs (under `bin/`):**
- Per-target binaries: `bin/smartling-cli_<os>_<arch>_<variant>/smartling-cli` (e.g. `bin/smartling-cli_linux_amd64_v1/smartling-cli`, `bin/smartling-cli_windows_amd64_v1/smartling-cli.exe`)
- Linux packages: `bin/smartling_<version>_linux_amd64.deb`, `.rpm`, plus arm64 variants — install the binary at `/usr/bin/smartling-cli` with a `/usr/bin/smartling` symlink
- `bin/checksums.txt` — SHA256 sums for verification

**Build time:** Cross-compile typically 5-15 seconds; `go build` for one platform is under 5 seconds.

### Testing

Expand Down Expand Up @@ -78,10 +80,8 @@ make docs # Generate command documentation
```

### Package Building
```bash
make deb VERSION=1.0.0 # Build Debian package
make rpm VERSION=1.0.0 # Build RPM package
```

`.deb` and `.rpm` packages are produced automatically by `make build` via GoReleaser's nfpms integration — no separate make targets. Package metadata (name, maintainer, license, install paths) lives in the `nfpms` block of `.goreleaser.yml`.

## Configuration

Expand Down
25 changes: 11 additions & 14 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ pipeline {
stages {
stage('Build') {
steps {
sh "docker pull golang"
sh "docker run -t --rm -v ${WORKSPACE}:/go/src/cli -w /go/src/cli golang make"
sh "docker pull goreleaser/goreleaser:v2.15.4"
sh """
docker run -t --rm \\
-v ${WORKSPACE}:/go/src/cli -w /go/src/cli \\
--entrypoint sh \\
goreleaser/goreleaser:v2.15.4 \\
-c 'apk add --no-cache make && make build'
"""
}
}

Expand All @@ -32,18 +38,9 @@ pipeline {
branch env.TARGET_BRANCH
}
steps {
sh "aws-profile connectors-staging aws s3 cp ${WORKSPACE}/bin s3://smartling-connectors-releases/cli/ --recursive --acl public-read"
}
}

stage('Generate Packages') {
when {
branch env.TARGET_BRANCH
}
steps {
sh "docker run -t --rm -v ${WORKSPACE}:/go/src/cli -w /go/src/cli gvangool/rpmbuilder:centos7 bash -c 'make rpm'"
// TODO : Replace with special docker image
sh "docker run -t --rm -v ${WORKSPACE}:/go/src/cli -w /go/src/cli debian bash -c 'apt-get update && apt-get install -y make git && make deb'"
sh '''
aws-profile connectors-staging aws s3 cp ${WORKSPACE}/bin s3://smartling-connectors-releases/cli/ --acl public-read --exclude "*" --include "smartling-cli*" --include "smartling_*.deb" --include "smartling_*.rpm" --include "checksums.txt" --recursive
'''
Comment thread
az-smartling marked this conversation as resolved.
}
}
}
Expand Down
66 changes: 8 additions & 58 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,76 +1,26 @@
MAINTAINER = Alex Koval <akoval@smartling.com>
DESCRIPTION = CLI for Smartling Platform

LDFLAGS ?= -s -w
GO_BUILD_FLAGS ?= -mod=mod -trimpath -ldflags="$(LDFLAGS)"
VERSION := $(shell grep -E '\bCliVersion\s*=\s*"' cmd/helpers/build/build.go | head -1 | sed -E 's/.*"([^"]+)".*/\1/')
ifeq ($(VERSION),)
$(error Could not extract CliVersion from cmd/helpers/build/build.go)
endif

.PHONY: all
all: clean get build
@

.PHONY: build
build: darwin windows.exe linux
@
build:
@echo "Building version $(VERSION)"
GORELEASER_CURRENT_TAG=$(VERSION) goreleaser release --clean --skip=publish --snapshot

.PHONY: get
get:
go mod download

.PHONY: clean
clean:
rm -rf bin pkg
rm -rf bin
mkdir bin

_PKG = pkg/build

_CONTROL = echo >> $(_PKG)/DEBIAN/control

.PHONY: deb
deb: _pkg-init
mkdir -p $(_PKG)/usr/bin
cp bin/smartling.linux $(_PKG)/usr/bin/smartling
mkdir -p $(_PKG)/DEBIAN
$(_CONTROL) "Package: smartling"
$(_CONTROL) "Version: $(VERSION)"
$(_CONTROL) "Architecture: all"
$(_CONTROL) "Section: unknown"
$(_CONTROL) "Priority: extra"
$(_CONTROL) "Maintainer: $(MAINTAINER)"
$(_CONTROL) "Homepage: https://github.com/Smartling/smartling-cli"
$(_CONTROL) "Description: $(DESCRIPTION)"
dpkg -b $(_PKG) pkg/smartling-$(VERSION)_all.deb
rm -rf $(_PKG)

_SPEC = echo >> $(_PKG)/smartling.spec

.PHONY: rpm
rpm: _pkg-init
$(_SPEC) "Name: smartling"
$(_SPEC) "Version: $(VERSION)"
$(_SPEC) "Release: 1%{?dist}"
$(_SPEC) "Summary: $(DESCRIPTION)"
$(_SPEC) "License: MIT"
$(_SPEC) "%description"
$(_SPEC) "%install"
$(_SPEC) "mkdir -p %{buildroot}/%{_bindir}"
$(_SPEC) "cp $(PWD)/bin/smartling.linux %{buildroot}/%{_bindir}/smartling"
$(_SPEC) "%files"
$(_SPEC) "%{_bindir}/smartling"
$(_SPEC) "%define _rpmdir $(_PKG)"
rpmbuild -bb $(_PKG)/smartling.spec
cp $(_PKG)/*/*.rpm pkg/
rm -rf $(_PKG)

.PHONY: _pkg-init
_pkg-init:
rm -rf $(_PKG)
mkdir -p $(_PKG)
$(eval VERSION ?= \
$(shell git rev-list --count HEAD).$(shell git rev-parse --short HEAD))

%:
CGO_ENABLED=0 GOOS=$(basename $@) go build $(GO_BUILD_FLAGS) -o bin/smartling.$@

.PHONY: docs
docs:
go run ./main.go docs
Expand Down
35 changes: 11 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,24 @@ See the [Wiki](https://github.com/Smartling/smartling-cli/wiki) page for this re
# Development
For developers interested in modifying the tool.

## Building package
## Building

Local development build:

```
make <target>
go build ./...
```

Where target is:

* `deb` for building Debian packages:
```
make deb
```

* `rpm` for building Fedora packages:
```
make rpm
```

Specific settings can be set in built-time:

*VERSION*:
Full release build (cross-compiles all platforms and produces deb/rpm packages via [GoReleaser](https://goreleaser.com/) nfpms — requires `goreleaser` installed locally):

```
make VERSION=<version-string> <target>
make build
```

*MAINTAINER*:
Outputs land in `bin/`:

```
make MAINTAINER=<maintainer> <target>
```
- Per-platform binaries under `bin/smartling-cli_<os>_<arch>_<variant>/smartling-cli`
- Linux packages: `bin/smartling_<version>_linux_amd64.deb`, `.rpm`, plus arm64 variants
- `bin/checksums.txt`

An executable named `smartling-cli` should become available in your
`$GOPATH/bin`.
Package metadata (maintainer, description, license) and cross-compile targets are configured in `.goreleaser.yml`.
21 changes: 21 additions & 0 deletions cmd/build/build.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package build

import (
"fmt"

"github.com/Smartling/smartling-cli/cmd/helpers/build"

"github.com/spf13/cobra"
)

// NewBuildCmd creates a new build command.
func NewBuildCmd() *cobra.Command {
buildCmd := &cobra.Command{
Use: "build",
Short: "Print the build information",
Run: func(_ *cobra.Command, _ []string) {
fmt.Println(build.String())
},
}
return buildCmd
}
4 changes: 3 additions & 1 deletion cmd/cmd_root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package cmd
import (
"strings"

"github.com/Smartling/smartling-cli/cmd/helpers/build"

"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -30,7 +32,7 @@ func NewRootCmd() *cobra.Command {
rootCmd := &cobra.Command{
Use: "smartling-cli",
Short: "Manage translation files using Smartling CLI.",
Version: "3.2",
Version: build.CliVersion,
Long: `Manage translation files using Smartling CLI.
Complete documentation is available at https://www.smartling.com`,
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
Expand Down
41 changes: 41 additions & 0 deletions cmd/helpers/build/build.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package build

import (
"fmt"
"runtime"
)

// These variables will be set via ldflags at build time.
var (
// CliVersion is version information
CliVersion = "3.3"
// CommitID is the git commit hash
CommitID = ""
// Date is date of binary built
Date = ""
// BuiltBy identifies the build pipeline (e.g. "GoReleaser", "make").
// Defaults to "unknown" so binaries built without ldflag injection
// don't mislabel themselves.
BuiltBy = "unknown"
)

// String returns the version information as a formatted string.
func String() string {
return fmt.Sprintf(`
Smartling-cli is a library and CLI tool for managing Smartling projects.

Version: %s
GitCommit: %s
BuildDate: %s
BuiltBy: %s
GoVersion: %s
Platform: %s
`,
CliVersion,
CommitID,
Date,
BuiltBy,
runtime.Version(),
runtime.GOOS+"/"+runtime.GOARCH,
)
}
4 changes: 4 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"github.com/Smartling/smartling-cli/cmd"
"github.com/Smartling/smartling-cli/cmd/build"
"github.com/Smartling/smartling-cli/cmd/docs"
"github.com/Smartling/smartling-cli/cmd/files"
deletecmd "github.com/Smartling/smartling-cli/cmd/files/delete"
Expand Down Expand Up @@ -32,6 +33,9 @@ func main() {
docsCmd := docs.NewDocsCmd()
rootCmd.AddCommand(docsCmd)

buildCmd := build.NewBuildCmd()
rootCmd.AddCommand(buildCmd)

initSrvInitializer := initialize.NewSrvInitializer()
initCmd := initialize.NewInitCmd(initSrvInitializer)
rootCmd.AddCommand(initCmd)
Expand Down