Building and Releasing Software

Overview

Go compiles to static binaries, making deployment simple. This chapter covers building, cross-compilation, and release workflows.

Basic Build

go build -o myapp ./cmd/server

Production Build

go build \
    -ldflags="-s -w" \
    -o bin/myapp \
    ./cmd/server

Flags: - -s - Strip symbol table - -w - Strip DWARF debugging info

Version Injection

var (
    version = "dev"
    commit  = "none"
    date    = "unknown"
)
go build -ldflags="-X main.version=1.0.0 -X main.commit=$(git rev-parse HEAD)"

Cross-Compilation

# Linux
GOOS=linux GOARCH=amd64 go build -o app-linux

# Windows
GOOS=windows GOARCH=amd64 go build -o app.exe

# macOS ARM
GOOS=darwin GOARCH=arm64 go build -o app-darwin

# All platforms
for os in linux darwin windows; do
    for arch in amd64 arm64; do
        GOOS=$os GOARCH=$arch go build -o bin/app-$os-$arch
    done
done

Docker

# Multi-stage build
FROM golang:1.26-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o /app/server ./cmd/server

FROM alpine:latest
COPY --from=builder /app/server /server
ENTRYPOINT ["/server"]

GitHub Actions

name: Release
on:
  push:
    tags: ['v*']

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: '1.26'
      - run: go build -o app
      - uses: softprops/action-gh-release@v1
        with:
          files: app

GoReleaser

# .goreleaser.yaml
builds:
  - main: ./cmd/server
    goos: [linux, darwin, windows]
    goarch: [amd64, arm64]

archives:
  - format: tar.gz
goreleaser release

Summary

Task Command
Build go build -o app
Optimize -ldflags="-s -w"
Cross-compile GOOS=linux GOARCH=amd64
Version inject -ldflags="-X main.version=x"